@@ -1,7 +1,7 @@ /* - * Copyright (c) 2008-2022 Jonathan Schleifer + * Copyright (c) 2008-2024 Jonathan Schleifer * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in @@ -19,15 +19,15 @@ #import "OFApplication.h" #import "OFArray.h" #import "OFFile.h" #import "OFFileManager.h" +#import "OFIRI.h" #import "OFLocale.h" #import "OFOptionsParser.h" #import "OFSandbox.h" #import "OFStdIOStream.h" -#import "OFURI.h" #import "OFArc.h" #import "GZIPArchive.h" #import "LHAArchive.h" #import "TarArchive.h" @@ -57,23 +57,23 @@ [stream writeString: @"\n"]; [stream writeLine: OF_LOCALIZED(@"full_usage", @"Options:\n" @" -a --append Append to archive\n" @" -c --create Create archive\n" - @" -C --directory Extract into the specified " + @" -C --directory= Extract into the specified " @"directory\n" - @" -E --encoding The encoding used by the archive " + @" -E --encoding= The encoding used by the archive " "(only tar files)\n" @" -f --force Force / overwrite files\n" @" -h --help Show this help\n" @" -l --list List all files in the archive\n" @" -n --no-clobber 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, lha, tar, tgz, " + @" -t --type= Archive type (gz, lha, tar, tgz, " @"zip)\n" @" -v --verbose Verbose output for file list\n" @" -x --extract Extract files")]; } @@ -165,11 +165,11 @@ [archive addFiles: expandedFiles]; } @implementation OFArc -- (void)applicationDidFinishLaunching +- (void)applicationDidFinishLaunching: (OFNotification *)notification { OFString *outputDir, *encodingString, *type; const OFOptionsParserOption options[] = { { 'a', @"append", 0, NULL, NULL }, { 'c', @"create", 0, NULL, NULL }, @@ -205,14 +205,15 @@ [OFApplication of_activateSandbox: sandbox]; #endif #ifndef OF_AMIGAOS - [OFLocale addLocalizationDirectory: @LOCALIZATION_DIR]; + [OFLocale addLocalizationDirectoryIRI: + [OFIRI fileIRIWithPath: @LOCALIZATION_DIR]]; #else - [OFLocale addLocalizationDirectory: - @"PROGDIR:/share/ofarc/localization"]; + [OFLocale addLocalizationDirectoryIRI: + [OFIRI fileIRIWithPath: @"PROGDIR:/share/ofarc/localization"]]; #endif optionsParser = [OFOptionsParser parserWithOptions: options]; while ((option = [optionsParser nextOption]) != '\0') { switch (option) { @@ -460,11 +461,11 @@ encoding: [OFLocale encoding]]; [OFStdErr writeString: @"\r"]; [OFStdErr writeLine: OF_LOCALIZED( @"failed_to_create_directory", @"Failed to create directory %[dir]: %[error]", - @"dir", e.URI.fileSystemRepresentation, + @"dir", e.IRI.fileSystemRepresentation, @"error", error)]; _exitStatus = 1; } @catch (OFOpenItemFailedException *e) { OFString *error = [OFString stringWithCString: strerror(e.errNo) @@ -485,15 +486,17 @@ } [OFApplication terminateWithStatus: _exitStatus]; } -- (id )openArchiveWithPath: (OFString *)path +- (id )openArchiveWithPath: (OFString *)path_ type: (OFString *)type mode: (char)mode encoding: (OFStringEncoding)encoding { + /* To make clang-analyzer happy about assigning nil to path later. */ + OFString *path = path_; OFString *modeString, *fileModeString; OFStream *file = nil; id archive = nil; [_archivePath release]; @@ -531,10 +534,12 @@ file = OFStdIn; break; default: @throw [OFInvalidArgumentException exception]; } + + path = nil; } else { @try { file = [OFFile fileWithPath: path mode: fileModeString]; } @catch (OFOpenItemFailedException *e) { OFString *error = [OFString @@ -565,32 +570,37 @@ type = @"zip"; } @try { if ([type isEqual: @"gz"]) - archive = [GZIPArchive archiveWithStream: file - mode: modeString - encoding: encoding]; + archive = [GZIPArchive archiveWithPath: path + stream: file + mode: modeString + encoding: encoding]; else if ([type isEqual: @"lha"]) - archive = [LHAArchive archiveWithStream: file - mode: modeString - encoding: encoding]; + archive = [LHAArchive archiveWithPath: path + stream: file + mode: modeString + encoding: encoding]; else if ([type isEqual: @"tar"]) - archive = [TarArchive archiveWithStream: file - mode: modeString - encoding: encoding]; + archive = [TarArchive archiveWithPath: path + stream: file + mode: modeString + encoding: encoding]; else if ([type isEqual: @"tgz"]) { OFStream *GZIPStream = [OFGZIPStream streamWithStream: file mode: modeString]; - archive = [TarArchive archiveWithStream: GZIPStream - mode: modeString - encoding: encoding]; + archive = [TarArchive archiveWithPath: path + stream: GZIPStream + mode: modeString + encoding: encoding]; } else if ([type isEqual: @"zip"]) - archive = [ZIPArchive archiveWithStream: file - mode: modeString - encoding: encoding]; + archive = [ZIPArchive archiveWithPath: path + stream: file + mode: modeString + encoding: encoding]; else { [OFStdErr writeLine: OF_LOCALIZED( @"unknown_archive_type", @"Unknown archive type: %[type]", @"type", type)]; @@ -637,15 +647,15 @@ } return archive; error: - if (mode == 'c') + if (mode == 'c' && path != nil) [[OFFileManager defaultManager] removeItemAtPath: path]; [OFApplication terminateWithStatus: 1]; - return nil; + abort(); } - (bool)shouldExtractFile: (OFString *)fileName outFileName: (OFString *)outFileName {