2 Copyright (C) 2000-2005 SKYRIX Software AG
4 This file is part of SOPE.
6 SOPE is free software; you can redistribute it and/or modify it under
7 the terms of the GNU Lesser General Public License as published by the
8 Free Software Foundation; either version 2, or (at your option) any
11 SOPE is distributed in the hope that it will be useful, but WITHOUT ANY
12 WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
14 License for more details.
16 You should have received a copy of the GNU Lesser General Public
17 License along with SOPE; see the file COPYING. If not, write to the
18 Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
22 #include "NGFileManager.h"
23 #include "NGFileManagerURL.h"
24 #include "NSObject+Logs.h"
27 @implementation NGFileManager
29 static BOOL logPathOps = NO;
36 if ((self = [super init])) {
46 /* path modifications */
48 - (NSString *)standardizePath:(NSString *)_path {
54 if (logPathOps) [self logWithFormat:@"standardize: %@", _path];
56 pc = [_path pathComponents];
57 if ((pcn = [pc count]) == 0) return _path;
60 [self logWithFormat:@" components: %@",
61 [pc componentsJoinedByString:@" => "]];
64 rpc = [NSMutableArray arrayWithCapacity:pcn];
66 for (i = 0; i < pcn; i++) {
69 p = [pc objectAtIndex:i];
71 if ([p isEqualToString:@"/"]) {
73 [rpc removeAllObjects];
76 else if ([p isEqualToString:@"."]) {
77 /* found current directory */
78 /* '.' can always be removed, right ??? ... */
80 else if ([p isEqualToString:@".."]) {
81 /* found parent directory */
83 /* relative path starting with '..' */
86 /* remove last path component .. */
89 if ((count = [rpc count]) > 0)
90 [rpc removeObjectAtIndex:(count - 1)];
93 else if ([p isEqualToString:@""]) {
94 /* ignore empty strings */
103 [self logWithFormat:@" new components: %@",
104 [rpc componentsJoinedByString:@" => "]];
106 result = [NSString pathWithComponents:rpc];
107 if ([result length] == 0)
110 if (logPathOps) [self logWithFormat:@" standardized: %@", result];
114 - (NSString *)resolveSymlinksInPath:(NSString *)_path {
118 - (NSString *)expandTildeInPath:(NSString *)_path {
122 /* directory operations */
124 - (BOOL)changeCurrentDirectoryPath:(NSString *)_path {
127 if (![self fileExistsAtPath:_path isDirectory:&isDir])
131 ASSIGNCOPY(self->cwd, _path);
134 - (NSString *)currentDirectoryPath {
138 - (BOOL)createDirectoryAtPath:(NSString *)_path
139 attributes:(NSDictionary *)_ats
144 /* file operations */
146 - (BOOL)copyPath:(NSString *)_s toPath:(NSString *)_d handler:(id)_handler {
149 - (BOOL)movePath:(NSString *)_s toPath:(NSString *)_d handler:(id)_handler {
152 - (BOOL)linkPath:(NSString *)_s toPath:(NSString *)_d handler:(id)_handler {
156 - (BOOL)removeFileAtPath:(NSString *)_path handler:(id)_handler {
160 - (BOOL)createFileAtPath:(NSString *)_path contents:(NSData *)_contents
161 attributes:(NSDictionary *)_attributes
166 /* getting and comparing file contents */
168 - (NSData *)contentsAtPath:(NSString *)_path {
171 - (BOOL)contentsEqualAtPath:(NSString *)_path1 andPath:(NSString *)_path2 {
172 NSData *data1, *data2;
174 data1 = [self contentsAtPath:_path1];
175 data2 = [self contentsAtPath:_path2];
177 if (data1 == data2) return YES;
178 if (data1 == nil || data2 == nil) return NO;
180 return [data1 isEqual:data2];
183 /* determining access to files */
185 - (BOOL)fileExistsAtPath:(NSString *)_path {
187 return [self fileExistsAtPath:_path isDirectory:&dummy];
189 - (BOOL)fileExistsAtPath:(NSString *)_path isDirectory:(BOOL*)_isDirectory {
192 - (BOOL)isReadableFileAtPath:(NSString *)_path {
195 - (BOOL)isWritableFileAtPath:(NSString *)_path {
198 - (BOOL)isExecutableFileAtPath:(NSString *)_path {
201 - (BOOL)isDeletableFileAtPath:(NSString *)_path {
205 /* Getting and setting attributes */
207 - (NSDictionary *)fileAttributesAtPath:(NSString *)_p traverseLink:(BOOL)_flag{
210 - (NSDictionary *)fileSystemAttributesAtPath:(NSString *)_p {
213 - (BOOL)changeFileAttributes:(NSDictionary *)_attributes atPath:(NSString *)_p{
217 /* discovering directory contents */
219 - (NSArray *)directoryContentsAtPath:(NSString *)_path {
222 - (NSDirectoryEnumerator *)enumeratorAtPath:(NSString *)_path {
225 - (NSArray *)subpathsAtPath:(NSString *)_path {
229 /* symbolic-link operations */
231 - (BOOL)createSymbolicLinkAtPath:(NSString *)_p pathContent:(NSString *)_dpath{
234 - (NSString *)pathContentOfSymbolicLinkAtPath:(NSString *)_path {
240 - (BOOL)supportsVersioningAtPath:(NSString *)_path {
241 return [self supportsFeature:NGFileManagerFeature_Versioning atPath:_path];
243 - (BOOL)supportsLockingAtPath:(NSString *)_path {
244 return [self supportsFeature:NGFileManagerFeature_Locking atPath:_path];
246 - (BOOL)supportsFolderDataSourceAtPath:(NSString *)_path {
247 return [self supportsFeature:NGFileManagerFeature_DataSources atPath:_path];
249 - (BOOL)supportsFeature:(NSString *)_featureURI atPath:(NSString *)_path {
255 - (BOOL)writeContents:(NSData *)_content atPath:(NSString *)_path {
261 - (EOGlobalID *)globalIDForPath:(NSString *)_path; {
264 - (NSString *)pathForGlobalID:(EOGlobalID *)_gid {
270 - (BOOL)supportsTrashFolderAtPath:(NSString *)_path {
273 - (NSString *)trashFolderForPath:(NSString *)_path {
277 - (BOOL)trashFileAtPath:(NSString *)_path handler:(id)_handler {
278 NSString *trash, *destPath;
283 if (![self supportsTrashFolderAtPath:_path])
285 if ([(trash = [self trashFolderForPath:_path]) length] == 0)
288 if ([_path hasPrefix:trash])
289 /* path already is in trash ... */
292 /* ensure that the trash folder is existent */
294 if ([self fileExistsAtPath:trash isDirectory:&isDir]) {
296 NSLog(@"%s: '%@' exists, but isn't a folder !", __PRETTY_FUNCTION__,
301 else { /* trash doesn't exist yet */
302 if (![self createDirectoryAtPath:trash attributes:nil]) {
303 NSLog(@"%s: couldn't create trash folder '%@' !", __PRETTY_FUNCTION__,
309 /* construct trash path for target ... */
311 destPath = [trash stringByAppendingPathComponent:
312 [_path lastPathComponent]];
315 while ([self fileExistsAtPath:tmp]) {
317 tmp = [destPath stringByAppendingFormat:@"%d", i];
319 NSLog(@"%s: too many files named similiar to '%@' in trash folder '%@'",
320 __PRETTY_FUNCTION__, destPath, trash);
327 if (![self movePath:_path toPath:destPath handler:_handler])
335 - (NSURL *)urlForPath:(NSString *)_path {
336 return [[[NGFileManagerURL alloc]
337 initWithPath:_path fileManager:self]
341 @end /* NGFileManager */