Index: src/OFZIPArchiveEntry.h ================================================================== --- src/OFZIPArchiveEntry.h +++ src/OFZIPArchiveEntry.h @@ -26,11 +26,11 @@ /*! * @brief Attribute compatibility part of ZIP versions. */ enum of_zip_archive_entry_attribute_compatibility { - /** MS-DOS and OS/2 (FAT / VFAT / FAT32 file systems) */ + /** MS-DOS and OS/2 */ OF_ZIP_ARCHIVE_ENTRY_ATTR_COMPAT_MSDOS = 0, /** Amiga */ OF_ZIP_ARCHIVE_ENTRY_ATTR_COMPAT_AMIGA = 1, /** OpenVMS */ OF_ZIP_ARCHIVE_ENTRY_ATTR_COMPAT_OPENVMS = 2, @@ -211,10 +211,18 @@ @end #ifdef __cplusplus extern "C" { #endif +/*! + * @brief Converts the ZIP entry version to a string + * + * @param version The ZIP entry version to convert to a string + * @return The ZIP entry version as a string + */ +extern OFString* of_zip_archive_entry_version_to_string(uint16_t version); + /*! * @brief Gets a pointer to and the size of the extensible data field with the * specified tag. * * @param extraField The extra field to search for an extensible data field with Index: src/OFZIPArchiveEntry.m ================================================================== --- src/OFZIPArchiveEntry.m +++ src/OFZIPArchiveEntry.m @@ -29,10 +29,88 @@ #import "OFInvalidArgumentException.h" #import "OFInvalidFormatException.h" extern uint32_t of_zip_archive_read_field32(uint8_t**, uint16_t*); extern uint64_t of_zip_archive_read_field64(uint8_t**, uint16_t*); + +OFString* +of_zip_archive_entry_version_to_string(uint16_t version) +{ + const char *attrCompat = NULL; + + switch (version >> 8) { + case OF_ZIP_ARCHIVE_ENTRY_ATTR_COMPAT_MSDOS: + attrCompat = "MS-DOS or OS/2"; + break; + case OF_ZIP_ARCHIVE_ENTRY_ATTR_COMPAT_AMIGA: + attrCompat = "Amiga"; + break; + case OF_ZIP_ARCHIVE_ENTRY_ATTR_COMPAT_OPENVMS: + attrCompat = "OpenVMS"; + break; + case OF_ZIP_ARCHIVE_ENTRY_ATTR_COMPAT_UNIX: + attrCompat = "UNIX"; + break; + case OF_ZIP_ARCHIVE_ENTRY_ATTR_COMPAT_VM_CMS: + attrCompat = "VM/CMS"; + break; + case OF_ZIP_ARCHIVE_ENTRY_ATTR_COMPAT_ATARI_ST: + attrCompat = "Atari ST"; + break; + case OF_ZIP_ARCHIVE_ENTRY_ATTR_COMPAT_OS2_HPFS: + attrCompat = "OS/2 HPFS"; + break; + case OF_ZIP_ARCHIVE_ENTRY_ATTR_COMPAT_MACINTOSH: + attrCompat = "Macintosh"; + break; + case OF_ZIP_ARCHIVE_ENTRY_ATTR_COMPAT_Z_SYSTEM: + attrCompat = "Z-System"; + break; + case OF_ZIP_ARCHIVE_ENTRY_ATTR_COMPAT_CP_M: + attrCompat = "CP/M"; + break; + case OF_ZIP_ARCHIVE_ENTRY_ATTR_COMPAT_WINDOWS_NTFS: + attrCompat = "Windows NTFS"; + break; + case OF_ZIP_ARCHIVE_ENTRY_ATTR_COMPAT_MVS: + attrCompat = "MVS (OS/390 - Z/OS)"; + break; + case OF_ZIP_ARCHIVE_ENTRY_ATTR_COMPAT_VSE: + attrCompat = "VSE"; + break; + case OF_ZIP_ARCHIVE_ENTRY_ATTR_COMPAT_ACORN_RISC: + attrCompat = "Acorn Risc"; + break; + case OF_ZIP_ARCHIVE_ENTRY_ATTR_COMPAT_VFAT: + attrCompat = "VFAT"; + break; + case OF_ZIP_ARCHIVE_ENTRY_ATTR_COMPAT_ALTERNATE_MVS: + attrCompat = "Alternate MVS"; + break; + case OF_ZIP_ARCHIVE_ENTRY_ATTR_COMPAT_BEOS: + attrCompat = "BeOS"; + break; + case OF_ZIP_ARCHIVE_ENTRY_ATTR_COMPAT_TANDEM: + attrCompat = "Tandem"; + break; + case OF_ZIP_ARCHIVE_ENTRY_ATTR_COMPAT_OS_400: + attrCompat = "OS/400"; + break; + case OF_ZIP_ARCHIVE_ENTRY_ATTR_COMPAT_OS_X: + attrCompat = "OS X (Darwin)"; + break; + } + + if (attrCompat != NULL) + return [OFString stringWithFormat: + @"%u.%u, %s", + (version & 0xFF) / 10, (version & 0xFF) % 10, attrCompat]; + else + return [OFString stringWithFormat: + @"%u.%u, unknown %02X", + (version % 0xFF) / 10, (version & 0xFF) % 10, version >> 8]; +} void of_zip_archive_entry_extra_field_find(OFDataArray *extraField, uint16_t tag, uint8_t **data, uint16_t *size) { Index: utils/OFZIP.m ================================================================== --- utils/OFZIP.m +++ utils/OFZIP.m @@ -220,37 +220,52 @@ OFZIPArchiveEntry *entry; while ((entry = [enumerator nextObject]) != nil) { void *pool = objc_autoreleasePoolPush(); + [of_stdout writeLine: [entry fileName]]; + if (_outputLevel >= 1) { OFString *date = [[entry modificationDate] localDateStringWithFormat: @"%Y-%m-%d %H:%M:%S"]; [of_stdout writeFormat: - @"%@: %" PRIu64 @" (%" PRIu64 @") bytes; %08X; %@; " - @"%@", [entry fileName], [entry uncompressedSize], - [entry compressedSize], [entry CRC32], date, - [entry fileComment]]; + @"\tCompressed: %" PRIu64 @" bytes\n" + @"\tUncompressed: %" PRIu64 @" bytes\n" + @"\tCRC32: %08X\n" + @"\tModification date: %@\n", + [entry compressedSize], [entry uncompressedSize], + [entry CRC32], date]; if (_outputLevel >= 2) { - if (([entry versionMadeBy] >> 8) == + uint16_t versionMadeBy = [entry versionMadeBy]; + + [of_stdout writeFormat: + @"\tVersion made by: %@\n" + @"\tMinimum version needed: %@\n", + of_zip_archive_entry_version_to_string( + versionMadeBy), + of_zip_archive_entry_version_to_string( + [entry minVersionNeeded])]; + + if ((versionMadeBy >> 8) == OF_ZIP_ARCHIVE_ENTRY_ATTR_COMPAT_UNIX) { uint32_t mode = [entry versionSpecificAttributes] >> 16; - [of_stdout writeFormat: @"; %06o", - mode]; + [of_stdout writeFormat: + @"\tMode: %06o\n", mode]; } } if (_outputLevel >= 3) - [of_stdout writeFormat: @"; %@", + [of_stdout writeFormat: @"\tExtra field: %@\n", [entry extraField]]; - [of_stdout writeString: @"\n"]; - } else - [of_stdout writeLine: [entry fileName]]; + if ([[entry fileComment] length] > 0) + [of_stdout writeFormat: @"\tComment: %@\n", + [entry fileComment]]; + } objc_autoreleasePoolPop(pool); } }