]> err.no Git - sope/blob - sope-core/NGExtensions/NGFileManager.m
Drop apache 1 build-dependency
[sope] / sope-core / NGExtensions / NGFileManager.m
1 /*
2   Copyright (C) 2000-2005 SKYRIX Software AG
3
4   This file is part of SOPE.
5
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
9   later version.
10
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.
15
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
19   02111-1307, USA.
20 */
21
22 #include "NGFileManager.h"
23 #include "NGFileManagerURL.h"
24 #include "NSObject+Logs.h"
25 #include "common.h"
26
27 @implementation NGFileManager
28
29 static BOOL logPathOps = NO;
30
31 + (int)version {
32   return 0;
33 }
34
35 - (id)init {
36   if ((self = [super init])) {
37     self->cwd = @"/";
38   }
39   return self;
40 }
41 - (void)dealloc {
42   [self->cwd release];
43   [super dealloc];
44 }
45
46 /* path modifications */
47
48 - (NSString *)standardizePath:(NSString *)_path {
49   NSMutableArray *rpc;
50   NSArray        *pc;
51   unsigned       i, pcn;
52   NSString       *result;
53
54   if (logPathOps) [self logWithFormat:@"standardize: %@", _path];
55   
56   pc = [_path pathComponents];
57   if ((pcn = [pc count]) == 0) return _path;
58
59   if (logPathOps) {
60     [self logWithFormat:@"  components: %@", 
61             [pc componentsJoinedByString:@" => "]];
62   }
63   
64   rpc = [NSMutableArray arrayWithCapacity:pcn];
65   
66   for (i = 0; i < pcn; i++) {
67     NSString *p;
68     
69     p = [pc objectAtIndex:i];
70     
71     if ([p isEqualToString:@"/"]) {
72       /* found root */
73       [rpc removeAllObjects];
74       [rpc addObject:@"/"];
75     }
76     else if ([p isEqualToString:@"."]) {
77       /* found current directory */
78       /* '.' can always be removed, right ??? ... */
79     }
80     else if ([p isEqualToString:@".."]) {
81       /* found parent directory */
82       if (i == 0)
83         /* relative path starting with '..' */
84         [rpc addObject:p];
85       else {
86         /* remove last path component .. */
87         unsigned count;
88         
89         if ((count = [rpc count]) > 0)
90           [rpc removeObjectAtIndex:(count - 1)];
91       }
92     }
93     else if ([p isEqualToString:@""]) {
94       /* ignore empty strings */
95     }
96     else {
97       /* usual path */
98       [rpc addObject:p];
99     }
100   }
101   
102   if (logPathOps) {
103     [self logWithFormat:@"  new components: %@", 
104             [rpc componentsJoinedByString:@" => "]];
105   }
106   result = [NSString pathWithComponents:rpc];
107   if ([result length] == 0)
108     return _path;
109   
110   if (logPathOps) [self logWithFormat:@"  standardized: %@", result];
111   return result;
112 }
113
114 - (NSString *)resolveSymlinksInPath:(NSString *)_path {
115   return _path;
116 }
117
118 - (NSString *)expandTildeInPath:(NSString *)_path {
119   return _path;
120 }
121
122 /* directory operations */
123
124 - (BOOL)changeCurrentDirectoryPath:(NSString *)_path {
125   BOOL isDir;
126
127   if (![self fileExistsAtPath:_path isDirectory:&isDir])
128     return NO;
129   if (!isDir)
130     return NO;
131   ASSIGNCOPY(self->cwd, _path);
132   return YES;
133 }
134 - (NSString *)currentDirectoryPath {
135   return self->cwd;
136 }
137
138 - (BOOL)createDirectoryAtPath:(NSString *)_path
139   attributes:(NSDictionary *)_ats
140 {
141   return NO;
142 }
143
144 /* file operations */
145
146 - (BOOL)copyPath:(NSString *)_s toPath:(NSString *)_d handler:(id)_handler {
147   return NO;
148 }
149 - (BOOL)movePath:(NSString *)_s toPath:(NSString *)_d handler:(id)_handler {
150   return NO;
151 }
152 - (BOOL)linkPath:(NSString *)_s toPath:(NSString *)_d handler:(id)_handler {
153   return NO;
154 }
155
156 - (BOOL)removeFileAtPath:(NSString *)_path handler:(id)_handler {
157   return NO;
158 }
159
160 - (BOOL)createFileAtPath:(NSString *)_path contents:(NSData *)_contents
161   attributes:(NSDictionary *)_attributes
162 {
163   return NO;
164 }
165
166 /* getting and comparing file contents */
167
168 - (NSData *)contentsAtPath:(NSString *)_path {
169   return nil;
170 }
171 - (BOOL)contentsEqualAtPath:(NSString *)_path1 andPath:(NSString *)_path2 {
172   NSData *data1, *data2;
173   
174   data1 = [self contentsAtPath:_path1];
175   data2 = [self contentsAtPath:_path2];
176   
177   if (data1 == data2) return YES;
178   if (data1 == nil || data2 == nil) return NO;
179   
180   return [data1 isEqual:data2];
181 }
182
183 /* determining access to files */
184
185 - (BOOL)fileExistsAtPath:(NSString *)_path {
186   BOOL dummy = NO;
187   return [self fileExistsAtPath:_path isDirectory:&dummy];
188 }
189 - (BOOL)fileExistsAtPath:(NSString *)_path isDirectory:(BOOL*)_isDirectory {
190   return NO;
191 }
192 - (BOOL)isReadableFileAtPath:(NSString *)_path {
193   return NO;
194 }
195 - (BOOL)isWritableFileAtPath:(NSString *)_path {
196   return NO;
197 }
198 - (BOOL)isExecutableFileAtPath:(NSString *)_path {
199   return NO;
200 }
201 - (BOOL)isDeletableFileAtPath:(NSString *)_path {
202   return NO;
203 }
204
205 /* Getting and setting attributes */
206
207 - (NSDictionary *)fileAttributesAtPath:(NSString *)_p traverseLink:(BOOL)_flag{
208   return nil;
209 }
210 - (NSDictionary *)fileSystemAttributesAtPath:(NSString *)_p {
211   return nil;
212 }
213 - (BOOL)changeFileAttributes:(NSDictionary *)_attributes atPath:(NSString *)_p{
214   return NO;
215 }
216
217 /* discovering directory contents */
218
219 - (NSArray *)directoryContentsAtPath:(NSString *)_path {
220   return nil;
221 }
222 - (NSDirectoryEnumerator *)enumeratorAtPath:(NSString *)_path {
223   return nil;
224 }
225 - (NSArray *)subpathsAtPath:(NSString *)_path {
226   return nil;
227 }
228
229 /* symbolic-link operations */
230
231 - (BOOL)createSymbolicLinkAtPath:(NSString *)_p pathContent:(NSString *)_dpath{
232   return NO;
233 }
234 - (NSString *)pathContentOfSymbolicLinkAtPath:(NSString *)_path {
235   return nil;
236 }
237
238 /* feature check */
239
240 - (BOOL)supportsVersioningAtPath:(NSString *)_path {
241   return [self supportsFeature:NGFileManagerFeature_Versioning atPath:_path];
242 }
243 - (BOOL)supportsLockingAtPath:(NSString *)_path {
244   return [self supportsFeature:NGFileManagerFeature_Locking atPath:_path];
245 }
246 - (BOOL)supportsFolderDataSourceAtPath:(NSString *)_path {
247   return [self supportsFeature:NGFileManagerFeature_DataSources atPath:_path];
248 }
249 - (BOOL)supportsFeature:(NSString *)_featureURI atPath:(NSString *)_path {
250   return NO;
251 }
252
253 /* writing */
254
255 - (BOOL)writeContents:(NSData *)_content atPath:(NSString *)_path {
256   return NO;
257 }
258
259 /* global-IDs */
260
261 - (EOGlobalID *)globalIDForPath:(NSString *)_path; {
262   return nil;
263 }
264 - (NSString *)pathForGlobalID:(EOGlobalID *)_gid {
265   return nil;
266 }
267
268 /* trash */
269
270 - (BOOL)supportsTrashFolderAtPath:(NSString *)_path {
271   return NO;
272 }
273 - (NSString *)trashFolderForPath:(NSString *)_path {
274   return nil;
275 }
276
277 - (BOOL)trashFileAtPath:(NSString *)_path handler:(id)_handler {
278   NSString *trash, *destPath;
279   BOOL     isDir;
280   unsigned i;
281   NSString *tmp;
282   
283   if (![self supportsTrashFolderAtPath:_path])
284     return NO;
285   if ([(trash = [self trashFolderForPath:_path]) length] == 0)
286     return NO;
287   
288   if ([_path hasPrefix:trash])
289     /* path already is in trash ... */
290     return YES;
291   
292   /* ensure that the trash folder is existent */
293
294   if ([self fileExistsAtPath:trash isDirectory:&isDir]) {
295     if (!isDir) {
296       NSLog(@"%s: '%@' exists, but isn't a folder !", __PRETTY_FUNCTION__,
297             trash);
298       return NO;
299     }
300   }
301   else { /* trash doesn't exist yet */
302     if (![self createDirectoryAtPath:trash attributes:nil]) {
303       NSLog(@"%s: couldn't create trash folder '%@' !", __PRETTY_FUNCTION__,
304             trash);
305       return NO;
306     }
307   }
308
309   /* construct trash path for target ... */
310
311   destPath = [trash stringByAppendingPathComponent:
312                       [_path lastPathComponent]];
313   tmp = destPath;
314   i = 0;
315   while ([self fileExistsAtPath:tmp]) {
316     i++;
317     tmp = [destPath stringByAppendingFormat:@"%d", i];
318     if (i > 40) {
319       NSLog(@"%s: too many files named similiar to '%@' in trash folder '%@'",
320             __PRETTY_FUNCTION__, destPath, trash);
321       return NO;
322     }
323   }
324   destPath = tmp;
325   
326   /* move to trash */
327   if (![self movePath:_path toPath:destPath handler:_handler])
328     return NO;
329   
330   return YES;
331 }
332
333 /* URLs */
334
335 - (NSURL *)urlForPath:(NSString *)_path {
336   return [[[NGFileManagerURL alloc]
337                              initWithPath:_path fileManager:self]
338                              autorelease];
339 }
340
341 @end /* NGFileManager */