It looks like 0040000 (octal) is the flag for directories on linux, but it does seem that std.zip is explicitly returning 0 if the file was created on the opposite platform re: Posix vs Windows, which is... odd.

@property @nogc nothrow uint fileAttributes() const
{
    version (Posix)
    {
        if ((_madeVersion & 0xFF00) == 0x0300)
            return _externalAttributes >> 16;
        return 0;
    }
    else version (Windows)
    {
        if ((_madeVersion & 0xFF00) == 0x0000)
            return _externalAttributes;
        return 0;
    }
    else
    {
        static assert(0, "Unimplemented platform");
    }
}

Looks like the only way around it is modifying std.zip? Adding something like:

@property bool isDir() const {
        enum uint FILE_ATTRIBUTE_DIRECTORY = 0x10; // WINNT.h
        enum uint S_IFDIR = 0x4000; // sys/stat.h
        version(Windows) {
                if ((_madeVersion & 0xFF00) == 0x0300) // Archive made on Posix
                        return cast(bool) (_externalAttributes & (S_IFDIR << 
16));
return cast(bool) (_externalAttributes & FILE_ATTRIBUTE_DIRECTORY);
        } else version(Posix) {
                if ((_madeVersion & 0xFF00) == 0x0300) // Archive made on Posix
                        return cast(bool) (_externalAttributes & (S_IFDIR << 
16));
return cast(bool) ((_externalAttributes) & FILE_ATTRIBUTE_DIRECTORY);
        } else {
                static assert(0, "Unimplemented platform");
        }
}

will let me do this:

void main() {
        foreach (zipfile; ["windowstest.zip", "linuxtest.zip"]) {
                writeln(zipfile);
                auto zip = new ZipArchive(std.file.read(zipfile));
                foreach (fn, am; zip.directory) {
                        writefln("%24s  %5s  %s", fn, am.isDir, 
am.fileAttributes);
                }
        }
}

Results on Windows:
windowstest.zip
                   a.txt  false  32
                testdir/   true  16
           testdir/b.txt  false  32
linuxtest.zip
                   a.txt  false  0
                testdir/   true  0
           testdir/b.txt  false  0

Results on Linux:
windowstest.zip
                testdir/   true  0
           testdir/b.txt  false  0
                   a.txt  false  0
linuxtest.zip
                testdir/   true  16893
           testdir/b.txt  false  33204
                   a.txt  false  33204

Reply via email to