ObjFW  Check-in [c7bdb196d4]

Overview
Comment:Rename all types in OFFileManager.h
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | new-naming-convention
Files: files | file ages | folders
SHA3-256: c7bdb196d4d0384db983b67f133b14b9fb206bac230563505248b2bbbe86c494
User & Date: js on 2021-04-17 05:16:32
Other Links: branch diff | manifest | tags
Context
2021-04-17
05:22
Rename of_options_parser_option_t check-in: 91daa42649 user: js tags: new-naming-convention
05:16
Rename all types in OFFileManager.h check-in: c7bdb196d4 user: js tags: new-naming-convention
03:37
of_run_loop_mode_t -> OFRunLoopMode check-in: b480ef54db user: js tags: new-naming-convention
Changes

Modified src/OFFileManager.h from [056f59171f] to [a969db1ae2].

42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60












61
62
63
64

65
66
67
68
69
70
71
72
73
74
75
76
77








78
79
80
81

82
83
84
85


86
87

88
89
90
91
92


93
94
95


96
97
98
99
100
101
102
103
104
105
106

107
108
109
110
111

112
113
114
115
116

117
118
119
120
121
122
123
124

125
126
127

128
129
130

131
132

133
134
135

136
137
138

139
140

141
142
143

144
145
146

147
148

149
150
151

152
153
154

155
156

157
158
159
160
161
162
163
164

165
166
167
168
169
170
171
172

173
174
175
176
177
178
179
180

181
182
183
184
185
186
187
188

189
190
191
192
193
194
195
196

197
198
199
200
201
202

203
204
205
206
207

208
209
210
211
212

213
214
215
216
217

218
219
220
221
222

223
224
225
226
227

228
229
230
231
232

233
234
235
236
237
238
239
42
43
44
45
46
47
48












49
50
51
52
53
54
55
56
57
58
59
60
61
62
63

64
65
66
67
68
69
70







71
72
73
74
75
76
77
78
79
80
81

82
83
84


85
86
87

88

89
90


91
92
93


94
95
96
97
98
99
100
101
102
103
104
105

106
107
108
109
110

111
112
113
114
115

116
117
118
119
120
121
122
123

124
125
126

127
128
129

130
131

132
133
134

135
136
137

138
139

140
141
142

143
144
145

146
147

148
149
150

151
152
153

154
155

156
157
158
159
160
161
162
163

164
165
166
167
168
169
170
171

172
173
174
175
176
177
178
179

180
181
182
183
184
185
186
187

188
189
190
191
192
193
194
195

196

197
198
199
200

201
202
203
204
205

206
207
208
209
210

211
212
213
214
215

216
217
218
219
220

221
222
223
224
225

226
227
228
229
230

231
232
233
234
235
236
237
238







-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+



-
+






-
-
-
-
-
-
-
+
+
+
+
+
+
+
+



-
+


-
-
+
+

-
+
-


-
-
+
+

-
-
+
+










-
+




-
+




-
+







-
+


-
+


-
+

-
+


-
+


-
+

-
+


-
+


-
+

-
+


-
+


-
+

-
+







-
+







-
+







-
+







-
+







-
+
-




-
+




-
+




-
+




-
+




-
+




-
+




-
+







@class OFURL;

/**
 * @brief A key for a file attribute in the file attributes dictionary.
 *
 * Possible keys for file URLs are:
 *
 *  * @ref of_file_attribute_key_size
 *  * @ref of_file_attribute_key_type
 *  * @ref of_file_attribute_key_posix_permissions
 *  * @ref of_file_attribute_key_posix_uid
 *  * @ref of_file_attribute_key_posix_gid
 *  * @ref of_file_attribute_key_owner
 *  * @ref of_file_attribute_key_group
 *  * @ref of_file_attribute_key_last_access_date
 *  * @ref of_file_attribute_key_modification_date
 *  * @ref of_file_attribute_key_status_change_date
 *  * @ref of_file_attribute_key_creation_date
 *  * @ref of_file_attribute_key_symbolic_link_destination
 *  * @ref OFFileSize
 *  * @ref OFFileType
 *  * @ref OFFilePOSIXPermissions
 *  * @ref OFFileOwnerAccountID
 *  * @ref OFFileGroupOwnerAccountID
 *  * @ref OFFileOwnerAccountName
 *  * @ref OFFileGroupOwnerAccountName
 *  * @ref OFFileLastAccessDate
 *  * @ref OFFileModificationDate
 *  * @ref OFFileStatusChangeDate
 *  * @ref OFFileCreationDate
 *  * @ref OFFileSymbolicLinkDestination
 *
 * Other URL schemes might not have all keys and might have keys not listed.
 */
typedef OFConstantString *of_file_attribute_key_t;
typedef OFConstantString *OFFileAttributeKey;

/**
 * @brief The type of a file.
 *
 * Possibles values for file URLs are:
 *
 *  * @ref of_file_type_regular
 *  * @ref of_file_type_directory
 *  * @ref of_file_type_symbolic_link
 *  * @ref of_file_type_fifo
 *  * @ref of_file_type_character_special
 *  * @ref of_file_type_block_special
 *  * @ref of_file_type_socket
 *  * @ref OFFileTypeRegular
 *  * @ref OFFileTypeDirectory
 *  * @ref OFFileTypeSymbolicLink
 *  * @ref OFFileTypeFIFO
 *  * @ref OFFileTypeCharacterSpecial
 *  * @ref OFFileTypeBlockSpecial
 *  * @ref OFFileTypeSocket
 *  * @ref OFFileTypeUnknown
 *
 * Other URL schemes might not have all types and might have types not listed.
 */
typedef OFConstantString *of_file_type_t;
typedef OFConstantString *OFFileAttributeType;

/**
 * @brief A dictionary mapping keys of type @ref of_file_attribute_key_t
 *	  to their attribute values.
 * @brief A dictionary mapping keys of type @ref OFFileAttributeKey to their
 *	  attribute values.
 */
typedef OFDictionary OF_GENERIC(of_file_attribute_key_t, id)
typedef OFDictionary OF_GENERIC(OFFileAttributeKey, id) *OFFileAttributes;
    *of_file_attributes_t;

/**
 * @brief A mutable dictionary mapping keys of type
 *	  @ref of_file_attribute_key_t to their attribute values.
 * @brief A mutable dictionary mapping keys of type @ref OFFileAttributeKey to
 *	  their attribute values.
 */
typedef OFMutableDictionary OF_GENERIC(of_file_attribute_key_t, id)
    *of_mutable_file_attributes_t;
typedef OFMutableDictionary OF_GENERIC(OFFileAttributeKey, id)
    *OFMutableFileAttributes;

