Well, it's been a total failure

Walter Bright newshound2 at digitalmars.com
Tue Sep 14 14:04:21 PDT 2010


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;
}


More information about the Digitalmars-d mailing list