Index: utils/ofarc/LHAArchive.m ================================================================== --- utils/ofarc/LHAArchive.m +++ utils/ofarc/LHAArchive.m @@ -16,14 +16,16 @@ #include "config.h" #include #import "OFApplication.h" +#import "OFArray.h" #import "OFDate.h" #import "OFFileManager.h" #import "OFLocale.h" #import "OFNumber.h" +#import "OFPair.h" #import "OFSet.h" #import "OFStdIOStream.h" #import "OFString.h" #import "LHAArchive.h" @@ -261,10 +263,11 @@ - (void)extractFiles: (OFArray OF_GENERIC(OFString *) *)files { OFFileManager *fileManager = [OFFileManager defaultManager]; bool all = (files.count == 0); + OFMutableArray *delayedModificationDates = [OFMutableArray array]; OFMutableSet OF_GENERIC(OFString *) *missing = [OFMutableSet setWithArray: files]; OFLHAArchiveEntry *entry; while ((entry = [_archive nextEntry]) != nil) { @@ -299,11 +302,18 @@ if ([fileName hasSuffix: @"/"]) { [fileManager createDirectoryAtPath: outFileName createParents: true]; setPermissions(outFileName, entry); - setModificationDate(outFileName, entry); + /* + * As creating a new file in a directory changes its + * modification date, we can only set it once all files + * have been created. + */ + [delayedModificationDates addObject: + [OFPair pairWithFirstObject: outFileName + secondObject: entry]]; if (app->_outputLevel >= 0) { [OFStdOut writeString: @"\r"]; [OFStdOut writeLine: OF_LOCALIZED( @"extracting_file_done", @@ -369,10 +379,13 @@ outer_loop_end: objc_autoreleasePoolPop(pool); } + for (OFPair *pair in delayedModificationDates) + setModificationDate(pair.firstObject, pair.secondObject); + if (missing.count > 0) { for (OFString *file in missing) [OFStdErr writeLine: OF_LOCALIZED( @"file_not_in_archive", @"File %[file] is not in the archive!", Index: utils/ofarc/TarArchive.m ================================================================== --- utils/ofarc/TarArchive.m +++ utils/ofarc/TarArchive.m @@ -16,14 +16,16 @@ #include "config.h" #include #import "OFApplication.h" +#import "OFArray.h" #import "OFDate.h" #import "OFFileManager.h" #import "OFLocale.h" #import "OFNumber.h" +#import "OFPair.h" #import "OFSet.h" #import "OFStdIOStream.h" #import "OFString.h" #import "TarArchive.h" @@ -282,10 +284,11 @@ - (void)extractFiles: (OFArray OF_GENERIC(OFString *) *)files { OFFileManager *fileManager = [OFFileManager defaultManager]; bool all = (files.count == 0); + OFMutableArray *delayedModificationDates = [OFMutableArray array]; OFMutableSet OF_GENERIC(OFString *) *missing = [OFMutableSet setWithArray: files]; OFTarArchiveEntry *entry; while ((entry = [_archive nextEntry]) != nil) { @@ -333,11 +336,18 @@ (type == OFTarArchiveEntryTypeFile && [fileName hasSuffix: @"/"])) { [fileManager createDirectoryAtPath: outFileName createParents: true]; setPermissions(outFileName, entry); - setModificationDate(outFileName, entry); + /* + * As creating a new file in a directory changes its + * modification date, we can only set it once all files + * have been created. + */ + [delayedModificationDates addObject: + [OFPair pairWithFirstObject: outFileName + secondObject: entry]]; if (app->_outputLevel >= 0) { [OFStdOut writeString: @"\r"]; [OFStdOut writeLine: OF_LOCALIZED( @"extracting_file_done", @@ -403,10 +413,13 @@ outer_loop_end: objc_autoreleasePoolPop(pool); } + for (OFPair *pair in delayedModificationDates) + setModificationDate(pair.firstObject, pair.secondObject); + if (missing.count > 0) { for (OFString *file in missing) [OFStdErr writeLine: OF_LOCALIZED( @"file_not_in_archive", @"File %[file] is not in the archive!", Index: utils/ofarc/ZIPArchive.m ================================================================== --- utils/ofarc/ZIPArchive.m +++ utils/ofarc/ZIPArchive.m @@ -16,15 +16,17 @@ #include "config.h" #include #import "OFApplication.h" +#import "OFArray.h" #import "OFData.h" #import "OFDate.h" #import "OFFileManager.h" #import "OFLocale.h" #import "OFNumber.h" +#import "OFPair.h" #import "OFSet.h" #import "OFStdIOStream.h" #import "OFString.h" #import "ZIPArchive.h" @@ -271,10 +273,11 @@ - (void)extractFiles: (OFArray OF_GENERIC(OFString *) *)files { OFFileManager *fileManager = [OFFileManager defaultManager]; bool all = (files.count == 0); + OFMutableArray *delayedModificationDates = [OFMutableArray array]; OFMutableSet OF_GENERIC(OFString *) *missing = [OFMutableSet setWithArray: files]; for (OFZIPArchiveEntry *entry in _archive.entries) { void *pool = objc_autoreleasePoolPush(); @@ -308,11 +311,18 @@ if ([fileName hasSuffix: @"/"]) { [fileManager createDirectoryAtPath: outFileName createParents: true]; setPermissions(outFileName, entry); - setModificationDate(outFileName, entry); + /* + * As creating a new file in a directory changes its + * modification date, we can only set it once all files + * have been created. + */ + [delayedModificationDates addObject: + [OFPair pairWithFirstObject: outFileName + secondObject: entry]]; if (app->_outputLevel >= 0) { [OFStdOut writeString: @"\r"]; [OFStdOut writeLine: OF_LOCALIZED( @"extracting_file_done", @@ -378,10 +388,13 @@ outer_loop_end: objc_autoreleasePoolPop(pool); } + for (OFPair *pair in delayedModificationDates) + setModificationDate(pair.firstObject, pair.secondObject); + if (missing.count > 0) { for (OFString *file in missing) [OFStdErr writeLine: OF_LOCALIZED( @"file_not_in_archive", @"File %[file] is not in the archive!",