#ifdef __cplusplus
extern "C" {
#endif
/**
 * @brief The size of the file as an @ref OFNumber.
 *
 * For convenience, a category on @ref OFDictionary is provided to access this
 * via @ref OFDictionary#fileSize.
 */
extern const of_file_attribute_key_t of_file_attribute_key_size;
extern const OFFileAttributeKey OFFileSize;

/**
 * @brief The type of the file.
 *
 * The corresponding value is of type @ref of_file_type_t.
 * The corresponding value is of type @ref OFFileAttributeType.
 *
 * For convenience, a category on @ref OFDictionary is provided to access this
 * via @ref OFDictionary#fileType.
 */
extern const of_file_attribute_key_t of_file_attribute_key_type;
extern const OFFileAttributeKey OFFileType;

/**
 * @brief The POSIX permissions of the file as an @ref OFNumber.
 *
 * For convenience, a category on @ref OFDictionary is provided to access this
 * via @ref OFDictionary#filePOSIXPermissions.
 */
extern const of_file_attribute_key_t of_file_attribute_key_posix_permissions;
extern const OFFileAttributeKey OFFilePOSIXPermissions;

/**
 * @brief The POSIX UID of the file as an @ref OFNumber.
 * @brief The account ID of the owner of the file as an @ref OFNumber.
 *
 * For convenience, a category on @ref OFDictionary is provided to access this
 * via @ref OFDictionary#filePOSIXUID.
 * via @ref OFDictionary#fileOwnerAccountID.
 */
extern const of_file_attribute_key_t of_file_attribute_key_posix_uid;
extern const OFFileAttributeKey OFFileOwnerAccountID;

/**
 * @brief The POSIX GID of the file as an @ref OFNumber.
 * @brief The account ID of the group owner of the file as an @ref OFNumber.
 *
 * For convenience, a category on @ref OFDictionary is provided to access this
 * via @ref OFDictionary#filePOSIXGID.
 * via @ref OFDictionary#fileGroupOwnerAccountID.
 */
extern const of_file_attribute_key_t of_file_attribute_key_posix_gid;
extern const OFFileAttributeKey OFFileGroupOwnerAccountID;

/**
 * @brief The owner of the file as an OFString.
 * @brief The account name of the owner of the file as an OFString.
 *
 * For convenience, a category on @ref OFDictionary is provided to access this
 * via @ref OFDictionary#fileOwner.
 * via @ref OFDictionary#fileOwnerAccountName.
 */
extern const of_file_attribute_key_t of_file_attribute_key_owner;
extern const OFFileAttributeKey OFFileOwnerAccountName;

/**
 * @brief The group of the file as an OFString.
 * @brief The account name of the group owner of the file as an OFString.
 *
 * For convenience, a category on @ref OFDictionary is provided to access this
 * via @ref OFDictionary#fileGroup.
 * via @ref OFDictionary#fileGroupOwnerAccountName.
 */
extern const of_file_attribute_key_t of_file_attribute_key_group;
extern const OFFileAttributeKey OFFileGroupOwnerAccountName;

/**
 * @brief The last access date of the file as an @ref OFDate.
 *
 * For convenience, a category on @ref OFDictionary is provided to access this
 * via @ref OFDictionary#fileLastAccessDate.
 */
extern const of_file_attribute_key_t of_file_attribute_key_last_access_date;
extern const OFFileAttributeKey OFFileLastAccessDate;

/**
 * @brief The last modification date of the file as an @ref OFDate.
 *
 * For convenience, a category on @ref OFDictionary is provided to access this
 * via @ref OFDictionary#fileModificationDate.
 */
extern const of_file_attribute_key_t of_file_attribute_key_modification_date;
extern const OFFileAttributeKey OFFileModificationDate;

/**
 * @brief The last status change date of the file as an @ref OFDate.
 *
 * For convenience, a category on @ref OFDictionary is provided to access this
 * via @ref OFDictionary#fileStatusChangeDate.
 */
extern const of_file_attribute_key_t of_file_attribute_key_status_change_date;
extern const OFFileAttributeKey OFFileStatusChangeDate;

/**
 * @brief The creation date of the file as an @ref OFDate.
 *
 * For convenience, a category on @ref OFDictionary is provided to access this
 * via @ref OFDictionary#fileCreationDate.
 */
extern const of_file_attribute_key_t of_file_attribute_key_creation_date;
extern const OFFileAttributeKey OFFileCreationDate;

/**
 * @brief The destination of a symbolic link as an OFString.
 *
 * For convenience, a category on @ref OFDictionary is provided to access this
 * via @ref OFDictionary#fileSymbolicLinkDestination.
 */
extern const of_file_attribute_key_t
extern const OFFileAttributeKey OFFileSymbolicLinkDestination;
    of_file_attribute_key_symbolic_link_destination;

/**
 * @brief A regular file.
 */
extern const of_file_type_t of_file_type_regular;
extern const OFFileAttributeType OFFileTypeRegular;

/**
 * @brief A directory.
 */
extern const of_file_type_t of_file_type_directory;
extern const OFFileAttributeType OFFileTypeDirectory;

/**
 * @brief A symbolic link.
 */
extern const of_file_type_t of_file_type_symbolic_link;
extern const OFFileAttributeType OFFileTypeSymbolicLink;

/**
 * @brief A FIFO.
 */
extern const of_file_type_t of_file_type_fifo;
extern const OFFileAttributeType OFFileTypeFIFO;

/**
 * @brief A character special file.
 */
extern const of_file_type_t of_file_type_character_special;
extern const OFFileAttributeType OFFileTypeCharacterSpecial;

/**
 * @brief A block special file.
 */
extern const of_file_type_t of_file_type_block_special;
extern const OFFileAttributeType OFFileTypeBlockSpecial;

/**
 * @brief A socket.
 */
extern const of_file_type_t of_file_type_socket;
extern const OFFileAttributeType OFFileTypeSocket;
#ifdef __cplusplus
}
#endif

/**
 * @class OFFileManager OFFileManager.h ObjFW/OFFileManager.h
 *
267
268
269
270
271
272
273
274

275
276

277
278
279
280
281
282
283
284

285
286

287
288
289
290
291
292
293
294
295
296
297

298
299
300
301
302
303
304
305
306
307
308
309
310

311
312
313
314
315
316
317
266
267
268
269
270
271
272

273
274

275
276
277
278
279
280
281
282

283
284

285
286
287
288
289
290
291
292
293
294
295

296
297
298
299
300
301
302
303
304
305
306
307


308
309
310
311
312
313
314
315







-
+

-
+







-
+

-
+










-
+











-
-
+








#ifdef OF_HAVE_FILES
/**
 * @brief Returns the attributes for the item at the specified path.
 *
 * @param path The path to return the attributes for
 * @return A dictionary of attributes for the specified path, with the keys of
 *	   type @ref of_file_attribute_key_t
 *	   type @ref OFFileAttributeKey
 */
- (of_file_attributes_t)attributesOfItemAtPath: (OFString *)path;
- (OFFileAttributes)attributesOfItemAtPath: (OFString *)path;
#endif

/**
 * @brief Returns the attributes for the item at the specified URL.
 *
 * @param URL The URL to return the attributes for
 * @return A dictionary of attributes for the specified URL, with the keys of
 *	   type @ref of_file_attribute_key_t
 *	   type @ref OFFileAttributeKey
 */
- (of_file_attributes_t)attributesOfItemAtURL: (OFURL *)URL;
- (OFFileAttributes)attributesOfItemAtURL: (OFURL *)URL;

#ifdef OF_HAVE_FILES
/**
 * @brief Sets the attributes for the item at the specified path.
 *
 * All attributes not part of the dictionary are left unchanged.
 *
 * @param attributes The attributes to set for the specified path
 * @param path The path of the item to set the attributes for
 */
- (void)setAttributes: (of_file_attributes_t)attributes
- (void)setAttributes: (OFFileAttributes)attributes
	 ofItemAtPath: (OFString *)path;
#endif

/**
 * @brief Sets the attributes for the item at the specified URL.
 *
 * All attributes not part of the dictionary are left unchanged.
 *
 * @param attributes The attributes to set for the specified URL
 * @param URL The URL of the item to set the attributes for
 */
- (void)setAttributes: (of_file_attributes_t)attributes
	  ofItemAtURL: (OFURL *)URL;
- (void)setAttributes: (OFFileAttributes)attributes ofItemAtURL: (OFURL *)URL;

#ifdef OF_HAVE_FILES
/**
 * @brief Checks whether a file exists at the specified path.
 *
 * @param path The path to check
 * @return A boolean whether there is a file at the specified path
562
563
564
565
566
567
568
569

570
571
572
573
574
575
576

577
578
579
580

581
582
583

584
585
586
587
588
589
590
591

592
593
594
595

596
597
598

599
600
601
602

603
604
605

606
607
608
609

610
611
612

613
614
615
616

617
618
619
620

621
622
623
624
625
626
627
628

629
630
631
632
633
634
635
636

637
638
639
640
641
642
643

644
645
646
647
648
649
650

651
652
653
654
655
656
657
658
560
561
562
563
564
565
566

567
568
569
570
571
572
573

574
575
576
577

578
579
580

581

582
583
584
585
586
587

588
589
590
591

592
593
594

595
596
597
598

599
600
601

602
603
604
605

606
607
608

609
610
611
612

613
614
615


616
617
618
619
620
621
622


623
624
625
626
627
628
629


630
631
632
633
634
635
636

637
638
639
640
641
642
643

644

645
646
647
648
649
650
651







-
+






-
+



-
+


-
+
-






-
+



-
+


-
+



-
+


-
+



-
+


-
+



-
+


-
-
+






-
-
+






-
-
+






-
+






-
+
-







 */
- (void)createSymbolicLinkAtURL: (OFURL *)URL
	    withDestinationPath: (OFString *)target;
@end

@interface OFDictionary (FileAttributes)
/**
 * @brief The @ref of_file_attribute_key_size key from the dictionary.
 * @brief The @ref OFFileSize key from the dictionary.
 *
 * Raises an @ref OFUndefinedKeyException if the key is missing.
 */
@property (readonly, nonatomic) unsigned long long fileSize;

/**
 * @brief The @ref of_file_attribute_key_type key from the dictionary.
 * @brief The @ref OFFileType key from the dictionary.
 *
 * Raises an @ref OFUndefinedKeyException if the key is missing.
 */
@property (readonly, nonatomic) of_file_type_t fileType;
@property (readonly, nonatomic) OFFileAttributeType fileType;

/**
 * @brief The @ref of_file_attribute_key_posix_permissions key from the
 * @brief The @ref OFFilePOSIXPermissions key from the dictionary.
 *	  dictionary.
 *
 * Raises an @ref OFUndefinedKeyException if the key is missing.
 */
@property (readonly, nonatomic) unsigned long filePOSIXPermissions;

/**
 * @brief The @ref of_file_attribute_key_posix_uid key from the dictionary.
 * @brief The @ref OFFileOwnerAccountID key from the dictionary.
 *
 * Raises an @ref OFUndefinedKeyException if the key is missing.
 */
@property (readonly, nonatomic) unsigned long filePOSIXUID;
@property (readonly, nonatomic) unsigned long fileOwnerAccountID;

/**
 * @brief The @ref of_file_attribute_key_posix_gid key from the dictionary.
 * @brief The @ref OFFileGroupOwnerAccountID key from the dictionary.
 *
 * Raises an @ref OFUndefinedKeyException if the key is missing.
 */
@property (readonly, nonatomic) unsigned long filePOSIXGID;
@property (readonly, nonatomic) unsigned long fileGroupOwnerAccountID;

/**
 * @brief The @ref of_file_attribute_key_owner key from the dictionary.
 * @brief The @ref OFFileOwnerAccountName key from the dictionary.
 *
 * Raises an @ref OFUndefinedKeyException if the key is missing.
 */
@property (readonly, nonatomic) OFString *fileOwner;
@property (readonly, nonatomic) OFString *fileOwnerAccountName;

