15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
|
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
|
+
-
-
-
+
+
+
+
-
+
+
+
+
+
-
-
+
+
-
|
*/
#include "config.h"
#include <inttypes.h>
#include <errno.h>
#import "OFApplication.h"
#import "OFDate.h"
#import "OFSet.h"
#import "OFApplication.h"
#import "OFFileManager.h"
#import "OFFileManager.h"
#import "OFLocalization.h"
#import "OFNumber.h"
#import "OFSet.h"
#import "OFStdIOStream.h"
#import "OFLocalization.h"
#import "ZIPArchive.h"
#import "OFZIP.h"
#import "OFInvalidFormatException.h"
#import "OFOpenItemFailedException.h"
#import "OFOutOfRangeException.h"
static OFZIP *app;
static void
setPermissions(OFString *path, OFZIPArchiveEntry *entry)
{
#ifdef OF_FILE_MANAGER_SUPPORTS_PERMISSIONS
if (([entry versionMadeBy] >> 8) ==
OF_ZIP_ARCHIVE_ENTRY_ATTR_COMPAT_UNIX) {
uint16_t mode = [entry versionSpecificAttributes] >> 16;
of_file_attribute_key_t key =
of_file_attribute_key_posix_permissions;
of_file_attributes_t attributes = [OFDictionary
dictionaryWithObject: [OFNumber numberWithUInt16: mode]
forKey: key];
[[OFFileManager defaultManager]
changePermissionsOfItemAtPath: path
[[OFFileManager defaultManager] setAttributes: attributes
ofItemAtPath: path];
permissions: mode];
}
#endif
}
@implementation ZIPArchive
+ (void)initialize
{
|
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
|
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
|
+
-
+
+
-
+
+
+
-
+
-
+
-
-
+
|
return;
}
for (OFString *localFileName in files) {
void *pool = objc_autoreleasePoolPush();
OFArray OF_GENERIC (OFString *) *components;
OFString *fileName;
of_file_attributes_t attributes;
bool isDirectory = false;
OFMutableZIPArchiveEntry *entry;
of_offset_t size;
uintmax_t size;
OFStream *output;
components = [localFileName pathComponents];
fileName = [components componentsJoinedByString: @"/"];
attributes = [fileManager
if ([fileManager directoryExistsAtPath: localFileName]) {
attributesOfItemAtPath: localFileName];
if ([[attributes fileType] isEqual: of_file_type_directory]) {
isDirectory = true;
fileName = [fileName stringByAppendingString: @"/"];
}
if (app->_outputLevel >= 0)
[of_stdout writeString: OF_LOCALIZED(@"adding_file",
@"Adding %[file]...",
@"file", fileName)];
entry = [OFMutableZIPArchiveEntry entryWithFileName: fileName];
if (isDirectory)
size = 0;
else
size = [fileManager sizeOfFileAtPath: localFileName];
size = [attributes fileSize];
if (size > INT64_MAX)
@throw [OFOutOfRangeException exception];
[entry setCompressedSize: (int64_t)size];
[entry setUncompressedSize: (int64_t)size];
[entry setCompressionMethod:
OF_ZIP_ARCHIVE_ENTRY_COMPRESSION_METHOD_NONE];
[entry setModificationDate:
[entry setModificationDate: [attributes fileModificationDate]];
[fileManager modificationDateOfItemAtPath: localFileName]];
[entry makeImmutable];
output = [_archive streamForWritingEntry: entry];
if (!isDirectory) {
int64_t written = 0;
uintmax_t written = 0;
int8_t percent = -1, newPercent;
OFFile *input = [OFFile fileWithPath: fileName
mode: @"r"];
while (![input isAtEndOfStream]) {
ssize_t length = [app
|