1 mike 1.1 //BEGIN_LICENSE
2 //
3 // Copyright (c) 2000 The Open Group, BMC Software, Tivoli Systems, IBM
4 //
5 // Permission is hereby granted, free of charge, to any person obtaining a
6 // copy of this software and associated documentation files (the "Software"),
7 // to deal in the Software without restriction, including without limitation
8 // the rights to use, copy, modify, merge, publish, distribute, sublicense,
9 // and/or sell copies of the Software, and to permit persons to whom the
10 // Software is furnished to do so, subject to the following conditions:
11 //
12 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
13 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
14 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
15 // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
16 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
17 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
18 // DEALINGS IN THE SOFTWARE.
19 //
20 //END_LICENSE
21 //BEGIN_HISTORY
22 mike 1.1 //
23 // Author:
24 //
|
25 mike 1.2 // $Log: FileSystem.cpp,v $
|
26 karl 1.10 // Revision 1.9 2001/04/08 19:56:38 karl
27 // Test version
28 //
|
29 karl 1.9 // Revision 1.8 2001/04/08 19:20:04 mike
30 // more TCP work
31 //
|
32 mike 1.8 // Revision 1.7 2001/04/08 01:13:21 mike
33 // Changed "ConstCIM" to "CIMConst"
34 //
|
35 karl 1.6 // Revision 1.5 2001/03/11 23:35:32 mike
36 // Ports to Linux
37 //
|
38 mike 1.4 // Revision 1.3 2001/02/13 02:06:40 mike
39 // Added renameFile() method.
40 //
|
41 mike 1.3 // Revision 1.2 2001/02/11 05:42:33 mike
42 // new
43 //
|
44 mike 1.2 // Revision 1.1.1.1 2001/01/14 19:51:35 mike
45 // Pegasus import
46 //
|
47 mike 1.1 //
48 //END_HISTORY
49
50 #include <Pegasus/Common/Config.h>
51
52 #ifdef PEGASUS_OS_TYPE_WINDOWS
53 # include <io.h>
54 # include <direct.h>
55 #else
56 # include <unistd.h>
57 # include <dirent.h>
58 #endif
59
60 #include <sys/stat.h>
61 #include <sys/types.h>
62 #include <cstdio>
63 #include "Destroyer.h"
64 #include "FileSystem.h"
|
65 mike 1.2 #include "Dir.h"
|
66 karl 1.6 //DEBUG ONLY
67 #include <iostream.h>
|
68 mike 1.1
69 // ATTN-B: porting!
70
71 PEGASUS_NAMESPACE_BEGIN
72
73 #ifdef PEGASUS_OS_TYPE_WINDOWS
74 static const int ACCESS_EXISTS = 0;
75 static const int ACCESS_WRITE = 2;
76 static const int ACCESS_READ = 4;
77 static const int ACCESS_READ_AND_WRITE = 6;
78 #endif
79
|
80 karl 1.6 /** Clone the path as a C String but discard
81 trailing slash if any:
82 */
|
83 mike 1.1 static char* _clonePath(const String& path)
84 {
85 char* p = path.allocateCString();
86
87 if (!*p)
88 return p;
89
90 char* last = p + path.getLength() - 1;
91
92 if (*last == '/')
93 *last = '\0';
94
95 return p;
96 }
97
98 Boolean FileSystem::exists(const String& path)
99 {
|
100 mike 1.5 ArrayDestroyer<char> p(_clonePath(path));
|
101 mike 1.1
102 #ifdef PEGASUS_OS_TYPE_WINDOWS
103 return _access(p.getPointer(), ACCESS_EXISTS) == 0;
104 #else
105 return access(p.getPointer(), F_OK) == 0;
106 #endif
107 }
108
|
109 karl 1.6 Boolean FileSystem::getCurrentDirectory(String& path)
110 {
111 #ifdef PEGASUS_OS_TYPE_WINDOWS
112 char* tmp = _getcwd(NULL, 0);
113
114 if (!tmp)
115 return false;
116
117 path.append(tmp);
118 delete [] tmp;
119 #else
120 char tmp[4096];
121
122 getcwd(tmp, sizeof(tmp));
123 path.append(tmp);
124 #endif
125 return true;
126 }
127
|
128 mike 1.2 Boolean FileSystem::existsIgnoreCase(const String& path, String& realPath)
129 {
130 realPath.clear();
|
131 mike 1.5 ArrayDestroyer<char> destroyer(_clonePath(path));
|
132 mike 1.2 char* p = destroyer.getPointer();
133
134 char* dirPath;
135 char* fileName;
136 char* slash = strrchr(p, '/');
137
138 if (slash)
139 {
140 *slash = '\0';
141 fileName = slash + 1;
142 dirPath = p;
143 if (*fileName == '\0')
144 return false;
145 }
146 else
147 {
148 fileName = p;
149 dirPath = ".";
150 }
151
152 for (Dir dir(dirPath); dir.more(); dir.next())
153 mike 1.2 {
154 #ifdef PEGASUS_OS_TYPE_WINDOWS
155 if (stricmp(fileName, dir.getName()) == 0)
156 #else
157 if (strcasecmp(fileName, dir.getName()) == 0)
158 #endif
159 {
160 if (strcmp(dirPath, ".") == 0)
161 realPath = dir.getName();
162 else
163 {
164 realPath = dirPath;
165 realPath += '/';
166 realPath += dir.getName();
167 }
168 return true;
169 }
170 }
171
172 return false;
173 }
174 mike 1.2
|
175 mike 1.1 Boolean FileSystem::canRead(const String& path)
176 {
|
177 mike 1.5 ArrayDestroyer<char> p(_clonePath(path));
|
178 mike 1.1
179 #ifdef PEGASUS_OS_TYPE_WINDOWS
180 return _access(p.getPointer(), ACCESS_READ) == 0;
181 #else
182 return access(p.getPointer(), R_OK) == 0;
183 #endif
184 }
185
186 Boolean FileSystem::canWrite(const String& path)
187 {
|
188 mike 1.5 ArrayDestroyer<char> p(_clonePath(path));
|
189 mike 1.1
190 #ifdef PEGASUS_OS_TYPE_WINDOWS
191 return _access(p.getPointer(), ACCESS_WRITE) == 0;
192 #else
193 return access(p.getPointer(), W_OK) == 0;
194 #endif
195 }
196
197 #if 0
198 // ATTN: not implemented for NT. But not used by Pegasus.
199 Boolean FileSystem::canExecute(const String& path)
200 {
|
201 mike 1.5 ArrayDestroyer<char> p(_clonePath(path));
|
202 mike 1.1 return access(p.getPointer(), X_OK) == 0;
203 }
204 #endif
205
206 Boolean FileSystem::isDirectory(const String& path)
207 {
|
208 mike 1.5 ArrayDestroyer<char> p(_clonePath(path));
|
209 mike 1.1
210 struct stat st;
211
212 #ifdef PEGASUS_OS_TYPE_WINDOWS
213
214 if (stat(p.getPointer(), &st) != 0)
215 return false;
216
217 Boolean result = (st.st_mode & _S_IFDIR) != 0;
218 return result;
219
220 #else
221
222 if (stat(p.getPointer(), &st) != 0)
223 return false;
224
225 Boolean result = S_ISDIR(st.st_mode);
226 return result;
227
228 #endif
229 }
230 mike 1.1
231 Boolean FileSystem::changeDirectory(const String& path)
232 {
|
233 mike 1.5 ArrayDestroyer<char> p(_clonePath(path));
|
234 mike 1.1 return chdir(p.getPointer()) == 0;
235 }
236
237 Boolean FileSystem::makeDirectory(const String& path)
238 {
|
239 mike 1.5 ArrayDestroyer<char> p(_clonePath(path));
|
240 mike 1.1 #ifdef PEGASUS_OS_TYPE_WINDOWS
241 return _mkdir(p.getPointer()) == 0;
242 #else
243 return mkdir(p.getPointer(), 0777) == 0;
244 #endif
245 }
246
247 Boolean FileSystem::getFileSize(const String& path, Uint32& size)
248 {
249 struct stat st;
250
|
251 mike 1.5 ArrayDestroyer<char> p(_clonePath(path));
|
252 mike 1.1
253 if (stat(p.getPointer(), &st) != 0)
254 return false;
255
256 size = st.st_size;
257 return true;
258 }
259
260 Boolean FileSystem::removeDirectory(const String& path)
261 {
|
262 mike 1.5 ArrayDestroyer<char> p(_clonePath(path));
|
263 mike 1.1 return rmdir(p.getPointer()) == 0;
264 }
265
|
266 karl 1.6 Boolean FileSystem::removeDirectoryHier(const String& path)
267 {
|
268 karl 1.10 String saveCwd;
269 FileSystem::getCurrentDirectory(saveCwd);
|
270 karl 1.6
|
271 mike 1.7 Array<String> fileList;
|
272 karl 1.6
273 if (!FileSystem::getDirectoryContents(path,fileList))
274 return false;
275
|
276 karl 1.10 FileSystem::changeDirectory(path);
|
277 karl 1.6
278 // for files-in-directory, delete or recall removedir
279 // Do not yet test for boolean returns on the removes
280 for (Uint32 i = 0, n = fileList.getSize(); i < n; i++)
|
281 karl 1.10 {
282 // ATTN: Debug code here
|
283 karl 1.9 ArrayDestroyer<char> q(_clonePath(fileList[i]));
|
284 karl 1.10
|
285 karl 1.9 if (FileSystem::isDirectory(fileList[i])){
|
286 karl 1.6 FileSystem::removeDirectoryHier(fileList[i]);
287 }
288
|
289 karl 1.9 else{
|
290 karl 1.10 // ATTN: Mike the second is the problem.
|
291 karl 1.9 cout << "DEBUG RMFIL " << q.getPointer() <<endl;
|
292 karl 1.10 cout << "DEBUG RMFIL " << fileList[i] <<endl;
293 removeFile(fileList[i]);
|
294 karl 1.6 }
295 }
|
296 mike 1.8
|
297 karl 1.10 FileSystem::changeDirectory(saveCwd);
|
298 karl 1.6 return removeDirectory(path);
299 }
300
|
301 mike 1.1 Boolean FileSystem::removeFile(const String& path)
302 {
|
303 mike 1.5 ArrayDestroyer<char> p(_clonePath(path));
|
304 mike 1.1 return unlink(p.getPointer()) == 0;
305 }
306
307 void FileSystem::loadFileToMemory(
308 Array<Sint8>& array,
309 const String& fileName)
310 {
311 Uint32 fileSize;
312
313 if (!getFileSize(fileName, fileSize))
314 throw CannotOpenFile(fileName);
315
316 char* tmp = fileName.allocateCString();
317 FILE* fp = fopen(tmp, "rb");
318 delete [] tmp;
319
320 if (fp == NULL)
321 throw CannotOpenFile(fileName);
322
323 array.reserve(fileSize);
324 char buffer[4096];
325 mike 1.1 size_t n;
326
327 while ((n = fread(buffer, 1, sizeof(buffer), fp)) > 0)
328 array.append(buffer, n);
329
330 fclose(fp);
331 }
332
333 Boolean FileSystem::compare(
334 const String& fileName1,
335 const String& fileName2)
336 {
337 Uint32 fileSize1;
338
339 if (!getFileSize(fileName1, fileSize1))
340 throw CannotOpenFile(fileName1);
341
342 Uint32 fileSize2;
343
344 if (!getFileSize(fileName2, fileSize2))
345 throw CannotOpenFile(fileName2);
346 mike 1.1
347 if (fileSize1 != fileSize2)
348 return false;
349
350 char* tmp1 = fileName1.allocateCString();
351 FILE* fp1 = fopen(tmp1, "rb");
352 delete [] tmp1;
353
354 if (fp1 == NULL)
355 throw CannotOpenFile(fileName1);
356
357 char* tmp2 = fileName2.allocateCString();
358 FILE* fp2 = fopen(tmp2, "rb");
359 delete [] tmp2;
360
361 if (fp2 == NULL)
362 {
363 fclose(fp1);
364 throw CannotOpenFile(fileName2);
365 }
366
367 mike 1.1 int c1;
368 int c2;
369
370 while ((c1 = fgetc(fp1)) != EOF && (c2 = fgetc(fp2)) != EOF)
371 {
372 if (c1 != c2)
373 {
374 fclose(fp1);
375 fclose(fp2);
376 return false;
377 }
378 }
379
380 fclose(fp1);
381 fclose(fp2);
382 return true;
383 }
|
384 karl 1.6 /* Get the file list in the directory into the
385 array of strings provided
386 @return The function should return false under these circumstances:
|
387 mike 1.1
|
388 karl 1.6
389 1. The directory does not exist.
390 2. The file exists but is not a directory.
391 3. The directory is inaccessible.
392
393 */
|
394 mike 1.1 Boolean FileSystem::getDirectoryContents(
395 const String& path,
396 Array<String>& paths)
397 {
|
398 karl 1.6 // This may be just extra fluff but added anyway
399 if (!FileSystem::isDirectory(path))
400 return false;
401
|
402 mike 1.1 paths.clear();
|
403 karl 1.6 try
404 {
405 for (Dir dir(path); dir.more(); dir.next())
406 {
407 String name = dir.getName();
408 if (String::equal(name, ".") || String::equal(name, ".."))
409 continue;
410 paths.append(name);
411 }
412 return true;
413 }
|
414 mike 1.1
|
415 karl 1.6 // Catch the Dir exception
416 catch(CannotOpenDirectory&)
|
417 mike 1.1 {
|
418 karl 1.6 return false;
|
419 mike 1.1 }
420
|
421 mike 1.3 }
422
423 Boolean FileSystem::renameFile(
424 const String& oldFileName,
425 const String& newFileName)
426 {
|
427 mike 1.5 ArrayDestroyer<char> p(oldFileName.allocateCString());
428 ArrayDestroyer<char> q(newFileName.allocateCString());
|
429 mike 1.3
430 #ifdef PEGASUS_OS_TYPE_WINDOWS
431 return rename(p.getPointer(), q.getPointer()) == 0;
432 #else
|
433 mike 1.5 if (link(p.getPointer(), q.getPointer()) != 0)
434 return false;
435
436 return unlink(p.getPointer()) == 0;
|
437 mike 1.3 #endif
|
438 mike 1.1 }
439
440 PEGASUS_NAMESPACE_END
|