/**
 * @brief The @ref of_file_attribute_key_group key from the dictionary.
 * @brief The @ref OFFileGroupOwnerAccountName key from the dictionary.
 *
 * Raises an @ref OFUndefinedKeyException if the key is missing.
 */
@property (readonly, nonatomic) OFString *fileGroup;
@property (readonly, nonatomic) OFString *fileGroupOwnerAccountName;

/**
 * @brief The @ref of_file_attribute_key_last_access_date key from the
 *	  dictionary.
 * @brief The @ref OFFileLastAccessDate key from the dictionary.
 *
 * Raises an @ref OFUndefinedKeyException if the key is missing.
 */
@property (readonly, nonatomic) OFDate *fileLastAccessDate;

/**
 * @brief The @ref of_file_attribute_key_modification_date key from the
 *	  dictionary.
 * @brief The @ref OFFileModificationDate key from the dictionary.
 *
 * Raises an @ref OFUndefinedKeyException if the key is missing.
 */
@property (readonly, nonatomic) OFDate *fileModificationDate;

/**
 * @brief The @ref of_file_attribute_key_status_change_date key from the
 *	  dictionary.
 * @brief The @ref OFFileStatusChangeDate key from the dictionary.
 *
 * Raises an @ref OFUndefinedKeyException if the key is missing.
 */
@property (readonly, nonatomic) OFDate *fileStatusChangeDate;

/**
 * @brief The @ref of_file_attribute_key_creation_date key from the dictionary.
 * @brief The @ref OFFileCreationDate key from the dictionary.
 *
 * Raises an @ref OFUndefinedKeyException if the key is missing.
 */
@property (readonly, nonatomic) OFDate *fileCreationDate;

/**
 * @brief The @ref of_file_attribute_key_symbolic_link_destination key from the
 * @brief The @ref OFFileSymbolicLinkDestination key from the dictionary.
 *	  dictionary.
 *
 * Raises an @ref OFUndefinedKeyException if the key is missing.
 */
@property (readonly, nonatomic) OFString *fileSymbolicLinkDestination;
@end

OF_ASSUME_NONNULL_END

Modified src/OFFileManager.m from [89ccc3daf1] to [abf911c67b].

67
68
69
70
71
72
73
74
75

76
77

78
79

80
81

82
83

84
85
86
87




88
89
90
91



92
93

94
95

96
97

98
99

100
101
102
103
104





105
106


107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126

127
128
129
130
131
132
133
134
67
68
69
70
71
72
73


74


75


76


77


78




79
80
81
82




83
84
85


86


87


88
89

90





91
92
93
94
95


96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116

117

118
119
120
121
122
123
124







-
-
+
-
-
+
-
-
+
-
-
+
-
-
+
-
-
-
-
+
+
+
+
-
-
-
-
+
+
+
-
-
+
-
-
+
-
-
+

-
+
-
-
-
-
-
+
+
+
+
+
-
-
+
+



















-
+
-







# include <proto/exec.h>
# include <proto/dos.h>
#endif

@interface OFDefaultFileManager: OFFileManager
@end

const of_file_attribute_key_t of_file_attribute_key_size =
    @"of_file_attribute_key_size";
const OFFileAttributeKey OFFileSize = @"OFFileSize";
const of_file_attribute_key_t of_file_attribute_key_type =
    @"of_file_attribute_key_type";
const OFFileAttributeKey OFFileType = @"OFFileType";
const of_file_attribute_key_t of_file_attribute_key_posix_permissions =
    @"of_file_attribute_key_posix_permissions";
const OFFileAttributeKey OFFilePOSIXPermissions = @"OFFilePOSIXPermissions";
const of_file_attribute_key_t of_file_attribute_key_posix_uid =
    @"of_file_attribute_key_posix_uid";
const OFFileAttributeKey OFFileOwnerAccountID = @"OFFileOwnerAccountID";
const of_file_attribute_key_t of_file_attribute_key_posix_gid =
    @"of_file_attribute_key_posix_gid";
const OFFileAttributeKey OFFileGroupOwnerAccountID =
const of_file_attribute_key_t of_file_attribute_key_owner =
    @"of_file_attribute_key_owner";
const of_file_attribute_key_t of_file_attribute_key_group =
    @"of_file_attribute_key_group";
    @"OFFileGroupOwnerAccountID";
const OFFileAttributeKey OFFileOwnerAccountName = @"OFFileOwnerAccountName";
const OFFileAttributeKey OFFileGroupOwnerAccountName =
    @"OFFileGroupOwnerAccountName";
const of_file_attribute_key_t of_file_attribute_key_last_access_date =
    @"of_file_attribute_key_last_access_date";
const of_file_attribute_key_t of_file_attribute_key_modification_date =
    @"of_file_attribute_key_modification_date";
const OFFileAttributeKey OFFileLastAccessDate = @"OFFileLastAccessDate";
const OFFileAttributeKey OFFileModificationDate = @"OFFileModificationDate";
const OFFileAttributeKey OFFileStatusChangeDate = @"OFFileStatusChangeDate";
const of_file_attribute_key_t of_file_attribute_key_status_change_date =
    @"of_file_attribute_key_status_change_date";
const OFFileAttributeKey OFFileCreationDate = @"OFFileCreationDate";
const of_file_attribute_key_t of_file_attribute_key_creation_date =
    @"of_file_attribute_key_creation_date";
const OFFileAttributeKey OFFileSymbolicLinkDestination =
const of_file_attribute_key_t of_file_attribute_key_symbolic_link_destination =
    @"of_file_attribute_key_symbolic_link_destination";
    @"OFFileSymbolicLinkDestination";

const of_file_type_t of_file_type_regular = @"of_file_type_regular";
const OFFileAttributeType OFFileTypeRegular = @"OFFileTypeRegular";
const of_file_type_t of_file_type_directory = @"of_file_type_directory";
const of_file_type_t of_file_type_symbolic_link = @"of_file_type_symbolic_link";
const of_file_type_t of_file_type_fifo = @"of_file_type_fifo";
const of_file_type_t of_file_type_character_special =
    @"of_file_type_character_special";
const OFFileAttributeType OFFileTypeDirectory = @"OFFileTypeDirectory";
const OFFileAttributeType OFFileTypeSymbolicLink = @"OFFileTypeSymbolicLink";
const OFFileAttributeType OFFileTypeFIFO = @"OFFileTypeFIFO";
const OFFileAttributeType OFFileTypeCharacterSpecial =
    @"OFFileTypeCharacterSpecial";
const of_file_type_t of_file_type_block_special = @"of_file_type_block_special";
const of_file_type_t of_file_type_socket = @"of_file_type_socket";
const OFFileAttributeType OFFileTypeBlockSpecial = @"OFFileTypeBlockSpecial";
const OFFileAttributeType OFFileTypeSocket = @"OFFileTypeSocket";

#ifdef OF_AMIGAOS4
# define CurrentDir(lock) SetCurrentDir(lock)
#endif

static OFFileManager *defaultManager;

#ifdef OF_AMIGAOS
static bool dirChanged = false;
static BPTR originalDirLock = 0;

OF_DESTRUCTOR()
{
	if (dirChanged)
		UnLock(CurrentDir(originalDirLock));
}
#endif

static id
attributeForKeyOrException(of_file_attributes_t attributes,
attributeForKeyOrException(OFFileAttributes attributes, OFFileAttributeKey key)
    of_file_attribute_key_t key)
{
	id object = [attributes objectForKey: key];

	if (object == nil)
		@throw [OFUndefinedKeyException exceptionWithObject: attributes
								key: key];

227
228
229
230
231
232
233
234

235
236
237
238
239
240
241
242
243
244
245
246
247
248

249
250
251

252
253
254
255
256
257
258
259
260
261
262
263
264

265
266
267
268
269
270
271
272
273
274
275
276
277
278

279
280
281
282
283
284
285
217
218
219
220
221
222
223

224
225
226
227
228
229
230
231
232
233
234
235
236
237

238
239
240

241
242
243
244
245
246
247
248
249
250
251
252


253
254
255
256
257
258
259
260
261
262
263
264
265
266

267
268
269
270
271
272
273
274







-
+













-
+


-
+











-
-
+













-
+








	[ret retain];
	objc_autoreleasePoolPop(pool);
	return [ret autorelease];
}
#endif

- (of_file_attributes_t)attributesOfItemAtURL: (OFURL *)URL
- (OFFileAttributes)attributesOfItemAtURL: (OFURL *)URL
{
	OFURLHandler *URLHandler;

	if (URL == nil)
		@throw [OFInvalidArgumentException exception];

	if ((URLHandler = [OFURLHandler handlerForURL: URL]) == nil)
		@throw [OFUnsupportedProtocolException exceptionWithURL: URL];

	return [URLHandler attributesOfItemAtURL: URL];
}

#ifdef OF_HAVE_FILES
- (of_file_attributes_t)attributesOfItemAtPath: (OFString *)path
- (OFFileAttributes)attributesOfItemAtPath: (OFString *)path
{
	void *pool = objc_autoreleasePoolPush();
	of_file_attributes_t ret;
	OFFileAttributes ret;

	ret = [self attributesOfItemAtURL: [OFURL fileURLWithPath: path]];

	[ret retain];

	objc_autoreleasePoolPop(pool);

	return [ret autorelease];
}
#endif

