Index: utils/ofzip/OFZIP.h ================================================================== --- utils/ofzip/OFZIP.h +++ utils/ofzip/OFZIP.h @@ -26,12 +26,13 @@ int8_t _outputLevel; OFString *_archivePath; int _exitStatus; } -- (id )openArchiveWithPath: (OFString*)path; +- (id )openArchiveWithPath: (OFString*)path + type: (OFString*)type; - (bool)shouldExtractFile: (OFString*)fileName outFileName: (OFString*)outFileName; - (ssize_t)copyBlockFromStream: (OFStream*)input toStream: (OFStream*)output fileName: (OFString*)fileName; @end Index: utils/ofzip/OFZIP.m ================================================================== --- utils/ofzip/OFZIP.m +++ utils/ofzip/OFZIP.m @@ -42,11 +42,11 @@ static void help(OFStream *stream, bool full, int status) { [stream writeFormat: - @"Usage: %@ -[fhlnpqvx] archive.zip [file1 file2 ...]\n", + @"Usage: %@ -[fhlnpqtvx] archive.zip [file1 file2 ...]\n", [OFApplication programName]]; if (full) [stream writeString: @"\nOptions:\n" @@ -56,10 +56,11 @@ @" -n --no-clober Never overwrite files\n" @" -p --print Print one or more files from the " @"archive\n" @" -q --quiet Quiet mode (no output, except " @"errors)\n" + @" -t --type Archive type (gz, tar, tgz, zip)\n" @" -v --verbose Verbose output for file list\n" @" -x --extract Extract files\n"]; [OFApplication terminateWithStatus: status]; } @@ -87,17 +88,19 @@ } @implementation OFZIP - (void)applicationDidFinishLaunching { + OFString *type = nil; const of_options_parser_option_t options[] = { { 'f', @"force", 0, NULL, NULL }, { 'h', @"help", 0, NULL, NULL }, { 'l', @"list", 0, NULL, NULL }, { 'n', @"no-clobber", 0, NULL, NULL }, { 'p', @"print", 0, NULL, NULL }, { 'q', @"quiet", 0, NULL, NULL }, + { 't', @"type", 1, NULL, &type }, { 'v', @"verbose", 0, NULL, NULL }, { 'x', @"extract", 0, NULL, NULL }, { '\0', nil, 0, NULL, NULL } }; OFOptionsParser *optionsParser = @@ -155,11 +158,11 @@ [OFApplication programName], [optionsParser lastLongOption]]; [OFApplication terminateWithStatus: 1]; break; - default: + case '?': if ([optionsParser lastLongOption] != nil) [of_stderr writeFormat: @"%@: Unknown option: --%@\n", [OFApplication programName], [optionsParser lastLongOption]]; @@ -172,11 +175,12 @@ [OFApplication terminateWithStatus: 1]; } } remainingArguments = [optionsParser remainingArguments]; - archive = [self openArchiveWithPath: [remainingArguments firstObject]]; + archive = [self openArchiveWithPath: [remainingArguments firstObject] + type: type]; switch (mode) { case 'l': if ([remainingArguments count] != 1) help(of_stderr, false, 1); @@ -221,10 +225,11 @@ [OFApplication terminateWithStatus: _exitStatus]; } - (id )openArchiveWithPath: (OFString*)path + type: (OFString*)type { OFFile *file = nil; id archive = nil; [_archivePath release]; @@ -240,22 +245,38 @@ [of_stderr writeFormat: @"Failed to open file %@: %s\n", [e path], strerror([e errNo])]; [OFApplication terminateWithStatus: 1]; } - @try { + if (type == nil || [type isEqual: @"auto"]) { /* This one has to be first for obvious reasons */ if ([path hasSuffix: @".tar.gz"] || [path hasSuffix: @".tgz"] || [path hasSuffix: @".TAR.GZ"] || [path hasSuffix: @".TGZ"]) + type = @"tgz"; + else if ([path hasSuffix: @".gz"] || [path hasSuffix: @".GZ"]) + type = @"gz"; + else if ([path hasSuffix: @".tar"] || [path hasSuffix: @".TAR"]) + type = @"tar"; + else + type = @"zip"; + } + + @try { + if ([type isEqual: @"gz"]) + archive = [GZIPArchive archiveWithStream: file]; + else if ([type isEqual: @"tar"]) + archive = [TarArchive archiveWithStream: file]; + else if ([type isEqual: @"tgz"]) archive = [TarArchive archiveWithStream: [OFGZIPStream streamWithStream: file]]; - else if ([path hasSuffix: @".gz"] || [path hasSuffix: @".GZ"]) - archive = [GZIPArchive archiveWithStream: file]; - else if ([path hasSuffix: @".tar"] || [path hasSuffix: @".TAR"]) - archive = [TarArchive archiveWithStream: file]; - else + else if ([type isEqual: @"zip"]) archive = [ZIPArchive archiveWithStream: file]; + else { + [of_stderr writeFormat: @"Unknown archive type: %@!\n", + type]; + [OFApplication terminateWithStatus: 1]; + } } @catch (OFReadFailedException *e) { [of_stderr writeFormat: @"Failed to read file %@: %s\n", path, strerror([e errNo])]; [OFApplication terminateWithStatus: 1]; } @catch (OFInvalidFormatException *e) {