2 Copyright (C) 2000-2004 SKYRIX Software AG
4 This file is part of OpenGroupware.org.
6 OGo 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 OGo 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 OGo; see the file COPYING. If not, write to the
18 Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
23 #include "NGFileManager.h"
24 #include "NGFileManagerURL.h"
25 #include "NSObject+Logs.h"
28 @implementation NGFileManager
30 static BOOL logPathOps = NO;
37 if ((self = [super init])) {
47 /* path modifications */
49 - (NSString *)standardizePath:(NSString *)_path {
55 if (logPathOps) [self logWithFormat:@"standardize: %@", _path];
57 pc = [_path pathComponents];
58 if ((pcn = [pc count]) == 0) return _path;
61 [self logWithFormat:@" components: %@",
62 [pc componentsJoinedByString:@" => "]];
65 rpc = [NSMutableArray arrayWithCapacity:pcn];
67 for (i = 0; i < pcn; i++) {
70 p = [pc objectAtIndex:i];
72 if ([p isEqualToString:@"/"]) {
74 [rpc removeAllObjects];
77 else if ([p isEqualToString:@"."]) {
78 /* found current directory */
79 /* '.' can always be removed, right ??? ... */
81 else if ([p isEqualToString:@".."]) {
82 /* found parent directory */
84 /* relative path starting with '..' */
87 /* remove last path component .. */
90 if ((count = [rpc count]) > 0)
91 [rpc removeObjectAtIndex:(count - 1)];
94 else if ([p isEqualToString:@""]) {
95 /* ignore empty strings */
104 [self logWithFormat:@" new components: %@",
105 [rpc componentsJoinedByString:@" => "]];
107 result = [NSString pathWithComponents:rpc];
108 if ([result length] == 0)
111 if (logPathOps) [self logWithFormat:@" standardized: %@", result];
115 - (NSString *)resolveSymlinksInPath:(NSString *)_path {
119 - (NSString *)expandTildeInPath:(NSString *)_path {
123 /* directory operations */
125 - (BOOL)changeCurrentDirectoryPath:(NSString *)_path {
128 if (![self fileExistsAtPath:_path isDirectory:&isDir])
132 ASSIGNCOPY(self->cwd, _path);
135 - (NSString *)currentDirectoryPath {
139 - (BOOL)createDirectoryAtPath:(NSString *)_path
140 attributes:(NSDictionary *)_ats
145 /* file operations */
147 - (BOOL)copyPath:(NSString *)_s toPath:(NSString *)_d handler:(id)_handler {
150 - (BOOL)movePath:(NSString *)_s toPath:(NSString *)_d handler:(id)_handler {
153 - (BOOL)linkPath:(NSString *)_s toPath:(NSString *)_d handler:(id)_handler {
157 - (BOOL)removeFileAtPath:(NSString *)_path handler:(id)_handler {
161 - (BOOL)createFileAtPath:(NSString *)_path contents:(NSData *)_contents
162 attributes:(NSDictionary *)_attributes
167 /* getting and comparing file contents */
169 - (NSData *)contentsAtPath:(NSString *)_path {
172 - (BOOL)contentsEqualAtPath:(NSString *)_path1 andPath:(NSString *)_path2 {
173 NSData *data1, *data2;
175 data1 = [self contentsAtPath:_path1];
176 data2 = [self contentsAtPath:_path2];
178 if (data1 == data2) return YES;
179 if (data1 == nil || data2 == nil) return NO;
181 return [data1 isEqual:data2];
184 /* determining access to files */
186 - (BOOL)fileExistsAtPath:(NSString *)_path {
188 return [self fileExistsAtPath:_path isDirectory:&dummy];
190 - (BOOL)fileExistsAtPath:(NSString *)_path isDirectory:(BOOL*)_isDirectory {
193 - (BOOL)isReadableFileAtPath:(NSString *)_path {
196 - (BOOL)isWritableFileAtPath:(NSString *)_path {
199 - (BOOL)isExecutableFileAtPath:(NSString *)_path {
202 - (BOOL)isDeletableFileAtPath:(NSString *)_path {
206 /* Getting and setting attributes */
208 - (NSDictionary *)fileAttributesAtPath:(NSString *)_p traverseLink:(BOOL)_flag{
211 - (NSDictionary *)fileSystemAttributesAtPath:(NSString *)_p {
214 - (BOOL)changeFileAttributes:(NSDictionary *)_attributes atPath:(NSString *)_p{
218 /* discovering directory contents */
220 - (NSArray *)directoryContentsAtPath:(NSString *)_path {
223 - (NSDirectoryEnumerator *)enumeratorAtPath:(NSString *)_path {
226 - (NSArray *)subpathsAtPath:(NSString *)_path {
230 /* symbolic-link operations */
232 - (BOOL)createSymbolicLinkAtPath:(NSString *)_p pathContent:(NSString *)_dpath{
235 - (NSString *)pathContentOfSymbolicLinkAtPath:(NSString *)_path {
241 - (BOOL)supportsVersioningAtPath:(NSString *)_path {
242 return [self supportsFeature:NGFileManagerFeature_Versioning atPath:_path];
244 - (BOOL)supportsLockingAtPath:(NSString *)_path {
245 return [self supportsFeature:NGFileManagerFeature_Locking atPath:_path];
247 - (BOOL)supportsFolderDataSourceAtPath:(NSString *)_path {
248 return [self supportsFeature:NGFileManagerFeature_DataSources atPath:_path];
250 - (BOOL)supportsFeature:(NSString *)_featureURI atPath:(NSString *)_path {
256 - (BOOL)writeContents:(NSData *)_content atPath:(NSString *)_path {
262 - (EOGlobalID *)globalIDForPath:(NSString *)_path; {
265 - (NSString *)pathForGlobalID:(EOGlobalID *)_gid {
271 - (BOOL)supportsTrashFolderAtPath:(NSString *)_path {
274 - (NSString *)trashFolderForPath:(NSString *)_path {
278 - (BOOL)trashFileAtPath:(NSString *)_path handler:(id)_handler {
279 NSString *trash, *destPath;
284 if (![self supportsTrashFolderAtPath:_path])
286 if ([(trash = [self trashFolderForPath:_path]) length] == 0)
289 if ([_path hasPrefix:trash])
290 /* path already is in trash ... */
293 /* ensure that the trash folder is existent */
295 if ([self fileExistsAtPath:trash isDirectory:&isDir]) {
297 NSLog(@"%s: '%@' exists, but isn't a folder !", __PRETTY_FUNCTION__,
302 else { /* trash doesn't exist yet */
303 if (![self createDirectoryAtPath:trash attributes:nil]) {
304 NSLog(@"%s: couldn't create trash folder '%@' !", __PRETTY_FUNCTION__,
310 /* construct trash path for target ... */
312 destPath = [trash stringByAppendingPathComponent:
313 [_path lastPathComponent]];
316 while ([self fileExistsAtPath:tmp]) {
318 tmp = [destPath stringByAppendingFormat:@"%d", i];
320 NSLog(@"%s: too many files named similiar to '%@' in trash folder '%@'",
321 __PRETTY_FUNCTION__, destPath, trash);
328 if (![self movePath:_path toPath:destPath handler:_handler])
336 - (NSURL *)urlForPath:(NSString *)_path {
337 return [[[NGFileManagerURL alloc]
338 initWithPath:_path fileManager:self]
342 @end /* NGFileManager */