- (void)setAttributes: (of_file_attributes_t)attributes
	  ofItemAtURL: (OFURL *)URL
- (void)setAttributes: (OFFileAttributes)attributes ofItemAtURL: (OFURL *)URL
{
	OFURLHandler *URLHandler;

	if (URL == nil)
		@throw [OFInvalidArgumentException exception];

	if ((URLHandler = [OFURLHandler handlerForURL: URL]) == nil)
		@throw [OFUnsupportedProtocolException exceptionWithURL: URL];

	[URLHandler setAttributes: attributes ofItemAtURL: URL];
}

#ifdef OF_HAVE_FILES
- (void)setAttributes: (of_file_attributes_t)attributes
- (void)setAttributes: (OFFileAttributes)attributes
	 ofItemAtPath: (OFString *)path
{
	void *pool = objc_autoreleasePoolPush();
	[self setAttributes: attributes
		ofItemAtURL: [OFURL fileURLWithPath: path]];
	objc_autoreleasePoolPop(pool);
}
565
566
567
568
569
570
571
572
573


574
575
576
577
578
579
580
554
555
556
557
558
559
560


561
562
563
564
565
566
567
568
569







-
-
+
+







}
#endif

- (void)copyItemAtURL: (OFURL *)source toURL: (OFURL *)destination
{
	void *pool;
	OFURLHandler *URLHandler;
	of_file_attributes_t attributes;
	of_file_type_t type;
	OFFileAttributes attributes;
	OFFileAttributeType type;

	if (source == nil || destination == nil)
		@throw [OFInvalidArgumentException exception];

	pool = objc_autoreleasePoolPush();

	if ((URLHandler = [OFURLHandler handlerForURL: source]) == nil)
597
598
599
600
601
602
603
604

605
606
607
608
609
610
611

612
613
614
615

616
617
618
619
620
621
622
586
587
588
589
590
591
592

593
594
595
596
597
598
599

600

601
602

603
604
605
606
607
608
609
610







-
+






-
+
-


-
+







		    exceptionWithSourceURL: source
			    destinationURL: destination
				     errNo: e.errNo];
	}

	type = attributes.fileType;

	if ([type isEqual: of_file_type_directory]) {
	if ([type isEqual: OFFileTypeDirectory]) {
		OFArray OF_GENERIC(OFURL *) *contents;

		@try {
			[self createDirectoryAtURL: destination];

			@try {
				of_file_attribute_key_t key =
				OFFileAttributeKey key = OFFilePOSIXPermissions;
				    of_file_attribute_key_posix_permissions;
				OFNumber *permissions =
				    [attributes objectForKey: key];
				of_file_attributes_t destinationAttributes;
				OFFileAttributes destinationAttributes;

				if (permissions != nil) {
					destinationAttributes = [OFDictionary
					    dictionaryWithObject: permissions
							  forKey: key];
					[self
					    setAttributes: destinationAttributes
648
649
650
651
652
653
654
655

656
657
658
659
660
661
662
636
637
638
639
640
641
642

643
644
645
646
647
648
649
650







-
+







			    URLByAppendingPathComponent:
			    item.lastPathComponent];

			[self copyItemAtURL: item toURL: destinationURL];

			objc_autoreleasePoolPop(pool2);
		}
	} else if ([type isEqual: of_file_type_regular]) {
	} else if ([type isEqual: OFFileTypeRegular]) {
		size_t pageSize = [OFSystemInfo pageSize];
		OFStream *sourceStream = nil;
		OFStream *destinationStream = nil;
		char *buffer;

		buffer = of_alloc(1, pageSize);
		@try {
674
675
676
677
678
679
680
681

682
683
684
685

686
687
688
689
690
691
692
662
663
664
665
666
667
668

669

670
671

672
673
674
675
676
677
678
679







-
+
-


-
+







				    readIntoBuffer: buffer
					    length: pageSize];
				[destinationStream writeBuffer: buffer
							length: length];
			}

			@try {
				of_file_attribute_key_t key =
				OFFileAttributeKey key = OFFilePOSIXPermissions;
				    of_file_attribute_key_posix_permissions;
				OFNumber *permissions = [attributes
				    objectForKey: key];
				of_file_attributes_t destinationAttributes;
				OFFileAttributes destinationAttributes;

				if (permissions != nil) {
					destinationAttributes = [OFDictionary
					    dictionaryWithObject: permissions
							  forKey: key];
					[self
					    setAttributes: destinationAttributes
709
710
711
712
713
714
715
716

717
718
719
720
721
722
723
696
697
698
699
700
701
702

703
704
705
706
707
708
709
710







-
+








			@throw e;
		} @finally {
			[sourceStream close];
			[destinationStream close];
			free(buffer);
		}
	} else if ([type isEqual: of_file_type_symbolic_link]) {
	} else if ([type isEqual: OFFileTypeSymbolicLink]) {
		@try {
			OFString *linkDestination =
			    attributes.fileSymbolicLinkDestination;

			[self createSymbolicLinkAtURL: destination
				  withDestinationPath: linkDestination];
		} @catch (id e) {
910
911
912
913
914
915
916
917

918
919
920
921

922
923

924
925
926
927
928
929

930
931
932

933
934
935

936
937
938

939
940
941

942
943
944

945
946

947
948
949

950
951

952
953
954
955
956

957
958
959
960
961
962

963
964
965
966
967
968

969
970
971
972
973
974

975
976
977
978
979
980

981
982
983
897
898
899
900
901
902
903

904
905
906
907

908
909

910
911
912
913
914
915

916
917
918

919
920
921

922
923
924

925
926
927

928
929
930

931
932

933
934
935

936
937

938
939
940
941
942

943

944
945
946
947

948

949
950
951
952

953

954
955
956
957

958

959
960
961
962

963

964
965







-
+



-
+

-
+





-
+


-
+


-
+


-
+


-
+


-
+

-
+


-
+

-
+




-
+
-




-
+
-




-
+
-




-
+
-




-
+
-


	return OF_RETAIN_COUNT_MAX;
}
@end

@implementation OFDictionary (FileAttributes)
- (unsigned long long)fileSize
{
	return [attributeForKeyOrException(self, of_file_attribute_key_size)
	return [attributeForKeyOrException(self, OFFileSize)
	    unsignedLongLongValue];
}

- (of_file_type_t)fileType
- (OFFileAttributeType)fileType
{
	return attributeForKeyOrException(self, of_file_attribute_key_type);
	return attributeForKeyOrException(self, OFFileType);
}

- (unsigned long)filePOSIXPermissions
{
	return [attributeForKeyOrException(self,
	    of_file_attribute_key_posix_permissions) unsignedLongValue];
	    OFFilePOSIXPermissions) unsignedLongValue];
}

- (unsigned long)filePOSIXUID
- (unsigned long)fileOwnerAccountID
{
	return [attributeForKeyOrException(self,
	    of_file_attribute_key_posix_uid) unsignedLongValue];
	    OFFileOwnerAccountID) unsignedLongValue];
}

- (unsigned long)filePOSIXGID
- (unsigned long)fileGroupOwnerAccountID
{
	return [attributeForKeyOrException(self,
	    of_file_attribute_key_posix_gid) unsignedLongValue];
	    OFFileGroupOwnerAccountID) unsignedLongValue];
}

- (OFString *)fileOwner
- (OFString *)fileOwnerAccountName
{
	return attributeForKeyOrException(self, of_file_attribute_key_owner);
	return attributeForKeyOrException(self, OFFileOwnerAccountName);
}

- (OFString *)fileGroup
- (OFString *)fileGroupOwnerAccountName
{
	return attributeForKeyOrException(self, of_file_attribute_key_group);
	return attributeForKeyOrException(self, OFFileGroupOwnerAccountName);
}

- (OFDate *)fileLastAccessDate
{
	return attributeForKeyOrException(self,
	return attributeForKeyOrException(self, OFFileLastAccessDate);
	    of_file_attribute_key_last_access_date);
}

- (OFDate *)fileModificationDate
{
	return attributeForKeyOrException(self,
	return attributeForKeyOrException(self, OFFileModificationDate);
	    of_file_attribute_key_modification_date);
}

- (OFDate *)fileStatusChangeDate
{
	return attributeForKeyOrException(self,
	return attributeForKeyOrException(self, OFFileStatusChangeDate);
	    of_file_attribute_key_status_change_date);
}

- (OFDate *)fileCreationDate
{
	return attributeForKeyOrException(self,
	return attributeForKeyOrException(self, OFFileCreationDate);
	    of_file_attribute_key_creation_date);
}

- (OFString *)fileSymbolicLinkDestination
{
	return attributeForKeyOrException(self,
	return attributeForKeyOrException(self, OFFileSymbolicLinkDestination);
	    of_file_attribute_key_symbolic_link_destination);
}
@end

Modified src/OFFileURLHandler.m from [48c2c95cb9] to [46f9d28643].

355
356
357
358
359
360
361
362

363
364
365

366
367
368

369
370
371
372
373


374
375
376
377

378
379
380
381
382
383


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
440
441

442
443
444
445
446
447
448
449
450

451
452
453
454
455
456
457
458
459
460
461
462

463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486


487
488
489
490
491
492
493
355
356
357
358
359
360
361

362
363
364

365

366

367

368
369


370
371
372
373
374

375

376
377
378


