@@ -17,10 +17,11 @@ #import "OFApplication.h" #import "OFArray.h" #import "OFFile.h" #import "OFIRI.h" +#import "OFIRIHandler.h" #import "OFLocale.h" #import "OFMD5Hash.h" #import "OFOptionsParser.h" #import "OFRIPEMD160Hash.h" #import "OFSHA1Hash.h" @@ -43,11 +44,11 @@ static void help(void) { [OFStdErr writeLine: OF_LOCALIZED(@"usage", @"Usage: %[prog] [--md5] [--ripemd160] [--sha1] [--sha224] " - @"[--sha256] [--sha384] [--sha512] file1 [file2 ...]", + @"[--sha256] [--sha384] [--sha512] [--iri] file1 [file2 ...]", @"prog", [OFApplication programName])]; [OFApplication terminateWithStatus: 1]; } @@ -71,19 +72,20 @@ @implementation OFHash - (void)applicationDidFinishLaunching: (OFNotification *)notification { int exitStatus = 0; bool calculateMD5, calculateRIPEMD160, calculateSHA1, calculateSHA224; - bool calculateSHA256, calculateSHA384, calculateSHA512; + bool calculateSHA256, calculateSHA384, calculateSHA512, isIRI; const OFOptionsParserOption options[] = { { '\0', @"md5", 0, &calculateMD5, NULL }, { '\0', @"ripemd160", 0, &calculateRIPEMD160, NULL }, { '\0', @"sha1", 0, &calculateSHA1, NULL }, { '\0', @"sha224", 0, &calculateSHA224, NULL }, { '\0', @"sha256", 0, &calculateSHA256, NULL }, { '\0', @"sha384", 0, &calculateSHA384, NULL }, { '\0', @"sha512", 0, &calculateSHA512, NULL }, + { '\0', @"iri", 0, &isIRI, NULL }, { '\0', nil, 0, NULL, NULL } }; OFOptionsParser *optionsParser = [OFOptionsParser parserWithOptions: options]; OFUnichar option; @@ -132,12 +134,13 @@ @try { sandbox.allowsStdIO = true; sandbox.allowsReadingFiles = true; sandbox.allowsUserDatabaseReading = true; - for (OFString *path in optionsParser.remainingArguments) - [sandbox unveilPath: path permissions: @"r"]; + if (!isIRI) + for (OFString *path in optionsParser.remainingArguments) + [sandbox unveilPath: path permissions: @"r"]; [sandbox unveilPath: @LOCALIZATION_DIR permissions: @"r"]; [OFApplication of_activateSandbox: sandbox]; } @finally { @@ -171,24 +174,35 @@ for (OFString *path in optionsParser.remainingArguments) { void *pool = objc_autoreleasePoolPush(); OFStream *file; - if ([path isEqual: @"-"]) + if (!isIRI && [path isEqual: @"-"]) file = OFStdIn; else { @try { - file = [OFFile fileWithPath: path mode: @"r"]; + if (isIRI) { + OFIRI *IRI = + [OFIRI IRIWithString: path]; + + file = [OFIRIHandler + openItemAtIRI: IRI + mode: @"r"]; + } else + file = [OFFile fileWithPath: path + mode: @"r"]; } @catch (OFOpenItemFailedException *e) { OFString *error = [OFString stringWithCString: strerror(e.errNo) encoding: [OFLocale encoding]]; + OFString *filePath = + (e.IRI != nil ? e.IRI.string : e.path); [OFStdErr writeLine: OF_LOCALIZED( @"failed_to_open_file", @"Failed to open file %[file]: %[error]", - @"file", e.path, + @"file", filePath, @"error", error)]; exitStatus = 1; goto outer_loop_end; }