@@ -21,10 +21,11 @@ #import "OFDate.h" #import "OFSet.h" #import "OFApplication.h" #import "OFFileManager.h" #import "OFStdIOStream.h" +#import "OFLocalization.h" #import "TarArchive.h" #import "OFZIP.h" #ifndef S_IRWXG @@ -94,72 +95,140 @@ [of_stdout writeLine: [entry fileName]]; if (app->_outputLevel >= 1) { OFString *date = [[entry modificationDate] localDateStringWithFormat: @"%Y-%m-%d %H:%M:%S"]; - - [of_stdout writeFormat: - @"\tSize: %" PRIu64 @" bytes\n" - @"\tMode: %06o\n", - [entry size], [entry mode]]; - - if ([entry owner] != nil) - [of_stdout writeFormat: @"\tOwner: %@\n", - [entry owner]]; - if ([entry group] != nil) - [of_stdout writeFormat: @"\tGroup: %@\n", - [entry group]]; - - [of_stdout writeFormat: @"\tModification date: %@\n", - date]; + OFString *size = [OFString stringWithFormat: + @"%" PRIu64, [entry size]]; + OFString *mode = [OFString stringWithFormat: + @"%06o", [entry mode]]; + + [of_stdout writeString: @"\t"]; + [of_stdout writeLine: OF_LOCALIZED(@"list_size", + @"Size: %[size] bytes", + @"size", size)]; + [of_stdout writeString: @"\t"]; + [of_stdout writeLine: OF_LOCALIZED(@"list_mode", + @"Mode: %[mode]", + @"mode", mode)]; + + if ([entry owner] != nil) { + [of_stdout writeString: @"\t"]; + [of_stdout writeLine: OF_LOCALIZED( + @"list_owner", + @"Owner: %[owner]", + @"owner", [entry owner])]; + } + if ([entry group] != nil) { + [of_stdout writeString: @"\t"]; + [of_stdout writeLine: OF_LOCALIZED( + @"list_group", + @"Group: %[group]", + @"group", [entry group])]; + } + + [of_stdout writeString: @"\t"]; + [of_stdout writeLine: OF_LOCALIZED( + @"list_modification_date", + @"Modification date: %[date]", + @"date", date)]; } if (app->_outputLevel >= 2) { + [of_stdout writeString: @"\t"]; + switch ([entry type]) { case OF_TAR_ARCHIVE_ENTRY_TYPE_FILE: - [of_stdout writeLine: @"\tType: Normal file"]; + [of_stdout writeLine: OF_LOCALIZED( + @"list_type_normal", + @"Type: Normal file")]; break; case OF_TAR_ARCHIVE_ENTRY_TYPE_LINK: - [of_stdout writeLine: @"\tType: Hard link"]; - [of_stdout writeFormat: - @"\tTarget file name: %@\n", - [entry targetFileName]]; + [of_stdout writeLine: OF_LOCALIZED( + @"list_type_hardlink", + @"Type: Hard link")]; + [of_stdout writeString: @"\t"]; + [of_stdout writeLine: OF_LOCALIZED( + @"list_link_target", + @"Target file name: %[target]", + @"target", [entry targetFileName])]; break; case OF_TAR_ARCHIVE_ENTRY_TYPE_SYMLINK: - [of_stdout writeLine: @"\tType: Symbolic link"]; - [of_stdout writeFormat: - @"\tTarget file name: %@\n", - [entry targetFileName]]; - break; - case OF_TAR_ARCHIVE_ENTRY_TYPE_CHARACTER_DEVICE: - [of_stdout writeLine: - @"\tType: Character device"]; - [of_stdout writeFormat: @"\tDevice major: %d\n" - @"\tDevice minor: %d\n", - [entry deviceMajor], - [entry deviceMinor]]; - break; - case OF_TAR_ARCHIVE_ENTRY_TYPE_BLOCK_DEVICE: - [of_stdout writeLine: - @"\tType: Block device"]; - [of_stdout writeFormat: @"\tDevice major: %d\n" - @"\tDevice minor: %d\n", - [entry deviceMajor], - [entry deviceMinor]]; - break; - case OF_TAR_ARCHIVE_ENTRY_TYPE_DIRECTORY: - [of_stdout writeLine: @"\tType: Directory"]; + [of_stdout writeLine: OF_LOCALIZED( + @"list_type_symlink", + @"Type: Symbolic link")]; + [of_stdout writeString: @"\t"]; + [of_stdout writeLine: OF_LOCALIZED( + @"list_link_target", + @"Target file name: %[target]", + @"target", [entry targetFileName])]; + break; + case OF_TAR_ARCHIVE_ENTRY_TYPE_CHARACTER_DEVICE: { + OFString *majorString = [OFString + stringWithFormat: @"%d", + [entry deviceMajor]]; + OFString *minorString = [OFString + stringWithFormat: @"%d", + [entry deviceMinor]]; + + [of_stdout writeLine: OF_LOCALIZED( + @"list_type_character_device", + @"Type: Character device")]; + [of_stdout writeString: @"\t"]; + [of_stdout writeLine: OF_LOCALIZED( + @"list_device_major", + @"Device major: %[major]", + @"major", majorString)]; + [of_stdout writeString: @"\t"]; + [of_stdout writeLine: OF_LOCALIZED( + @"list_device_minor", + @"Device minor: %[minor]", + @"minor", minorString)]; + break; + } + case OF_TAR_ARCHIVE_ENTRY_TYPE_BLOCK_DEVICE: { + OFString *majorString = [OFString + stringWithFormat: @"%d", + [entry deviceMajor]]; + OFString *minorString = [OFString + stringWithFormat: @"%d", + [entry deviceMinor]]; + + [of_stdout writeLine: OF_LOCALIZED( + @"list_type_block_device", + @"Type: Block device")]; + [of_stdout writeString: @"\t"]; + [of_stdout writeLine: OF_LOCALIZED( + @"list_device_major", + @"Device major: %[major]", + @"major", majorString)]; + [of_stdout writeString: @"\t"]; + [of_stdout writeLine: OF_LOCALIZED( + @"list_device_minor", + @"Device minor: %[minor]", + @"minor", minorString)]; + break; + } + case OF_TAR_ARCHIVE_ENTRY_TYPE_DIRECTORY: + [of_stdout writeLine: OF_LOCALIZED( + @"list_type_directory", + @"Type: Directory")]; break; case OF_TAR_ARCHIVE_ENTRY_TYPE_FIFO: - [of_stdout writeLine: @"\tType: FIFO"]; + [of_stdout writeLine: OF_LOCALIZED( + @"list_type_fifo", + @"Type: FIFO")]; break; case OF_TAR_ARCHIVE_ENTRY_TYPE_CONTIGUOUS_FILE: - [of_stdout writeLine: - @"\tType: Contiguous file"]; + [of_stdout writeLine: OF_LOCALIZED( + @"list_type_contiguous_file", + @"Type: Contiguous file")]; break; default: - [of_stdout writeLine: @"\tType: Unknown"]; + [of_stdout writeLine: OF_LOCALIZED( + @"list_type_unknown", + @"Type: Unknown")]; break; } } objc_autoreleasePoolPop(pool); @@ -187,12 +256,14 @@ if (!all && ![files containsObject: fileName]) continue; if ([entry type] != OF_TAR_ARCHIVE_ENTRY_TYPE_FILE) { if (app->_outputLevel >= 0) - [of_stdout writeFormat: @"Skipping %@...\n", - fileName]; + [of_stdout writeLine: OF_LOCALIZED( + @"skipping_file", + @"Skipping %[file]...", + @"file", fileName)]; continue; } [missing removeObject: fileName]; @@ -200,39 +271,50 @@ if ([outFileName hasPrefix: @"/"]) { #else if ([outFileName hasPrefix: @"/"] || [outFileName containsString: @":"]) { #endif - [of_stderr writeFormat: @"Refusing to extract %@!\n", - fileName]; + [of_stderr writeLine: OF_LOCALIZED( + @"refusing_to_extract_file", + @"Refusing to extract %[file]!", + @"file", fileName)]; app->_exitStatus = 1; goto outer_loop_end; } pathComponents = [outFileName pathComponents]; for (OFString *component in pathComponents) { if ([component isEqual: OF_PATH_PARENT_DIRECTORY]) { - [of_stderr writeFormat: - @"Refusing to extract %@!\n", fileName]; + [of_stderr writeLine: OF_LOCALIZED( + @"refusing_to_extract_file", + @"Refusing to extract %[file]!", + @"file", fileName)]; app->_exitStatus = 1; goto outer_loop_end; } } outFileName = [OFString pathWithComponents: pathComponents]; if (app->_outputLevel >= 0) - [of_stdout writeFormat: @"Extracting %@...", fileName]; + [of_stdout writeString: OF_LOCALIZED(@"extracting_file", + @"Extracting %[file]...", + @"file", fileName)]; if ([fileName hasSuffix: @"/"]) { [fileManager createDirectoryAtPath: outFileName createParents: true]; setPermissions(outFileName, entry); - if (app->_outputLevel >= 0) - [of_stdout writeLine: @" done"]; + if (app->_outputLevel >= 0) { + [of_stdout writeString: @"\r"]; + [of_stdout writeLine: OF_LOCALIZED( + @"extracting_file_done", + @"Extracting %[file]... done", + @"file", fileName)]; + } goto outer_loop_end; } directory = [outFileName stringByDeletingLastPathComponent]; @@ -261,30 +343,43 @@ written += length; newPercent = (written == size ? 100 : (int8_t)(written * 100 / size)); if (app->_outputLevel >= 0 && percent != newPercent) { + OFString *percentString; + percent = newPercent; + percentString = [OFString stringWithFormat: + @"%3u", percent]; - [of_stdout writeFormat: - @"\rExtracting %@... %3u%%", - fileName, percent]; + [of_stdout writeString: @"\r"]; + [of_stdout writeString: OF_LOCALIZED( + @"extracting_file_percent", + @"Extracting %[file]... %[percent]%", + @"file", fileName, + @"percent", percentString)]; } } - if (app->_outputLevel >= 0) - [of_stdout writeFormat: @"\rExtracting %@... done\n", - fileName]; + if (app->_outputLevel >= 0) { + [of_stdout writeString: @"\r"]; + [of_stdout writeLine: OF_LOCALIZED( + @"extracting_file_done", + @"Extracting %[file]... done", + @"file", fileName)]; + } outer_loop_end: objc_autoreleasePoolPop(pool); } if ([missing count] > 0) { for (OFString *file in missing) - [of_stderr writeFormat: - @"File %@ is not in the archive!\n", file]; + [of_stderr writeLine: OF_LOCALIZED( + @"file_not_in_archive", + @"File %[file] is not in the archive!", + @"file", file)]; app->_exitStatus = 1; } } @@ -292,11 +387,12 @@ { OFMutableSet *files; OFTarArchiveEntry *entry; if ([files_ count] < 1) { - [of_stderr writeLine: @"Need one or more files to print!"]; + [of_stderr writeLine: OF_LOCALIZED(@"print_no_file_specified", + @"Need one or more files to print!")]; app->_exitStatus = 1; return; } files = [OFMutableSet setWithArray: files_]; @@ -320,12 +416,13 @@ [files removeObject: fileName]; [entry close]; } - for (OFString *path in files) { - [of_stderr writeFormat: @"File %@ is not in the archive!\n", - path]; + for (OFString *file in files) { + [of_stderr writeLine: OF_LOCALIZED(@"file_not_in_archive", + @"File %[file] is not in the archive!", + @"file", file)]; app->_exitStatus = 1; } } @end