379
380
381
382
383


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
440
441
442
443
444

445
446
447
448
449
450
451
452
453
454
455
456

457
458
459
460
461
462
463
464
465

466
467
468
469
470
471
472
473
474
475
476
477
478


479
480
481
482
483
484
485
486
487







-
+


-
+
-

-
+
-


-
-
+
+



-
+
-



-
-
+
+



-
-
+
+



-
+
-




-
+




-
+


-
+


-
+



-
+




-
+
-



-
+

-
+















-
+








-
+











-
+








-













-
-
+
+







	return 0;
#else
	return of_stat(path, buffer);
#endif
}

static void
setTypeAttribute(of_mutable_file_attributes_t attributes, of_stat_t *s)
setTypeAttribute(OFMutableFileAttributes attributes, of_stat_t *s)
{
	if (S_ISREG(s->st_mode))
		[attributes setObject: of_file_type_regular
		[attributes setObject: OFFileTypeRegular forKey: OFFileType];
			       forKey: of_file_attribute_key_type];
	else if (S_ISDIR(s->st_mode))
		[attributes setObject: of_file_type_directory
		[attributes setObject: OFFileTypeDirectory forKey: OFFileType];
			       forKey: of_file_attribute_key_type];
#ifdef S_ISLNK
	else if (S_ISLNK(s->st_mode))
		[attributes setObject: of_file_type_symbolic_link
			       forKey: of_file_attribute_key_type];
		[attributes setObject: OFFileTypeSymbolicLink
			       forKey: OFFileType];
#endif
#ifdef S_ISFIFO
	else if (S_ISFIFO(s->st_mode))
		[attributes setObject: of_file_type_fifo
		[attributes setObject: OFFileTypeFIFO forKey: OFFileType];
			       forKey: of_file_attribute_key_type];
#endif
#ifdef S_ISCHR
	else if (S_ISCHR(s->st_mode))
		[attributes setObject: of_file_type_character_special
			       forKey: of_file_attribute_key_type];
		[attributes setObject: OFFileTypeCharacterSpecial
			       forKey: OFFileType];
#endif
#ifdef S_ISBLK
	else if (S_ISBLK(s->st_mode))
		[attributes setObject: of_file_type_block_special
			       forKey: of_file_attribute_key_type];
		[attributes setObject: OFFileTypeBlockSpecial
			       forKey: OFFileType];
#endif
#ifdef S_ISSOCK
	else if (S_ISSOCK(s->st_mode))
		[attributes setObject: of_file_type_socket
		[attributes setObject: OFFileTypeSocket forKey: OFFileType];
			       forKey: of_file_attribute_key_type];
#endif
}

static void
setDateAttributes(of_mutable_file_attributes_t attributes, of_stat_t *s)
setDateAttributes(OFMutableFileAttributes attributes, of_stat_t *s)
{
	/* FIXME: We could be more precise on some OSes */
	[attributes
	    setObject: [OFDate dateWithTimeIntervalSince1970: s->st_atime]
	       forKey: of_file_attribute_key_last_access_date];
	       forKey: OFFileLastAccessDate];
	[attributes
	    setObject: [OFDate dateWithTimeIntervalSince1970: s->st_mtime]
	       forKey: of_file_attribute_key_modification_date];
	       forKey: OFFileModificationDate];
	[attributes
	    setObject: [OFDate dateWithTimeIntervalSince1970: s->st_ctime]
	       forKey: of_file_attribute_key_status_change_date];
	       forKey: OFFileStatusChangeDate];
#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
	[attributes
	    setObject: [OFDate dateWithTimeIntervalSince1970: s->st_birthtime]
	       forKey: of_file_attribute_key_creation_date];
	       forKey: OFFileCreationDate];
#endif
}

static void
setOwnerAndGroupAttributes(of_mutable_file_attributes_t attributes,
setOwnerAndGroupAttributes(OFMutableFileAttributes attributes, of_stat_t *s)
    of_stat_t *s)
{
#ifdef OF_FILE_MANAGER_SUPPORTS_OWNER
	[attributes setObject: [NSNumber numberWithUnsignedLong: s->st_uid]
		       forKey: of_file_attribute_key_posix_uid];
		       forKey: OFFileOwnerAccountID];
	[attributes setObject: [NSNumber numberWithUnsignedLong: s->st_gid]
		       forKey: of_file_attribute_key_posix_gid];
		       forKey: OFFileGroupOwnerAccountID];

# ifdef OF_HAVE_THREADS
	[passwdMutex lock];
	@try {
# endif
		OFStringEncoding encoding = [OFLocale encoding];
		struct passwd *passwd = getpwuid(s->st_uid);
		struct group *group_ = getgrgid(s->st_gid);

		if (passwd != NULL) {
			OFString *owner = [OFString
			    stringWithCString: passwd->pw_name
				     encoding: encoding];

			[attributes setObject: owner
				       forKey: of_file_attribute_key_owner];
				       forKey: OFFileOwnerAccountName];
		}

		if (group_ != NULL) {
			OFString *group = [OFString
			    stringWithCString: group_->gr_name
				     encoding: encoding];

			[attributes setObject: group
				       forKey: of_file_attribute_key_group];
				       forKey: OFFileGroupOwnerAccountName];
		}
# ifdef OF_HAVE_THREADS
	} @finally {
		[passwdMutex unlock];
	}
# endif
#endif
}

#ifdef OF_FILE_MANAGER_SUPPORTS_SYMLINKS
static void
setSymbolicLinkDestinationAttribute(of_mutable_file_attributes_t attributes,
setSymbolicLinkDestinationAttribute(OFMutableFileAttributes attributes,
    OFURL *URL)
{
	OFString *path = URL.fileSystemRepresentation;
# ifndef OF_WINDOWS
	OFStringEncoding encoding = [OFLocale encoding];
	char destinationC[PATH_MAX];
	ssize_t length;
	OFString *destination;
	of_file_attribute_key_t key;

	length = readlink([path cStringWithEncoding: encoding], destinationC,
	    PATH_MAX);

	if (length < 0)
		@throw [OFRetrieveItemAttributesFailedException
		    exceptionWithURL: URL
			       errNo: errno];

	destination = [OFString stringWithCString: destinationC
					 encoding: encoding
					   length: length];

	key = of_file_attribute_key_symbolic_link_destination;
	[attributes setObject: destination forKey: key];
	[attributes setObject: destination
		       forKey: OFFileSymbolicLinkDestination];
# else
	HANDLE handle;
	OFString *destination;

	if (func_CreateSymbolicLinkW == NULL)
		return;

501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
495
496
497
498
499
500
501

502
503
504
505
506
507
508







-







	@try {
		union {
			char bytes[MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
			REPARSE_DATA_BUFFER data;
		} buffer;
		DWORD size;
		wchar_t *tmp;
		of_file_attribute_key_t key;

		if (!DeviceIoControl(handle, FSCTL_GET_REPARSE_POINT, NULL, 0,
		    buffer.bytes, MAXIMUM_REPARSE_DATA_BUFFER_SIZE, &size,
		    NULL))
			@throw [OFRetrieveItemAttributesFailedException
			    exceptionWithURL: URL
				       errNo: retrieveError()];
524
525
526
527
528
529
530
531
532


533
534


535
536
537
538
539
540
541
517
518
519
520
521
522
523


524
525


526
527
528
529
530
531
532
533
534







-
-
+
+
-
-
+
+







		    (slrb.SubstituteNameOffset / sizeof(wchar_t));

		destination = [OFString
		    stringWithUTF16String: tmp
				   length: slrb.SubstituteNameLength /
					   sizeof(wchar_t)];

		[attributes setObject: of_file_type_symbolic_link
			       forKey: of_file_attribute_key_type];
		[attributes setObject: OFFileTypeSymbolicLink
			       forKey: OFFileType];
		key = of_file_attribute_key_symbolic_link_destination;
		[attributes setObject: destination forKey: key];
		[attributes setObject: destination
			       forKey: OFFileSymbolicLinkDestination];
#  undef slrb
	} @finally {
		CloseHandle(handle);
	}
# endif
}
#endif
600
601
602
603
604
605
606
607

608
609

610
611
612
613
614
615
616
593
594
595
596
597
598
599

600
601

602
603
604
605
606
607
608
609







-
+

-
+







		    mode: mode];

	objc_autoreleasePoolPop(pool);

	return [file autorelease];
}

- (of_file_attributes_t)attributesOfItemAtURL: (OFURL *)URL
- (OFFileAttributes)attributesOfItemAtURL: (OFURL *)URL
{
	of_mutable_file_attributes_t ret = [OFMutableDictionary dictionary];
	OFMutableFileAttributes ret = [OFMutableDictionary dictionary];
	void *pool = objc_autoreleasePoolPush();
	OFString *path;
	int error;
	of_stat_t s;

	if (URL == nil)
		@throw [OFInvalidArgumentException exception];
625
626
627
628
629
630
631
632

633
634
635
636
637

638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655

656
657
658
659


660
661
662
663
664
665
666
667
618
619
620
621
622
623
624

625
626
627
628
629

630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647

648
649
650


651
652

653
654
655
656
657
658
659







-
+




-
+

















-
+


-
-
+
+
-







		    exceptionWithURL: URL
			       errNo: error];

	if (s.st_size < 0)
		@throw [OFOutOfRangeException exception];

	[ret setObject: [NSNumber numberWithUnsignedLongLong: s.st_size]
		forKey: of_file_attribute_key_size];
		forKey: OFFileSize];

	setTypeAttribute(ret, &s);

	[ret setObject: [NSNumber numberWithUnsignedLong: s.st_mode]
		forKey: of_file_attribute_key_posix_permissions];
		forKey: OFFilePOSIXPermissions];

	setOwnerAndGroupAttributes(ret, &s);
	setDateAttributes(ret, &s);

