︙ | | | ︙ | |
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
|
unsigned int st_mode;
OFTimeInterval st_atime, st_mtime, st_ctime;
# ifdef OF_WINDOWS
# define HAVE_STRUCT_STAT_ST_BIRTHTIME
OFTimeInterval st_birthtime;
DWORD fileAttributes;
# endif
} of_stat_t;
#elif defined(HAVE_STAT64)
typedef struct stat64 of_stat_t;
#else
typedef struct stat of_stat_t;
#endif
#ifdef OF_WINDOWS
# define S_IFLNK 0x10000
# define S_ISLNK(mode) (mode & S_IFLNK)
#endif
|
|
|
|
|
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
|
unsigned int st_mode;
OFTimeInterval st_atime, st_mtime, st_ctime;
# ifdef OF_WINDOWS
# define HAVE_STRUCT_STAT_ST_BIRTHTIME
OFTimeInterval st_birthtime;
DWORD fileAttributes;
# endif
} Stat;
#elif defined(HAVE_STAT64)
typedef struct stat64 Stat;
#else
typedef struct stat Stat;
#endif
#ifdef OF_WINDOWS
# define S_IFLNK 0x10000
# define S_ISLNK(mode) (mode & S_IFLNK)
#endif
|
︙ | | | ︙ | |
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
|
releaseReaddirMutex(void)
{
[readdirMutex release];
}
#endif
#ifdef OF_WINDOWS
static int (*func__wutime64)(const wchar_t *, struct __utimbuf64 *);
static WINAPI BOOLEAN (*func_CreateSymbolicLinkW)(LPCWSTR, LPCWSTR, DWORD);
static WINAPI BOOLEAN (*func_CreateHardLinkW)(LPCWSTR, LPCWSTR,
LPSECURITY_ATTRIBUTES);
#endif
#ifdef OF_WINDOWS
static OFTimeInterval
filetimeToTimeInterval(const FILETIME *filetime)
{
|
|
|
|
|
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
|
releaseReaddirMutex(void)
{
[readdirMutex release];
}
#endif
#ifdef OF_WINDOWS
static int (*_wutime64FuncPtr)(const wchar_t *, struct __utimbuf64 *);
static WINAPI BOOLEAN (*createSymbolicLinkWFuncPtr)(LPCWSTR, LPCWSTR, DWORD);
static WINAPI BOOLEAN (*createHardLinkWFuncPtr)(LPCWSTR, LPCWSTR,
LPSECURITY_ATTRIBUTES);
#endif
#ifdef OF_WINDOWS
static OFTimeInterval
filetimeToTimeInterval(const FILETIME *filetime)
{
|
︙ | | | ︙ | |
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
|
default:
return EIO;
}
}
#endif
static int
of_stat(OFString *path, of_stat_t *buffer)
{
#if defined(OF_WINDOWS)
WIN32_FILE_ATTRIBUTE_DATA data;
bool success;
if ([OFSystemInfo isWindowsNT])
success = GetFileAttributesExW(path.UTF16String,
|
|
|
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
|
default:
return EIO;
}
}
#endif
static int
statWrapper(OFString *path, Stat *buffer)
{
#if defined(OF_WINDOWS)
WIN32_FILE_ATTRIBUTE_DATA data;
bool success;
if ([OFSystemInfo isWindowsNT])
success = GetFileAttributesExW(path.UTF16String,
|
︙ | | | ︙ | |
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
|
return errno;
return 0;
#endif
}
static int
of_lstat(OFString *path, of_stat_t *buffer)
{
#if defined(HAVE_LSTAT) && !defined(OF_WINDOWS) && !defined(OF_AMIGAOS) && \
!defined(OF_NINTENDO_3DS) && !defined(OF_WII)
# ifdef HAVE_LSTAT64
if (lstat64([path cStringWithEncoding: [OFLocale encoding]],
buffer) != 0)
return errno;
# else
if (lstat([path cStringWithEncoding: [OFLocale encoding]], buffer) != 0)
return errno;
# endif
return 0;
#else
return of_stat(path, buffer);
#endif
}
static void
setTypeAttribute(OFMutableFileAttributes attributes, of_stat_t *s)
{
if (S_ISREG(s->st_mode))
[attributes setObject: OFFileTypeRegular forKey: OFFileType];
else if (S_ISDIR(s->st_mode))
[attributes setObject: OFFileTypeDirectory forKey: OFFileType];
#ifdef S_ISLNK
else if (S_ISLNK(s->st_mode))
|
|
|
|
|
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
|
return errno;
return 0;
#endif
}
static int
lstatWrapper(OFString *path, Stat *buffer)
{
#if defined(HAVE_LSTAT) && !defined(OF_WINDOWS) && !defined(OF_AMIGAOS) && \
!defined(OF_NINTENDO_3DS) && !defined(OF_WII)
# ifdef HAVE_LSTAT64
if (lstat64([path cStringWithEncoding: [OFLocale encoding]],
buffer) != 0)
return errno;
# else
if (lstat([path cStringWithEncoding: [OFLocale encoding]], buffer) != 0)
return errno;
# endif
return 0;
#else
return statWrapper(path, buffer);
#endif
}
static void
setTypeAttribute(OFMutableFileAttributes attributes, Stat *s)
{
if (S_ISREG(s->st_mode))
[attributes setObject: OFFileTypeRegular forKey: OFFileType];
else if (S_ISDIR(s->st_mode))
[attributes setObject: OFFileTypeDirectory forKey: OFFileType];
#ifdef S_ISLNK
else if (S_ISLNK(s->st_mode))
|
︙ | | | ︙ | |
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
|
#ifdef S_ISSOCK
else if (S_ISSOCK(s->st_mode))
[attributes setObject: OFFileTypeSocket forKey: OFFileType];
#endif
}
static void
setDateAttributes(OFMutableFileAttributes attributes, of_stat_t *s)
{
/* FIXME: We could be more precise on some OSes */
[attributes
setObject: [OFDate dateWithTimeIntervalSince1970: s->st_atime]
forKey: OFFileLastAccessDate];
[attributes
setObject: [OFDate dateWithTimeIntervalSince1970: s->st_mtime]
forKey: OFFileModificationDate];
[attributes
setObject: [OFDate dateWithTimeIntervalSince1970: s->st_ctime]
forKey: OFFileStatusChangeDate];
#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
[attributes
setObject: [OFDate dateWithTimeIntervalSince1970: s->st_birthtime]
forKey: OFFileCreationDate];
#endif
}
static void
setOwnerAndGroupAttributes(OFMutableFileAttributes attributes, of_stat_t *s)
{
#ifdef OF_FILE_MANAGER_SUPPORTS_OWNER
[attributes setObject: [NSNumber numberWithUnsignedLong: s->st_uid]
forKey: OFFileOwnerAccountID];
[attributes setObject: [NSNumber numberWithUnsignedLong: s->st_gid]
forKey: OFFileGroupOwnerAccountID];
|
|
|
|
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
|
#ifdef S_ISSOCK
else if (S_ISSOCK(s->st_mode))
[attributes setObject: OFFileTypeSocket forKey: OFFileType];
#endif
}
static void
setDateAttributes(OFMutableFileAttributes attributes, Stat *s)
{
/* FIXME: We could be more precise on some OSes */
[attributes
setObject: [OFDate dateWithTimeIntervalSince1970: s->st_atime]
forKey: OFFileLastAccessDate];
[attributes
setObject: [OFDate dateWithTimeIntervalSince1970: s->st_mtime]
forKey: OFFileModificationDate];
[attributes
setObject: [OFDate dateWithTimeIntervalSince1970: s->st_ctime]
forKey: OFFileStatusChangeDate];
#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
[attributes
setObject: [OFDate dateWithTimeIntervalSince1970: s->st_birthtime]
forKey: OFFileCreationDate];
#endif
}
static void
setOwnerAndGroupAttributes(OFMutableFileAttributes attributes, Stat *s)
{
#ifdef OF_FILE_MANAGER_SUPPORTS_OWNER
[attributes setObject: [NSNumber numberWithUnsignedLong: s->st_uid]
forKey: OFFileOwnerAccountID];
[attributes setObject: [NSNumber numberWithUnsignedLong: s->st_gid]
forKey: OFFileGroupOwnerAccountID];
|
︙ | | | ︙ | |
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
|
[attributes setObject: destination
forKey: OFFileSymbolicLinkDestination];
# else
HANDLE handle;
OFString *destination;
if (func_CreateSymbolicLinkW == NULL)
return;
if ((handle = CreateFileW(path.UTF16String, 0, (FILE_SHARE_READ |
FILE_SHARE_WRITE), NULL, OPEN_EXISTING,
FILE_FLAG_OPEN_REPARSE_POINT, NULL)) == INVALID_HANDLE_VALUE)
@throw [OFRetrieveItemAttributesFailedException
exceptionWithURL: URL
|
|
|
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
|
[attributes setObject: destination
forKey: OFFileSymbolicLinkDestination];
# else
HANDLE handle;
OFString *destination;
if (createSymbolicLinkWFuncPtr == NULL)
return;
if ((handle = CreateFileW(path.UTF16String, 0, (FILE_SHARE_READ |
FILE_SHARE_WRITE), NULL, OPEN_EXISTING,
FILE_FLAG_OPEN_REPARSE_POINT, NULL)) == INVALID_HANDLE_VALUE)
@throw [OFRetrieveItemAttributesFailedException
exceptionWithURL: URL
|
︙ | | | ︙ | |
550
551
552
553
554
555
556
557
558
559
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
|
#if !defined(HAVE_READDIR_R) && !defined(OF_WINDOWS) && defined(OF_HAVE_THREADS)
readdirMutex = [[OFMutex alloc] init];
atexit(releaseReaddirMutex);
#endif
#ifdef OF_WINDOWS
if ((module = LoadLibrary("msvcrt.dll")) != NULL)
func__wutime64 = (int (*)(const wchar_t *,
struct __utimbuf64 *))GetProcAddress(module, "_wutime64");
if ((module = LoadLibrary("kernel32.dll")) != NULL) {
func_CreateSymbolicLinkW =
(WINAPI BOOLEAN (*)(LPCWSTR, LPCWSTR, DWORD))
GetProcAddress(module, "CreateSymbolicLinkW");
func_CreateHardLinkW =
(WINAPI BOOLEAN (*)(LPCWSTR, LPCWSTR,
LPSECURITY_ATTRIBUTES))
GetProcAddress(module, "CreateHardLinkW");
}
#endif
/*
* Make sure OFFile is initialized.
* On some systems, this is needed to initialize the file system driver.
*/
[OFFile class];
}
+ (bool)of_directoryExistsAtPath: (OFString *)path
{
of_stat_t s;
if (of_stat(path, &s) != 0)
return false;
return S_ISDIR(s.st_mode);
}
- (OFStream *)openItemAtURL: (OFURL *)URL mode: (OFString *)mode
{
|
|
|
|
|
|
|
550
551
552
553
554
555
556
557
558
559
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
|
#if !defined(HAVE_READDIR_R) && !defined(OF_WINDOWS) && defined(OF_HAVE_THREADS)
readdirMutex = [[OFMutex alloc] init];
atexit(releaseReaddirMutex);
#endif
#ifdef OF_WINDOWS
if ((module = LoadLibrary("msvcrt.dll")) != NULL)
_wutime64FuncPtr = (int (*)(const wchar_t *,
struct __utimbuf64 *))GetProcAddress(module, "_wutime64");
if ((module = LoadLibrary("kernel32.dll")) != NULL) {
createSymbolicLinkWFuncPtr =
(WINAPI BOOLEAN (*)(LPCWSTR, LPCWSTR, DWORD))
GetProcAddress(module, "CreateSymbolicLinkW");
createHardLinkWFuncPtr =
(WINAPI BOOLEAN (*)(LPCWSTR, LPCWSTR,
LPSECURITY_ATTRIBUTES))
GetProcAddress(module, "CreateHardLinkW");
}
#endif
/*
* Make sure OFFile is initialized.
* On some systems, this is needed to initialize the file system driver.
*/
[OFFile class];
}
+ (bool)of_directoryExistsAtPath: (OFString *)path
{
Stat s;
if (statWrapper(path, &s) != 0)
return false;
return S_ISDIR(s.st_mode);
}
- (OFStream *)openItemAtURL: (OFURL *)URL mode: (OFString *)mode
{
|
︙ | | | ︙ | |
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
|
- (OFFileAttributes)attributesOfItemAtURL: (OFURL *)URL
{
OFMutableFileAttributes ret = [OFMutableDictionary dictionary];
void *pool = objc_autoreleasePoolPush();
OFString *path;
int error;
of_stat_t s;
if (URL == nil)
@throw [OFInvalidArgumentException exception];
if (![[URL scheme] isEqual: _scheme])
@throw [OFInvalidArgumentException exception];
path = URL.fileSystemRepresentation;
if ((error = of_lstat(path, &s)) != 0)
@throw [OFRetrieveItemAttributesFailedException
exceptionWithURL: URL
errNo: error];
if (s.st_size < 0)
@throw [OFOutOfRangeException exception];
|
|
|
|
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
|
- (OFFileAttributes)attributesOfItemAtURL: (OFURL *)URL
{
OFMutableFileAttributes ret = [OFMutableDictionary dictionary];
void *pool = objc_autoreleasePoolPush();
OFString *path;
int error;
Stat s;
if (URL == nil)
@throw [OFInvalidArgumentException exception];
if (![[URL scheme] isEqual: _scheme])
@throw [OFInvalidArgumentException exception];
path = URL.fileSystemRepresentation;
if ((error = lstatWrapper(path, &s)) != 0)
@throw [OFRetrieveItemAttributesFailedException
exceptionWithURL: URL
errNo: error];
if (s.st_size < 0)
@throw [OFOutOfRangeException exception];
|
︙ | | | ︙ | |
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
|
if (lastAccessDate == nil)
lastAccessDate = modificationDate;
if (modificationDate == nil)
modificationDate = lastAccessDate;
#if defined(OF_WINDOWS)
if (func__wutime64 != NULL) {
struct __utimbuf64 times = {
.actime =
(__time64_t)lastAccessDate.timeIntervalSince1970,
.modtime =
(__time64_t)modificationDate.timeIntervalSince1970
};
if (func__wutime64([path UTF16String], ×) != 0)
@throw [OFSetItemAttributesFailedException
exceptionWithURL: URL
attributes: attributes
failedAttribute: attributeKey
errNo: errno];
} else {
struct _utimbuf times = {
|
|
|
|
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
|
if (lastAccessDate == nil)
lastAccessDate = modificationDate;
if (modificationDate == nil)
modificationDate = lastAccessDate;
#if defined(OF_WINDOWS)
if (_wutime64FuncPtr != NULL) {
struct __utimbuf64 times = {
.actime =
(__time64_t)lastAccessDate.timeIntervalSince1970,
.modtime =
(__time64_t)modificationDate.timeIntervalSince1970
};
if (_wutime64FuncPtr([path UTF16String], ×) != 0)
@throw [OFSetItemAttributesFailedException
exceptionWithURL: URL
attributes: attributes
failedAttribute: attributeKey
errNo: errno];
} else {
struct _utimbuf times = {
|
︙ | | | ︙ | |
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
|
objc_autoreleasePoolPop(pool);
}
- (bool)fileExistsAtURL: (OFURL *)URL
{
void *pool = objc_autoreleasePoolPush();
of_stat_t s;
bool ret;
if (URL == nil)
@throw [OFInvalidArgumentException exception];
if (![URL.scheme isEqual: _scheme])
@throw [OFInvalidArgumentException exception];
if (of_stat(URL.fileSystemRepresentation, &s) != 0) {
objc_autoreleasePoolPop(pool);
return false;
}
ret = S_ISREG(s.st_mode);
objc_autoreleasePoolPop(pool);
return ret;
}
- (bool)directoryExistsAtURL: (OFURL *)URL
{
void *pool = objc_autoreleasePoolPush();
of_stat_t s;
bool ret;
if (URL == nil)
@throw [OFInvalidArgumentException exception];
if (![URL.scheme isEqual: _scheme])
@throw [OFInvalidArgumentException exception];
if (of_stat(URL.fileSystemRepresentation, &s) != 0) {
objc_autoreleasePoolPop(pool);
return false;
}
ret = S_ISDIR(s.st_mode);
objc_autoreleasePoolPop(pool);
|
|
|
|
|
|
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
|
objc_autoreleasePoolPop(pool);
}
- (bool)fileExistsAtURL: (OFURL *)URL
{
void *pool = objc_autoreleasePoolPush();
Stat s;
bool ret;
if (URL == nil)
@throw [OFInvalidArgumentException exception];
if (![URL.scheme isEqual: _scheme])
@throw [OFInvalidArgumentException exception];
if (statWrapper(URL.fileSystemRepresentation, &s) != 0) {
objc_autoreleasePoolPop(pool);
return false;
}
ret = S_ISREG(s.st_mode);
objc_autoreleasePoolPop(pool);
return ret;
}
- (bool)directoryExistsAtURL: (OFURL *)URL
{
void *pool = objc_autoreleasePoolPush();
Stat s;
bool ret;
if (URL == nil)
@throw [OFInvalidArgumentException exception];
if (![URL.scheme isEqual: _scheme])
@throw [OFInvalidArgumentException exception];
if (statWrapper(URL.fileSystemRepresentation, &s) != 0) {
objc_autoreleasePoolPop(pool);
return false;
}
ret = S_ISDIR(s.st_mode);
objc_autoreleasePoolPop(pool);
|
︙ | | | ︙ | |
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
|
}
- (void)removeItemAtURL: (OFURL *)URL
{
void *pool = objc_autoreleasePoolPush();
OFString *path;
int error;
of_stat_t s;
if (URL == nil)
@throw [OFInvalidArgumentException exception];
if (![URL.scheme isEqual: _scheme])
@throw [OFInvalidArgumentException exception];
path = URL.fileSystemRepresentation;
if ((error = of_lstat(path, &s)) != 0)
@throw [OFRemoveItemFailedException exceptionWithURL: URL
errNo: error];
if (S_ISDIR(s.st_mode)) {
OFArray OF_GENERIC(OFURL *) *contents;
@try {
|
|
|
|
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
|
}
- (void)removeItemAtURL: (OFURL *)URL
{
void *pool = objc_autoreleasePoolPush();
OFString *path;
int error;
Stat s;
if (URL == nil)
@throw [OFInvalidArgumentException exception];
if (![URL.scheme isEqual: _scheme])
@throw [OFInvalidArgumentException exception];
path = URL.fileSystemRepresentation;
if ((error = lstatWrapper(path, &s)) != 0)
@throw [OFRemoveItemFailedException exceptionWithURL: URL
errNo: error];
if (S_ISDIR(s.st_mode)) {
OFArray OF_GENERIC(OFURL *) *contents;
@try {
|
︙ | | | ︙ | |
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
|
if (link([sourcePath cStringWithEncoding: encoding],
[destinationPath cStringWithEncoding: encoding]) != 0)
@throw [OFLinkFailedException
exceptionWithSourceURL: source
destinationURL: destination
errNo: errno];
# else
if (func_CreateHardLinkW == NULL)
@throw [OFNotImplementedException exceptionWithSelector: _cmd
object: self];
if (!func_CreateHardLinkW(destinationPath.UTF16String,
sourcePath.UTF16String, NULL))
@throw [OFLinkFailedException
exceptionWithSourceURL: source
destinationURL: destination
errNo: retrieveError()];
# endif
|
|
|
|
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
|
if (link([sourcePath cStringWithEncoding: encoding],
[destinationPath cStringWithEncoding: encoding]) != 0)
@throw [OFLinkFailedException
exceptionWithSourceURL: source
destinationURL: destination
errNo: errno];
# else
if (createHardLinkWFuncPtr == NULL)
@throw [OFNotImplementedException exceptionWithSelector: _cmd
object: self];
if (!createHardLinkWFuncPtr(destinationPath.UTF16String,
sourcePath.UTF16String, NULL))
@throw [OFLinkFailedException
exceptionWithSourceURL: source
destinationURL: destination
errNo: retrieveError()];
# endif
|
︙ | | | ︙ | |
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
|
if (symlink([target cStringWithEncoding: encoding],
[path cStringWithEncoding: encoding]) != 0)
@throw [OFCreateSymbolicLinkFailedException
exceptionWithURL: URL
target: target
errNo: errno];
# else
if (func_CreateSymbolicLinkW == NULL)
@throw [OFNotImplementedException exceptionWithSelector: _cmd
object: self];
if (!func_CreateSymbolicLinkW(path.UTF16String, target.UTF16String, 0))
@throw [OFCreateSymbolicLinkFailedException
exceptionWithURL: URL
target: target
errNo: retrieveError()];
# endif
objc_autoreleasePoolPop(pool);
|
|
|
>
|
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
|
if (symlink([target cStringWithEncoding: encoding],
[path cStringWithEncoding: encoding]) != 0)
@throw [OFCreateSymbolicLinkFailedException
exceptionWithURL: URL
target: target
errNo: errno];
# else
if (createSymbolicLinkWFuncPtr == NULL)
@throw [OFNotImplementedException exceptionWithSelector: _cmd
object: self];
if (!createSymbolicLinkWFuncPtr(path.UTF16String, target.UTF16String,
0))
@throw [OFCreateSymbolicLinkFailedException
exceptionWithURL: URL
target: target
errNo: retrieveError()];
# endif
objc_autoreleasePoolPop(pool);
|
︙ | | | ︙ | |