Steven Schveighoffer wrote:
Not that anyone here is in charge of your time, I think Andrei's "waste
of time" point is that there are better, more productive things you can
do for the good of D. If someone else wants to write this utility,
great. But in the meantime, can we just put in the easy fix?
It's arguable whether the "easy" fix is to write a trivial utility, or to
rejigger all my build and install scripts.
In any case, it's done. Here it is, it's mostly a cut&paste from another zip
utility I wrote long ago.
==========================================
import std.c.stdio;
import std.c.stdlib;
import std.stdio;
import std.file;
import std.date;
import std.zip;
import std.zlib;
int main(string[] args)
{
if (args.length == 1)
{
writeln("Usage: zip zipfile attr members...");
exit(0);
}
if (args.length == 2)
{
auto zipname = args[1];
auto buffer = cast(byte[])std.file.read(zipname);
auto zr = new std.zip.ZipArchive(cast(void[])buffer);
writefln("comment = '%s'", zr.comment);
foreach (ArchiveMember de; zr.directory)
{
zr.expand(de);
writefln("name = %s", de.name);
writefln("\tcomment = %s", de.comment);
writefln("\tmadeVersion = x%04x", de.madeVersion);
writefln("\textractVersion = x%04x", de.extractVersion);
writefln("\tflags = x%04x", de.flags);
writefln("\tcompressionMethod = %d", de.compressionMethod);
writefln("\tcrc32 = x%08x", de.crc32);
writefln("\texpandedSize = %s", de.expandedSize);
writefln("\tcompressedSize = %s", de.compressedSize);
writefln("\teattr = %03o, %03o", de.externalAttributes >> 16,
de.externalAttributes & 0xFFFF);
writefln("\tiattr = %03o", de.internalAttributes);
writefln("\tdate = %s",
std.date.toString(std.date.toDtime(de.time)));
}
return 0;
}
auto zipname = args[1];
auto attr = args[2];
auto members = args[3 .. $];
uint newattr = 0;
foreach (c; attr)
{
if (c < '0' || c > '7' || attr.length > 4)
throw new ZipException("attr must be 1..4 octal digits, not " ~
attr);
newattr = (newattr << 3) | (c - '0');
}
auto buffer = cast(byte[])std.file.read(zipname);
auto zr = new std.zip.ZipArchive(cast(void[])buffer);
foreach (member; members)
{
foreach (ArchiveMember de; zr.directory)
{
if (de.name == member)
goto L1;
}
throw new ZipException(member ~ " not in zipfile " ~ zipname);
L1:
;
}
bool changes;
foreach (ArchiveMember de; zr.directory)
{
zr.expand(de);
foreach (member; members)
{
if (de.name == member && ((de.externalAttributes >> 16) & 07777) !=
newattr)
{ changes = true;
de.madeVersion = 0x317; // necessary or linux unzip will ignore
attributes
de.externalAttributes = (de.externalAttributes & ~(07777 << 16)) | (newattr <<
16);
break;
}
}
}
if (changes)
{ void[] data2 = zr.build();
std.file.write(zipname, cast(byte[])data2);
}
return 0;
}