#ifdef OF_FILE_MANAGER_SUPPORTS_SYMLINKS
	if (S_ISLNK(s.st_mode))
		setSymbolicLinkDestinationAttribute(ret, URL);
#endif

	objc_autoreleasePoolPop(pool);

	return ret;
}

- (void)of_setLastAccessDate: (OFDate *)lastAccessDate
	 andModificationDate: (OFDate *)modificationDate
		 ofItemAtURL: (OFURL *)URL
		  attributes: (of_file_attributes_t)attributes OF_DIRECT
		  attributes: (OFFileAttributes)attributes OF_DIRECT
{
	OFString *path = URL.fileSystemRepresentation;
	of_file_attribute_key_t attributeKey = (modificationDate != nil
	    ? of_file_attribute_key_modification_date
	OFFileAttributeKey attributeKey = (modificationDate != nil
	    ? OFFileModificationDate : OFFileLastAccessDate);
	    : of_file_attribute_key_last_access_date);

	if (lastAccessDate == nil)
		lastAccessDate = modificationDate;
	if (modificationDate == nil)
		modificationDate = lastAccessDate;

#if defined(OF_WINDOWS)
762
763
764
765
766
767
768
769

770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788

789
790
791
792
793
794
795
796
797
798
799





800
801
802
803
804
805
806
754
755
756
757
758
759
760

761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779

780
781
782
783
784
785
786





787
788
789
790
791
792
793
794
795
796
797
798







-
+


















-
+






-
-
-
-
-
+
+
+
+
+







		     failedAttribute: attributeKey
			       errNo: errno];
#endif
}

- (void)of_setPOSIXPermissions: (OFNumber *)permissions
		   ofItemAtURL: (OFURL *)URL
		    attributes: (of_file_attributes_t)attributes OF_DIRECT
		    attributes: (OFFileAttributes)attributes OF_DIRECT
{
#ifdef OF_FILE_MANAGER_SUPPORTS_PERMISSIONS
	mode_t mode = (mode_t)permissions.unsignedLongValue;
	OFString *path = URL.fileSystemRepresentation;
	int status;

# ifdef OF_WINDOWS
	if ([OFSystemInfo isWindowsNT])
		status = _wchmod(path.UTF16String, mode);
	else
# endif
		status = chmod(
		    [path cStringWithEncoding: [OFLocale encoding]], mode);

	if (status != 0)
		@throw [OFSetItemAttributesFailedException
		    exceptionWithURL: URL
			  attributes: attributes
		     failedAttribute: of_file_attribute_key_posix_permissions
		     failedAttribute: OFFilePOSIXPermissions
			       errNo: errno];
#else
	OF_UNRECOGNIZED_SELECTOR
#endif
}

- (void)of_setOwner: (OFString *)owner
	   andGroup: (OFString *)group
	ofItemAtURL: (OFURL *)URL
       attributeKey: (of_file_attribute_key_t)attributeKey
	 attributes: (of_file_attributes_t)attributes OF_DIRECT
- (void)of_setOwnerAccountName: (OFString *)owner
      andGroupOwnerAccountName: (OFString *)group
		   ofItemAtURL: (OFURL *)URL
		  attributeKey: (OFFileAttributeKey)attributeKey
		    attributes: (OFFileAttributes)attributes OF_DIRECT
{
#ifdef OF_FILE_MANAGER_SUPPORTS_OWNER
	OFString *path = URL.fileSystemRepresentation;
	uid_t uid = -1;
	gid_t gid = -1;
	OFStringEncoding encoding;

853
854
855
856
857
858
859
860
861

862
863
864

865
866

867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882


883
884

885
886
887
888
889
890
891
892
893
894
895
896
897
898
899












900
901
902
903
904
905
906

907
908

909
910
911
912
913
914
915
916
845
846
847
848
849
850
851


852
853
854

855
856

857
858
859
860
861
862
863
864
865
866
867
868
869
870
871


872
873
874

875
876
877
878












879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896

897


898

899
900
901
902
903
904
905







-
-
+


-
+

-
+














-
-
+
+

-
+



-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+






-
+
-
-
+
-







		     failedAttribute: attributeKey
			       errNo: errno];
#else
	OF_UNRECOGNIZED_SELECTOR
#endif
}

- (void)setAttributes: (of_file_attributes_t)attributes
	  ofItemAtURL: (OFURL *)URL
- (void)setAttributes: (OFFileAttributes)attributes ofItemAtURL: (OFURL *)URL
{
	void *pool = objc_autoreleasePoolPush();
	OFEnumerator OF_GENERIC(of_file_attribute_key_t) *keyEnumerator;
	OFEnumerator OF_GENERIC(OFFileAttributeKey) *keyEnumerator;
	OFEnumerator *objectEnumerator;
	of_file_attribute_key_t key;
	OFFileAttributeKey key;
	id object;
	OFDate *lastAccessDate, *modificationDate;

	if (URL == nil)
		@throw [OFInvalidArgumentException exception];

	if (![URL.scheme isEqual: _scheme])
		@throw [OFInvalidArgumentException exception];

	keyEnumerator = [attributes keyEnumerator];
	objectEnumerator = [attributes objectEnumerator];

	while ((key = [keyEnumerator nextObject]) != nil &&
	    (object = [objectEnumerator nextObject]) != nil) {
		if ([key isEqual: of_file_attribute_key_modification_date] ||
		    [key isEqual: of_file_attribute_key_last_access_date])
		if ([key isEqual: OFFileModificationDate] ||
		    [key isEqual: OFFileLastAccessDate])
			continue;
		else if ([key isEqual: of_file_attribute_key_posix_permissions])
		else if ([key isEqual: OFFilePOSIXPermissions])
			[self of_setPOSIXPermissions: object
					 ofItemAtURL: URL
					  attributes: attributes];
		else if ([key isEqual: of_file_attribute_key_owner])
			[self of_setOwner: object
				 andGroup: nil
			      ofItemAtURL: URL
			     attributeKey: key
			       attributes: attributes];
		else if ([key isEqual: of_file_attribute_key_group])
			[self of_setOwner: nil
				 andGroup: object
			      ofItemAtURL: URL
			     attributeKey: key
			       attributes: attributes];
		else if ([key isEqual: OFFileOwnerAccountName])
			[self of_setOwnerAccountName: object
			    andGroupOwnerAccountName: nil
					 ofItemAtURL: URL
					attributeKey: key
					  attributes: attributes];
		else if ([key isEqual: OFFileGroupOwnerAccountName])
			[self of_setOwnerAccountName: nil
			    andGroupOwnerAccountName: object
					 ofItemAtURL: URL
					attributeKey: key
					  attributes: attributes];
		else
			@throw [OFNotImplementedException
			    exceptionWithSelector: _cmd
					   object: self];
	}

	lastAccessDate = [attributes
	lastAccessDate = [attributes objectForKey: OFFileLastAccessDate];
	    objectForKey: of_file_attribute_key_last_access_date];
	modificationDate = [attributes
	modificationDate = [attributes objectForKey: OFFileModificationDate];
	    objectForKey: of_file_attribute_key_modification_date];

	if (lastAccessDate != nil || modificationDate != nil)
		[self of_setLastAccessDate: lastAccessDate
		       andModificationDate: modificationDate
			       ofItemAtURL: URL
				attributes: attributes];

Modified src/OFURLHandler.h from [9ec6927971] to [aebd1b72ac].

94
95
96
97
98
99
100
101

102
103

104
105
106
107
108
109
110
111
112
113
114

115
116
117
118
119
120
121
94
95
96
97
98
99
100

101
102

103
104
105
106
107
108
109
110
111
112


113
114
115
116
117
118
119
120







-
+

-
+









-
-
+







- (OFStream *)openItemAtURL: (OFURL *)URL mode: (OFString *)mode;

/**
 * @brief Returns the attributes for the item at the specified URL.
 *
 * @param URL The URL to return the attributes for
 * @return A dictionary of attributes for the specified URL, with the keys of
 *	   type @ref of_file_attribute_key_t
 *	   type @ref OFFileAttributeKey
 */
- (of_file_attributes_t)attributesOfItemAtURL: (OFURL *)URL;
- (OFFileAttributes)attributesOfItemAtURL: (OFURL *)URL;

/**
 * @brief Sets the attributes for the item at the specified URL.
 *
 * All attributes not part of the dictionary are left unchanged.
 *
 * @param attributes The attributes to set for the specified URL
 * @param URL The URL of the item to set the attributes for
 */
- (void)setAttributes: (of_file_attributes_t)attributes
	  ofItemAtURL: (OFURL *)URL;
- (void)setAttributes: (OFFileAttributes)attributes ofItemAtURL: (OFURL *)URL;

/**
 * @brief Checks whether a file exists at the specified URL.
 *
 * @param URL The URL to check
 * @return A boolean whether there is a file at the specified URL
 */

Modified src/OFURLHandler.m from [7996e25454] to [d88aa91e77].

136
137
138
139
140
141
142
143

144
145
146
147
148
149

150
151
152
153
154
155
156
136
137
138
139
140
141
142

143
144
145
146
147


148
149
150
151
152
153
154
155







-
+




-
-
+







}

