Oolite 1.91.0.7745-260117-205bce7
Loading...
Searching...
No Matches
NSFileManagerOOExtensions.m
Go to the documentation of this file.
1/*
2
3NSFileManagerOOExtensions.m
4
5This extends NSFileManager and adds some methods to insulate the
6main oolite code from the gory details of creating/chdiring to the
7commander save directory.
8
9Oolite
10Copyright (C) 2004-2013 Giles C Williams and contributors
11
12This program is free software; you can redistribute it and/or
13modify it under the terms of the GNU General Public License
14as published by the Free Software Foundation; either version 2
15of the License, or (at your option) any later version.
16
17This program is distributed in the hope that it will be useful,
18but WITHOUT ANY WARRANTY; without even the implied warranty of
19MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20GNU General Public License for more details.
21
22You should have received a copy of the GNU General Public License
23along with this program; if not, write to the Free Software
24Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
25MA 02110-1301, USA.
26
27*/
28
29#include <stdlib.h>
30#include <SDL.h>
31#import "ResourceManager.h"
32#import "OOPListParsing.h"
33#import "GameController.h"
35#import "unzip.h"
36
37@implementation NSFileManager (OOExtensions)
38
39- (NSArray *) commanderContentsOfPath:(NSString *)savePath
40{
41 BOOL pathIsDirectory = NO;
42 if ([[NSFileManager defaultManager] fileExistsAtPath:savePath isDirectory:&pathIsDirectory] && pathIsDirectory)
43 {
44 NSMutableArray *contents = [NSMutableArray arrayWithArray:[self oo_directoryContentsAtPath:savePath]];
45
46 // at this point we should strip out any files not loadable as Oolite saved games
47 unsigned i;
48 for (i = 0; i < [contents count]; i++)
49 {
50 NSString* path = [savePath stringByAppendingPathComponent: (NSString*)[contents objectAtIndex:i]];
51
52 // ensure it's not a directory
53 if (![[NSFileManager defaultManager] fileExistsAtPath:path isDirectory:&pathIsDirectory] && pathIsDirectory)
54 {
55
56 // check file extension
57 if (![[path pathExtension] isEqual:@"oolite-save"])
58 {
59 [contents removeObjectAtIndex: i--];
60 continue;
61 }
62
63 // check to see if we can parse the file okay
64 NSDictionary *cdr = OODictionaryFromFile(path);
65 if (!cdr)
66 {
67 OOLog(@"savedGame.read.fail.notDictionary", @">>>> %@ could not be parsed as a saved game.", path);
68 [contents removeObjectAtIndex: i--];
69 continue;
70 }
71 }
72
73 // all okay - we can use this path!
74 [contents replaceObjectAtIndex: i withObject: path];
75
76 }
77
78 return contents;
79 }
80 else
81 {
82 OOLogERR(@"savedGame.read.fail.fileNotFound", @"File at path '%@' could not be found.", savePath);
83 return nil;
84 }
85}
86
87
89{
90 const char *savedirEnv = SDL_getenv("OO_SAVEDIR");
91 NSString *savedir;
92
93 if (savedirEnv)
94 {
95 savedir = [NSString stringWithUTF8String:savedirEnv];
96 }
97 else
98 {
99 savedir = [NSHomeDirectory() stringByAppendingPathComponent:@SAVEDIR];
100 }
101 BOOL pathIsDirectory = NO;
102
103 // does it exist?
104 if (![[NSFileManager defaultManager] fileExistsAtPath:savedir isDirectory:&pathIsDirectory])
105 {
106 // it doesn't exist.
107 if([self oo_createDirectoryAtPath:savedir attributes:nil])
108 {
109 return savedir;
110 }
111 else
112 {
113 OOLogERR(@"savedGame.defaultPath.create.failed", @"Unable to create '%@'. Saved games will go to the home directory.", savedir);
114 return NSHomeDirectory();
115 }
116 }
117
118 // is it a directory?
119 if (!pathIsDirectory)
120 {
121 OOLogERR(@"savedGame.defaultPath.notDirectory", @"'%@' is not a directory, saved games will go to the home directory.", savedir);
122 return NSHomeDirectory();
123 }
124
125 return savedir;
126}
127
128
129#if OOLITE_MAC_OS_X
130
131- (NSArray *) oo_directoryContentsAtPath:(NSString *)path
132{
133 return [self contentsOfDirectoryAtPath:path error:NULL];
134}
135
136
137- (BOOL) oo_createDirectoryAtPath:(NSString *)path attributes:(NSDictionary *)attributes
138{
139 return [self createDirectoryAtPath:path withIntermediateDirectories:YES attributes:attributes error:NULL];
140}
141
142
143- (NSDictionary *) oo_fileAttributesAtPath:(NSString *)path traverseLink:(BOOL)traverseLink
144{
145 if (traverseLink)
146 {
147 NSString *linkDest = nil;
148 do
149 {
150 linkDest = [self destinationOfSymbolicLinkAtPath:path error:NULL];
151 if (linkDest != nil) path = linkDest;
152 } while (linkDest != nil);
153 }
154
155 return [self attributesOfItemAtPath:path error:NULL];
156}
157
158
159- (NSDictionary *) oo_fileSystemAttributesAtPath:(NSString *)path
160{
161 return [self attributesOfFileSystemForPath:path error:NULL];
162}
163
164
165- (BOOL) oo_removeItemAtPath:(NSString *)path
166{
167 return [self removeItemAtPath:path error:NULL];
168}
169
170
171- (BOOL) oo_moveItemAtPath:(NSString *)src toPath:(NSString *)dest
172{
173 return [self moveItemAtPath:src toPath:dest error:NULL];
174}
175
176#else
177
178- (NSArray *) oo_directoryContentsAtPath:(NSString *)path
179{
180 return [self directoryContentsAtPath:path];
181}
182
183
184- (BOOL) oo_createDirectoryAtPath:(NSString *)path attributes:(NSDictionary *)attributes
185{
186 #if OOLITE_WINDOWS && !OOLITE_MODERN_BUILD
187 return [self createDirectoryAtPath:path attributes:attributes];
188 #else
189 // has been in GNUStep since 2008, so it's probably safe to use now.
190 // .... why do I say things like that, of course it's not safe - CIM
191 return [self createDirectoryAtPath:path withIntermediateDirectories:YES attributes:attributes error:NULL];
192 #endif
193}
194
195
196- (NSDictionary *) oo_fileAttributesAtPath:(NSString *)path traverseLink:(BOOL)yorn
197{
198 return [self fileAttributesAtPath:path traverseLink:yorn];
199}
200
201
202- (NSDictionary *) oo_fileSystemAttributesAtPath:(NSString *)path
203{
204 return [self fileSystemAttributesAtPath:path];
205}
206
207
208- (BOOL) oo_removeItemAtPath:(NSString *)path
209{
210 return [self removeFileAtPath:path handler:nil];
211}
212
213
214- (BOOL) oo_moveItemAtPath:(NSString *)src toPath:(NSString *)dest
215{
216 return [self movePath:src toPath:dest handler:nil];
217}
218
219#endif
220
221
222#if OOLITE_SDL
223- (BOOL) chdirToSnapshotPath
224{
225 const char *snapshotEnv = SDL_getenv("OO_SNAPSHOTSDIR");
226 NSString *savedir;
227
228 if (snapshotEnv)
229 {
230 savedir = [NSString stringWithUTF8String:snapshotEnv];
231 }
232 else
233 {
234 // SDL: the default path for snapshots is oolite.app/oolite-saves/snapshots
235 savedir = [[NSHomeDirectory() stringByAppendingPathComponent:@SAVEDIR] stringByAppendingPathComponent:@SNAPSHOTDIR];
236 }
237
238 if (![self changeCurrentDirectoryPath: savedir])
239 {
240 // it probably doesn't exist.
241 if (![self oo_createDirectoryAtPath: savedir attributes: nil])
242 {
243 OOLog(@"savedSnapshot.defaultPath.create.failed", @"Unable to create directory %@", savedir);
244 return NO;
245 }
246 if (![self changeCurrentDirectoryPath: savedir])
247 {
248 OOLog(@"savedSnapshot.defaultPath.chdir.failed", @"Created %@ but couldn't make it the current directory.", savedir);
249 return NO;
250 }
251 }
252
253 return YES;
254}
255#endif
256
257- (BOOL) oo_oxzFileExistsAtPath:(NSString *)path
258{
259 NSUInteger i, cl;
260 NSArray *components = [path pathComponents];
261 cl = [components count];
262 for (i = 0 ; i < cl ; i++)
263 {
264 NSString *component = [components objectAtIndex:i];
265 if ([[[component pathExtension] lowercaseString] isEqualToString:@"oxz"])
266 {
267 break;
268 }
269 }
270 // if i == cl then the path is entirely uncompressed
271 if (i == cl)
272 {
273 BOOL directory = NO;
274 BOOL result = [self fileExistsAtPath:path isDirectory:&directory];
275 if (directory)
276 {
277 return NO;
278 }
279 return result;
280 }
281
282 NSRange range;
283 range.location = 0; range.length = i+1;
284 NSString *zipFile = [NSString pathWithComponents:[components subarrayWithRange:range]];
285 range.location = i+1; range.length = cl-(i+1);
286 NSString *containedFile = [NSString pathWithComponents:[components subarrayWithRange:range]];
287
288 unzFile uf = NULL;
289 const char* zipname = [zipFile cStringUsingEncoding:NSUTF8StringEncoding];
290 if (zipname != NULL)
291 {
292 uf = unzOpen64(zipname);
293 }
294 if (uf == NULL)
295 {
296 // no such zip file
297 return NO;
298 }
299 const char* filename = [containedFile cStringUsingEncoding:NSUTF8StringEncoding];
300 // unzLocateFile(*, *, 1) = case-sensitive extract
301 BOOL result = YES;
302 if (unzLocateFile(uf, filename, 1) != UNZ_OK)
303 {
304 result = NO;
305 }
306 else
307 {
308 int err = UNZ_OK;
309 unz_file_info64 file_info = {0};
310 err = unzGetCurrentFileInfo64(uf, &file_info, NULL, 0, NULL, 0, NULL, 0);
311 if (err != UNZ_OK)
312 {
313 result = NO;
314 }
315 else
316 {
317
318
319 }
320 }
321 unzClose(uf);
322 return result;
323}
324
325
326
327
328@end
329
330
#define OOLogERR(class, format,...)
Definition OOLogging.h:112
#define OOLog(class, format,...)
Definition OOLogging.h:88
NSDictionary * OODictionaryFromFile(NSString *path)
return nil
NSArray * oo_directoryContentsAtPath:(NSString *path)
const char * filename
Definition ioapi.h:133
int ZEXPORT unzLocateFile(unzFile file, const char *szFileName, int iCaseSensitivity)
Definition unzip.c:1238
int ZEXPORT unzGetCurrentFileInfo64(unzFile file, unz_file_info64 *pfile_info, char *szFileName, uLong fileNameBufferSize, void *extraField, uLong extraFieldBufferSize, char *szComment, uLong commentBufferSize)
Definition unzip.c:1130
unzFile ZEXPORT unzOpen64(const void *path)
Definition unzip.c:801
int ZEXPORT unzClose(unzFile file)
Definition unzip.c:811
struct unz_file_info64_s unz_file_info64
voidp unzFile
Definition unzip.h:70
#define UNZ_OK
Definition unzip.h:74