- (OFStream *)openItemAtURL: (OFURL *)URL mode: (OFString *)mode
{
	OF_UNRECOGNIZED_SELECTOR
}

- (of_file_attributes_t)attributesOfItemAtURL: (OFURL *)URL
- (OFFileAttributes)attributesOfItemAtURL: (OFURL *)URL
{
	OF_UNRECOGNIZED_SELECTOR
}

- (void)setAttributes: (of_file_attributes_t)attributes
	  ofItemAtURL: (OFURL *)URL
- (void)setAttributes: (OFFileAttributes)attributes ofItemAtURL: (OFURL *)URL
{
	OF_UNRECOGNIZED_SELECTOR
}

- (bool)fileExistsAtURL: (OFURL *)URL
{
	OF_UNRECOGNIZED_SELECTOR

Modified src/exceptions/OFSetItemAttributesFailedException.h from [d9ce8daea6] to [82396088b1].

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
61
62
63
64
65
66
67
68
69
70
71
72


73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89


90
91
92
93
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
61
62
63
64
65
66
67
68
69
70


71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87


88
89
90
91
92
93







-
-
+
+
















-
+




-
+














-
-
+
+















-
-
+
+




 *	  ObjFW/OFSetItemAttributesFailedException.h
 *
 * @brief An exception indicating an item's attributes could not be set.
 */
@interface OFSetItemAttributesFailedException: OFException
{
	OFURL *_URL;
	of_file_attributes_t _attributes;
	of_file_attribute_key_t _failedAttribute;
	OFFileAttributes _attributes;
	OFFileAttributeKey _failedAttribute;
	int _errNo;
}

/**
 * @brief The URL of the item whose attributes could not be set.
 */
@property (readonly, nonatomic) OFURL *URL;

/**
 * @brief The errno of the error that occurred.
 */
@property (readonly, nonatomic) int errNo;

/**
 * @brief The attributes that should have been set.
 */
@property (readonly, nonatomic) of_file_attributes_t attributes;
@property (readonly, nonatomic) OFFileAttributes attributes;

/**
 * @brief The first attribute that could not be set.
 */
@property (readonly, nonatomic) of_file_attribute_key_t failedAttribute;
@property (readonly, nonatomic) OFFileAttributeKey failedAttribute;

+ (instancetype)exception OF_UNAVAILABLE;

/**
 * @brief Creates a new, autoreleased set item attributes failed exception.
 *
 * @param URL The URL of the item whose attributes could not be set
 * @param attributes The attributes that should have been set for the specified
 *		     item.
 * @param failedAttribute The first attribute that could not be set
 * @param errNo The errno of the error that occurred
 * @return A new, autoreleased set item attributes failed exception
 */
+ (instancetype)exceptionWithURL: (OFURL *)URL
		      attributes: (of_file_attributes_t)attributes
		 failedAttribute: (of_file_attribute_key_t)failedAttribute
		      attributes: (OFFileAttributes)attributes
		 failedAttribute: (OFFileAttributeKey)failedAttribute
			   errNo: (int)errNo;

- (instancetype)init OF_UNAVAILABLE;

/**
 * @brief Initializes an already allocated set item attributes failed exception.
 *
 * @param URL The URL of the item whose attributes could not be set
 * @param attributes The attributes that should have been set for the specified
 *		     item.
 * @param failedAttribute The first attribute that could not be set
 * @param errNo The errno of the error that occurred
 * @return An initialized set item attributes failed exception
 */
- (instancetype)initWithURL: (OFURL *)URL
		 attributes: (of_file_attributes_t)attributes
	    failedAttribute: (of_file_attribute_key_t)failedAttribute
		 attributes: (OFFileAttributes)attributes
	    failedAttribute: (OFFileAttributeKey)failedAttribute
		      errNo: (int)errNo OF_DESIGNATED_INITIALIZER;
@end

OF_ASSUME_NONNULL_END

Modified src/exceptions/OFSetItemAttributesFailedException.m from [86a87692ad] to [868fc58c92].

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
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







-
-
+
+














-
-
+
+








+ (instancetype)exception
{
	OF_UNRECOGNIZED_SELECTOR
}

+ (instancetype)exceptionWithURL: (OFURL *)URL
		      attributes: (of_file_attributes_t)attributes
		 failedAttribute: (of_file_attribute_key_t)failedAttribute
		      attributes: (OFFileAttributes)attributes
		 failedAttribute: (OFFileAttributeKey)failedAttribute
			   errNo: (int)errNo
{
	return [[[self alloc] initWithURL: URL
			       attributes: attributes
			  failedAttribute: failedAttribute
				    errNo: errNo] autorelease];
}

- (instancetype)init
{
	OF_INVALID_INIT_METHOD
}

- (instancetype)initWithURL: (OFURL *)URL
		 attributes: (of_file_attributes_t)attributes
	    failedAttribute: (of_file_attribute_key_t)failedAttribute
		 attributes: (OFFileAttributes)attributes
	    failedAttribute: (OFFileAttributeKey)failedAttribute
		      errNo: (int)errNo
{
	self = [super init];

	@try {
		_URL = [URL copy];
		_attributes = [attributes copy];

Modified utils/ofarc/GZIPArchive.m from [22fc2ffb1f] to [cd709fb905].

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
61
62
63
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
61
62
63







-
-
-
-
+
+
+
+












-
+






-
+







static OFArc *app;

static void
setPermissions(OFString *destination, OFString *source)
{
#ifdef OF_FILE_MANAGER_SUPPORTS_PERMISSIONS
	OFFileManager *fileManager = [OFFileManager defaultManager];
	of_file_attributes_t attributes =
	    [fileManager attributesOfItemAtPath: source];
	of_file_attribute_key_t key = of_file_attribute_key_posix_permissions;
	of_file_attributes_t destinationAttributes = [OFDictionary
	OFFileAttributes attributes = [fileManager
	    attributesOfItemAtPath: source];
	OFFileAttributeKey key = OFFilePOSIXPermissions;
	OFFileAttributes destinationAttributes = [OFDictionary
	    dictionaryWithObject: [attributes objectForKey: key]
			  forKey: key];

	[fileManager setAttributes: destinationAttributes
		      ofItemAtPath: destination];
#endif
}

static void
setModificationDate(OFString *path, OFGZIPStream *stream)
{
	OFDate *modificationDate = stream.modificationDate;
	of_file_attributes_t attributes;
	OFFileAttributes attributes;

	if (modificationDate == nil)
		return;

	attributes = [OFDictionary
	    dictionaryWithObject: modificationDate
			  forKey: of_file_attribute_key_modification_date];
			  forKey: OFFileModificationDate];
	[[OFFileManager defaultManager] setAttributes: attributes
					 ofItemAtPath: path];
}

@implementation GZIPArchive
+ (void)initialize
{

Modified utils/ofarc/LHAArchive.m from [ea0271aad2] to [228be0ebf1].

44
45
46
47
48
49
50
51

52
53

54
55
56
57
58
59
60
61
62
63
64

65
66
67
68
69
70
71
72
73
74
75
76
77
78
79

80
81
82
83
84
85
86
44
45
46
47
48
49
50

51
52

53
54
55
56
57
58
59
60
61
62
63

64
65
66
67
68
69
70
71
72
73
74
75
76
77
78

79
80
81
82
83
84
85
86







-
+

-
+










-
+














-
+








	if (mode == nil)
		return;

	mode = [OFNumber numberWithUnsignedShort:
	    mode.unsignedShortValue & 0777];

	of_file_attributes_t attributes = [OFDictionary
	OFFileAttributes attributes = [OFDictionary
	    dictionaryWithObject: mode
			  forKey: of_file_attribute_key_posix_permissions];
			  forKey: OFFilePOSIXPermissions];

	[[OFFileManager defaultManager] setAttributes: attributes
					 ofItemAtPath: path];
#endif
}

static void
setModificationDate(OFString *path, OFLHAArchiveEntry *entry)
{
	OFDate *modificationDate = entry.modificationDate;
	of_file_attributes_t attributes;
	OFFileAttributes attributes;

	if (modificationDate == nil) {
		/*
		 * Fall back to the original date if we have no modification
		 * date, as the modification date is a UNIX extension.
		 */
		modificationDate = entry.date;

		if (modificationDate == nil)
			return;
	}

	attributes = [OFDictionary
	    dictionaryWithObject: modificationDate
			  forKey: of_file_attribute_key_modification_date];
			  forKey: OFFileModificationDate];
	[[OFFileManager defaultManager] setAttributes: attributes
					 ofItemAtPath: path];
}

@implementation LHAArchive
+ (void)initialize
{
449
450
451
452
453
454
455
456
457


458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482






483
484
485

486
487
488
489
490

491
492
493
494
495
496
497
449
450
451
452
453
454
455


456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476






477
478
479
480
481
482
483
484

485
486
487
488
489

490
491
492
493
494
495
496
497







-
-
+
+



















-
-
-
-
-
-
+
+
+
+
+
+


-
+




-
+







		    @"Need one or more files to add!")];
		app->_exitStatus = 1;
		return;
	}

	for (OFString *fileName in files) {
		void *pool = objc_autoreleasePoolPush();
		of_file_attributes_t attributes;
		of_file_type_t type;
		OFFileAttributes attributes;
		OFFileAttributeType type;
		OFMutableLHAArchiveEntry *entry;
		OFStream *output;

		if (app->_outputLevel >= 0)
			[of_stdout writeString: OF_LOCALIZED(@"adding_file",
			    @"Adding %[file]...",
			    @"file", fileName)];

		attributes = [fileManager attributesOfItemAtPath: fileName];
		type = attributes.fileType;
		entry = [OFMutableLHAArchiveEntry entryWithFileName: fileName];

#ifdef OF_FILE_MANAGER_SUPPORTS_PERMISSIONS
		entry.mode = [OFNumber numberWithUnsignedLong:
		    attributes.filePOSIXPermissions];
#endif
		entry.date = attributes.fileModificationDate;

#ifdef OF_FILE_MANAGER_SUPPORTS_OWNER
		entry.UID =
		    [OFNumber numberWithUnsignedLong: attributes.filePOSIXUID];
		entry.GID =
		    [OFNumber numberWithUnsignedLong: attributes.filePOSIXGID];
		entry.owner = attributes.fileOwner;
		entry.group = attributes.fileGroup;
		entry.UID = [OFNumber numberWithUnsignedLong:
		    attributes.fileOwnerAccountID];
		entry.GID = [OFNumber numberWithUnsignedLong:
		    attributes.fileGroupOwnerAccountID];
		entry.owner = attributes.fileOwnerAccountName;
		entry.group = attributes.fileGroupOwnerAccountName;
#endif

		if ([type isEqual: of_file_type_directory])
		if ([type isEqual: OFFileTypeDirectory])
			entry.compressionMethod = @"-lhd-";

		output = [_archive streamForWritingEntry: entry];

		if ([type isEqual: of_file_type_regular]) {
		if ([type isEqual: OFFileTypeRegular]) {
			unsigned long long written = 0;
			unsigned long long size = attributes.fileSize;
			int8_t percent = -1, newPercent;

			OFFile *input = [OFFile fileWithPath: fileName
							mode: @"r"];

Modified utils/ofarc/TarArchive.m from [5d7d524669] to [4ed164991e].

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
61
62
63
64
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
61
62
63
64







-
+

-
+










-
+






-
+







static OFArc *app;

static void
setPermissions(OFString *path, OFTarArchiveEntry *entry)
{
#ifdef OF_FILE_MANAGER_SUPPORTS_PERMISSIONS
	OFNumber *mode = [OFNumber numberWithUnsignedShort: entry.mode & 0777];
	of_file_attributes_t attributes = [OFDictionary
	OFFileAttributes attributes = [OFDictionary
	    dictionaryWithObject: mode
			  forKey: of_file_attribute_key_posix_permissions];
			  forKey: OFFilePOSIXPermissions];

	[[OFFileManager defaultManager] setAttributes: attributes
					 ofItemAtPath: path];
#endif
}

static void
setModificationDate(OFString *path, OFTarArchiveEntry *entry)
{
	OFDate *modificationDate = entry.modificationDate;
	of_file_attributes_t attributes;
	OFFileAttributes attributes;

	if (modificationDate == nil)
		return;

	attributes = [OFDictionary
	    dictionaryWithObject: modificationDate
			  forKey: of_file_attribute_key_modification_date];
			  forKey: OFFileModificationDate];
	[[OFFileManager defaultManager] setAttributes: attributes
					 ofItemAtPath: path];
}

@implementation TarArchive
+ (void)initialize
{
460
461
462
463
464
465
466
467
468


469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491




492
493
494

495
496

497
498
499

500
501
502
503
504
505
506
460
461
462
463
464
465
466


467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487




488
489
490
491
492
493

494
495

496
497
498

499
500
501
502
503
504
505
506







-
-
+
+



















-
-
-
-
+
+
+
+


-
+

-
+


-
+







		    @"Need one or more files to add!")];
		app->_exitStatus = 1;
		return;
	}

	for (OFString *fileName in files) {
		void *pool = objc_autoreleasePoolPush();
		of_file_attributes_t attributes;
		of_file_type_t type;
		OFFileAttributes attributes;
		OFFileAttributeType type;
		OFMutableTarArchiveEntry *entry;
		OFStream *output;

		if (app->_outputLevel >= 0)
			[of_stdout writeString: OF_LOCALIZED(@"adding_file",
			    @"Adding %[file]...",
			    @"file", fileName)];

		attributes = [fileManager attributesOfItemAtPath: fileName];
		type = attributes.fileType;
		entry = [OFMutableTarArchiveEntry entryWithFileName: fileName];

#ifdef OF_FILE_MANAGER_SUPPORTS_PERMISSIONS
		entry.mode = attributes.filePOSIXPermissions;
#endif
		entry.size = attributes.fileSize;
		entry.modificationDate = attributes.fileModificationDate;

#ifdef OF_FILE_MANAGER_SUPPORTS_OWNER
		entry.UID = attributes.filePOSIXUID;
		entry.GID = attributes.filePOSIXGID;
		entry.owner = attributes.fileOwner;
		entry.group = attributes.fileGroup;
		entry.UID = attributes.fileOwnerAccountID;
		entry.GID = attributes.fileGroupOwnerAccountID;
		entry.owner = attributes.fileOwnerAccountName;
		entry.group = attributes.fileGroupOwnerAccountName;
#endif

		if ([type isEqual: of_file_type_regular])
		if ([type isEqual: OFFileTypeRegular])
			entry.type = OF_TAR_ARCHIVE_ENTRY_TYPE_FILE;
		else if ([type isEqual: of_file_type_directory]) {
		else if ([type isEqual: OFFileTypeDirectory]) {
			entry.type = OF_TAR_ARCHIVE_ENTRY_TYPE_DIRECTORY;
			entry.size = 0;
		} else if ([type isEqual: of_file_type_symbolic_link]) {
		} else if ([type isEqual: OFFileTypeSymbolicLink]) {
			entry.type = OF_TAR_ARCHIVE_ENTRY_TYPE_SYMLINK;
			entry.targetFileName =
			    attributes.fileSymbolicLinkDestination;
			entry.size = 0;
		}

		[entry makeImmutable];

Modified utils/ofarc/ZIPArchive.m from [d17203d99f] to [20066e086c].

40
41
42
43
44
45
46
47
48
49
50



51
52
53
54
55
56
57
58
59
60
61
62

63
64
65
66
67
68
69

70
71
72
73
74
75
76
40
41
42
43
44
45
46




47
48
49
50
51
52
53
54
55
56
57
58
59
60

61
62
63
64
65
66
67

68
69
70
71
72
73
74
75







-
-
-
-
+
+
+











-
+






-
+







setPermissions(OFString *path, OFZIPArchiveEntry *entry)
{
#ifdef OF_FILE_MANAGER_SUPPORTS_PERMISSIONS
	if ((entry.versionMadeBy >> 8) ==
	    OF_ZIP_ARCHIVE_ENTRY_ATTR_COMPAT_UNIX) {
		OFNumber *mode = [OFNumber numberWithUnsignedShort:
		    (entry.versionSpecificAttributes >> 16) & 0777];
		of_file_attribute_key_t key =
		    of_file_attribute_key_posix_permissions;
		of_file_attributes_t attributes =
		    [OFDictionary dictionaryWithObject: mode forKey: key];
		OFFileAttributes attributes = [OFDictionary
		    dictionaryWithObject: mode
				  forKey: OFFilePOSIXPermissions];

		[[OFFileManager defaultManager] setAttributes: attributes
						 ofItemAtPath: path];
	}
#endif
}

static void
setModificationDate(OFString *path, OFZIPArchiveEntry *entry)
{
	OFDate *modificationDate = entry.modificationDate;
	of_file_attributes_t attributes;
	OFFileAttributes attributes;

	if (modificationDate == nil)
		return;

	attributes = [OFDictionary
	    dictionaryWithObject: modificationDate
			  forKey: of_file_attribute_key_modification_date];
			  forKey: OFFileModificationDate];
	[[OFFileManager defaultManager] setAttributes: attributes
					 ofItemAtPath: path];
}

@implementation ZIPArchive
+ (void)initialize
{
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
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







-
+











-
+







		return;
	}

	for (OFString *localFileName in files) {
		void *pool = objc_autoreleasePoolPush();
		OFArray OF_GENERIC (OFString *) *components;
		OFString *fileName;
		of_file_attributes_t attributes;
		OFFileAttributes attributes;
		bool isDirectory = false;
		OFMutableZIPArchiveEntry *entry;
		unsigned long long size;
		OFStream *output;

		components = localFileName.pathComponents;
		fileName = [components componentsJoinedByString: @"/"];

		attributes = [fileManager
		    attributesOfItemAtPath: localFileName];

		if ([attributes.fileType isEqual: of_file_type_directory]) {
		if ([attributes.fileType isEqual: OFFileTypeDirectory]) {
			isDirectory = true;
			fileName = [fileName stringByAppendingString: @"/"];
		}

		if (app->_outputLevel >= 0)
			[of_stdout writeString: OF_LOCALIZED(@"adding_file",
			    @"Adding %[file]...",