1 karl 1.39 //%2006////////////////////////////////////////////////////////////////////////
|
2 mike 1.15 //
|
3 karl 1.34 // Copyright (c) 2000, 2001, 2002 BMC Software; Hewlett-Packard Development
4 // Company, L.P.; IBM Corp.; The Open Group; Tivoli Systems.
5 // Copyright (c) 2003 BMC Software; Hewlett-Packard Development Company, L.P.;
|
6 karl 1.30 // IBM Corp.; EMC Corporation, The Open Group.
|
7 karl 1.34 // Copyright (c) 2004 BMC Software; Hewlett-Packard Development Company, L.P.;
8 // IBM Corp.; EMC Corporation; VERITAS Software Corporation; The Open Group.
|
9 karl 1.36 // Copyright (c) 2005 Hewlett-Packard Development Company, L.P.; IBM Corp.;
10 // EMC Corporation; VERITAS Software Corporation; The Open Group.
|
11 karl 1.39 // Copyright (c) 2006 Hewlett-Packard Development Company, L.P.; IBM Corp.;
12 // EMC Corporation; Symantec Corporation; The Open Group.
|
13 mike 1.15 //
14 // Permission is hereby granted, free of charge, to any person obtaining a copy
|
15 mike 1.16 // of this software and associated documentation files (the "Software"), to
16 // deal in the Software without restriction, including without limitation the
17 // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
18 mike 1.15 // sell copies of the Software, and to permit persons to whom the Software is
19 // furnished to do so, subject to the following conditions:
|
20 kumpf 1.19 //
|
21 mike 1.16 // THE ABOVE COPYRIGHT NOTICE AND THIS PERMISSION NOTICE SHALL BE INCLUDED IN
|
22 mike 1.15 // ALL COPIES OR SUBSTANTIAL PORTIONS OF THE SOFTWARE. THE SOFTWARE IS PROVIDED
23 // "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
|
24 mike 1.16 // LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
25 // PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
26 // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
27 mike 1.15 // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
28 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
29 //
30 //==============================================================================
31 //
32 //%/////////////////////////////////////////////////////////////////////////////
33
34 #ifndef Pegasus_FileSystem_h
35 #define Pegasus_FileSystem_h
36
37 #include <Pegasus/Common/Config.h>
38 #include <Pegasus/Common/String.h>
|
39 kumpf 1.23 #include <Pegasus/Common/ArrayInternal.h>
|
40 kumpf 1.22 #include <Pegasus/Common/InternalException.h>
|
41 kumpf 1.26 #include <Pegasus/Common/System.h>
|
42 kumpf 1.21 #include <Pegasus/Common/Linkage.h>
|
43 mike 1.16 #include <fstream>
|
44 david 1.27 #include <cstdio>
45 #if defined(PEGASUS_OS_OS400)
|
46 mike 1.40 #include "EBCDIC_OS400.h"
|
47 david 1.27 #endif
|
48 mike 1.37 #include <Pegasus/Common/Buffer.h>
|
49 mike 1.15
50 PEGASUS_NAMESPACE_BEGIN
51
52 /** The FileSystem class provides methods for manipulating the file system.
53
54 This class provides an methods for:
55 <ul>
|
56 kumpf 1.42 <li>Manipulating directories (create, remove, change).</li>
57 <li>Checking files for ability to read and write.</li>
58 <li>Removing files.</li>
59 <li>Comparing files.</li>
60 <li>Loading files into memory.</li>
|
61 mike 1.15 </ul>
62
|
63 mike 1.16 The methods of this class are all static. So there is no need to
|
64 mike 1.15 instantiate this class to use it. In fact, instantiation is precluded
65 by a private default constructor.
66
67 A word about the "NoCase" extensions. Some methods of this class have
68 a "NoCase" version. For example, there is a canRead() and a canReadNoCase().
69 The "NoCase" variation ignores the case of the file while it is being
70 located. For example, suppose there is a file called "File1". Then
71 canReadNoCase("file1") finds the file called "File1" and returns true (of
72 course there is a possibility that there really is a file called "file1"
|
73 mike 1.16 in the same directory in which case the behavior of this method is
74 undefined). Notice that Windows does this anyway. These methods were
|
75 mike 1.15 developed primarily for Unix which is case sensitive with respect to file
76 names. It should be noted that the no-case methods are slower (since they
77 must stat the directory and look at the file names).
78
79 The no-case variations are used by the repository which--according to
|
80 mike 1.16 CIM--must treat two classes names with different case characterisits, but
|
81 mike 1.15 othererwise similar, as identical. For example, "MyClass", "myclass", and
82 "MYCLASS" all refer to the same class. Since the default repository
83 implementation uses disk file names to represent class names (e.g., there
84 may be a file called "MyClass.#) that there must be a way of opening
85 a file without regard to its case.
86 */
87 class PEGASUS_COMMON_LINKAGE FileSystem
88 {
89 public:
90
91 /** Determines whether file exists.
|
92 kumpf 1.42 @param path path of the file.
93 @return true if the file exists.
|
94 mike 1.15 */
95 static Boolean exists(const String& path);
96
97 /** Determine whether the file exists. Ignores case of the file.
|
98 kumpf 1.42 @param path path of the file.
99 @param pathOut path of the file with actual case.
100 @return true if the file exists; false otherwise.
|
101 mike 1.15 */
102 static Boolean existsNoCase(const String& path, String& pathOut);
103
104 /** Determine whether the file exists. Ignores the case of the file.
|
105 kumpf 1.42 @param path path of the file.
106 @return true if the file exists; false otherwise.
|
107 mike 1.15 */
108 static Boolean existsNoCase(const String& path);
109
110 /** Determines whether the file can be read.
|
111 kumpf 1.42 @param path path of the file.
112 @return true if the file can be read.
|
113 mike 1.15 */
114 static Boolean canRead(const String& path);
115
116 /** Determines whether the file can be read. Ignores case of file.
|
117 kumpf 1.42 @param path path of the file.
118 @return true if the file can be read.
|
119 mike 1.15 */
120 static Boolean canReadNoCase(const String& path);
121
122 /** Determines whether the file can be written.
|
123 kumpf 1.42 @param path path of the file.
124 @return true if the file can be written.
|
125 mike 1.15 */
126 static Boolean canWrite(const String& path);
127
128 /** Determines whether the file can be written. Ignores case of file.
|
129 kumpf 1.42 @param path path of the file.
130 @return true if the file can be written.
|
131 mike 1.15 */
132 static Boolean canWriteNoCase(const String& path);
133
134 /** Get the size of the file in bytes.
|
135 kumpf 1.42 @param path path of file.
136 @param size set to size of file.
137 @return true on success.
|
138 mike 1.15 */
139 static Boolean getFileSize(const String& path, Uint32& size);
140
141 /** Get the size of the file in bytes.
|
142 kumpf 1.42 @param path path of file.
143 @param size set to size of file.
144 @return true on success.
|
145 mike 1.15 */
146 static Boolean getFileSizeNoCase(const String& path, Uint32& size);
147
148 /** Removes a file.
|
149 kumpf 1.42 @param path of file to be removed.
150 @return true on sucess.
|
151 mike 1.15 */
152 static Boolean removeFile(const String& path);
153
154 /** Removes a file. Ignores case of file.
|
155 kumpf 1.42 @param path of file to be removed.
156 @return true on sucess.
|
157 mike 1.15 */
158 static Boolean removeFileNoCase(const String& path);
159
160 /** Loads contents of the file into the array. Note that the file is
|
161 kumpf 1.42 opened using binary mode (newline sequences are not expanded to
162 carriage-return-line-feed sequences on Windows).
163 @param array set to the contents of the file upon return.
164 @param fileName name of file to be loaded.
165 @exception CannotOpenFile
|
166 mike 1.15 */
167 static void loadFileToMemory(
|
168 kumpf 1.42 Buffer& array,
169 const String& fileName);
|
170 mike 1.15
171 /** Determines whether two files have exactly the same content.
|
172 kumpf 1.42 @param path1 path of first file.
173 @param path2 path of second file.
174 @return true if files are identical.
175 @exception CannotOpenFile
|
176 mike 1.15 */
177 static Boolean compareFiles(
|
178 kumpf 1.42 const String& path1,
179 const String& path2);
|
180 mike 1.15
181 /** Renames a file.
|
182 kumpf 1.42 @param oldPath old name of file.
183 @param newPath new name of file.
184 @return true on success.
|
185 mike 1.15 */
186 static Boolean renameFile(
|
187 kumpf 1.42 const String& oldPath,
188 const String& newPath);
|
189 mike 1.15
|
190 mike 1.17 /** Same as rename file except that the case of the file referred to
|
191 kumpf 1.42 by oldPath is ignored.
|
192 mike 1.17 */
193 static Boolean renameFileNoCase(
|
194 kumpf 1.42 const String& oldPath,
195 const String& newPath);
|
196 mike 1.17
197 /** Copy a file.
|
198 kumpf 1.42 @param fromPath name of existing file.
199 @param toPath name of new file.
200 @return true on success.
|
201 mike 1.17 */
202 static Boolean copyFile(
|
203 kumpf 1.42 const String& fromPath,
204 const String& toPath);
|
205 mike 1.17
|
206 mike 1.15 /** Opens a file and ignores the case of the file. Note that the file
|
207 kumpf 1.42 will be opend in binary mode (no translation of carriage-return-line-
208 feed sequences on Windows).
209 @param os file stream to be opend.
210 @param path path of file to be opened.
211 @return true on success.
|
212 mike 1.15 */
|
213 mike 1.17 static Boolean openNoCase(PEGASUS_STD(ifstream)& is, const String& path);
214
215 /** Opens a file and ignores the case of the file. Note that the file
|
216 kumpf 1.42 open mode of the file must be passed in.
217 @param os file stream to be opend.
218 @param path path of file to be opened.
219 @param mode mode to open the file in.
220 @return true on success.
|
221 mike 1.17 */
222 static Boolean openNoCase(
|
223 kumpf 1.43 PEGASUS_STD(fstream)& fs,
224 const String& path,
|
225 kumpf 1.42 int mode);
|
226 mike 1.15
227 /** Determines whether the path refers to a directory.
|
228 kumpf 1.42 @param path path of the directory.
229 @return true if path refers to a directory.
|
230 mike 1.15 */
231 static Boolean isDirectory(const String& path);
232
233 /** Changes the current directory.
|
234 kumpf 1.42 @param path path of directory to be changed to.
235 @return true on success.
|
236 mike 1.15 */
237 static Boolean changeDirectory(const String& path);
238
|
239 mike 1.16 /** Creates a directory.
|
240 kumpf 1.42 @param path path of directory to be created.
241 @return true on success.
|
242 mike 1.15 */
243 static Boolean makeDirectory(const String& path);
244
|
245 mike 1.16 /** Get the path of the current working Directory.
|
246 kumpf 1.42 @param path set to current working directory upon return.
247 @return true on success (operation may fail if the current
248 working directory becomes stale; this can happen on
249 Unix if it is removed but is impossible on Windows
250 due to reference counting).
|
251 mike 1.15 */
252 static Boolean getCurrentDirectory(String& path);
253
254 /** Remove the given directory. The directory must be empty
|
255 kumpf 1.42 to be eligible for removal
256 @param String path is the relative or ablsolute path to
257 the directory to remove
258 @return true if directory removed
|
259 mike 1.15 */
260 static Boolean removeDirectory(const String& path);
261
262 /** Remove a directory and all files and directories under it.
|
263 kumpf 1.42 WARNING: This differs significantly from the <tt>removeDirectory</tt>
264 function in that it removes both directories and files and
265 removes a complete hiearchy. Use with caution.
266 @param path path of directory to be removed.
267 @return true on success.
|
268 mike 1.16 */
|
269 mike 1.15 static Boolean removeDirectoryHier(const String& path);
270
271 /** Gets names of all entries (files and directories) of a directory.
|
272 kumpf 1.42 Note that this function excludes the "." and ".." entries.
273 @param path path path of directory.
274 @param paths contains list of entry names upon return. Note that
275 the entry names only are provided (no path part).
276 @return true on success.
|
277 mike 1.15 */
278 static Boolean getDirectoryContents(
|
279 kumpf 1.42 const String& path,
280 Array<String>& paths);
|
281 mike 1.15
282 /** Determines whether the given directory is empty. A directory is
|
283 kumpf 1.42 empty if it contains no files or directories.
284 @param path path of directory.
285 @return true if directory is empty.
|
286 mike 1.15 */
287 static Boolean isDirectoryEmpty(const String& path);
288
|
289 mike 1.16 /** Translate backward slashes to forward slashes.
|
290 kumpf 1.42 @param path to be translated.
|
291 mike 1.15 */
292 static void translateSlashes(String& path);
293
|
294 kumpf 1.20 /** Get an absolute path from an absolute directory and a relative or
295 absolute file name. If the file name is fully specified, it is
296 returned unchanged. Otherwise, the specified directory is prepended
297 to the file name.
298 */
299 static String getAbsolutePath(const char* path, const String& filename);
300
|
301 tony 1.25 /** Return the just the filename to the file name into base.
302 */
303 static String extractFileName(const String& base);
304
305 /** Return the just the path to the file name into path.
306 */
307 static String extractFilePath(const String& path);
308
|
309 kumpf 1.31 /** Changes file permissions on the given file.
|
310 kumpf 1.42 @param path path of the file.
311 @param mode the bit-wise inclusive OR of the values for the
|
312 kumpf 1.31 desired permissions.
|
313 kumpf 1.42 @return true on success, false on error and errno is set appropriately.
|
314 kumpf 1.31 */
315 static Boolean changeFilePermissions(const String& path, mode_t mode);
316
|
317 konrad.r 1.32 /**
318 Return OS path specific delimiter.
|
319 kumpf 1.43
|
320 konrad.r 1.32 @return delimiter specific to the platform
321 */
322 static String getPathDelimiter();
323
324 /**
325 Returns the absolute pathname for the specified filename.
|
326 kumpf 1.43
|
327 konrad.r 1.32 @param paths directories seperated by an OS specific delimiter to search
328 @param filename filename to search for in the paths
329
330 @return the full absolute pathname to the found filename or an empty
331 string on failure.
332 */
|
333 kumpf 1.42 static String getAbsoluteFileName(
334 const String& paths,
335 const String& filename);
|
336 kumpf 1.43
|
337 kumpf 1.33 /**
338 Convert a library name to its corresponding file name by adding the
339 appropriate prefix and suffix.
340
341 @param libraryName The name of the library for which to build the file
342 name.
343 @return The file name corresponding to the specified library name.
344 */
345 static String buildLibraryFileName(const String &libraryName);
346
|
347 kumpf 1.42 static Boolean changeFileOwner(
348 const String& fileName,
349 const String& userName);
350
|
351 mateus.baur 1.47 /**
352 Flushes the data from the iostream buffers to the OS buffers and
353 then flushes the data from the OS buffers to the disk.
354
355 This will avoid the possible data loss in case of an OS crash when
356 OS filesystem commit directory-level changes immediately while
357 file-level changes remain cached (e.g. HP-UX).
358
359 @param fstream. The iostream that we want to flush data.
360 */
361 static void syncWithDirectoryUpdates(PEGASUS_STD(fstream)&);
362
|
363 mike 1.15 private:
364
365 FileSystem() { }
366 };
367
368 inline Boolean FileSystem::existsNoCase(const String& path)
369 {
370 String dummy;
371 return existsNoCase(path, dummy);
372 }
373
374 inline Boolean FileSystem::canReadNoCase(const String& path)
375 {
376 String realPath;
377
378 if (!existsNoCase(path, realPath))
|
379 kumpf 1.42 return false;
|
380 mike 1.15
381 return FileSystem::canRead(realPath);
382 }
383
384 inline Boolean FileSystem::canWriteNoCase(const String& path)
385 {
386 String realPath;
387
388 if (!existsNoCase(path, realPath))
|
389 kumpf 1.42 return false;
|
390 mike 1.15
391 return FileSystem::canWrite(realPath);
392 }
393
394 inline Boolean FileSystem::removeFileNoCase(const String& path)
395 {
396 String realPath;
397
398 if (!existsNoCase(path, realPath))
|
399 kumpf 1.42 return false;
|
400 mike 1.15
401 return FileSystem::removeFile(realPath);
|
402 mike 1.17 }
403
404 inline Boolean FileSystem::renameFileNoCase(
405 const String& oldPath,
406 const String& newPath)
407 {
408 String realPath;
409
410 if (!existsNoCase(oldPath, realPath))
|
411 kumpf 1.42 return false;
|
412 mike 1.17
413 return FileSystem::renameFile(realPath, newPath);
|
414 mike 1.15 }
415
416 inline Boolean FileSystem::getFileSizeNoCase(const String& path, Uint32& size)
417 {
418 String realPath;
419
420 if (!existsNoCase(path, realPath))
|
421 kumpf 1.42 return false;
|
422 mike 1.15
423 return FileSystem::getFileSize(realPath, size);
|
424 kumpf 1.20 }
425
426 inline String FileSystem::getAbsolutePath(
427 const char* path,
428 const String& filename)
429 {
430 String absolutePath;
431
432 if (filename != String::EMPTY)
433 {
|
434 kumpf 1.26 if (!System::is_absolute_path(filename.getCString()) && path && path[0])
|
435 kumpf 1.20 {
436 absolutePath.append(path);
437 absolutePath.append('/');
438 }
439 absolutePath.append(filename);
440 }
441 translateSlashes(absolutePath);
442
443 return absolutePath;
|
444 mike 1.15 }
445
|
446 kumpf 1.18 inline Boolean Open(PEGASUS_STD(ifstream)& is, const String& path)
447 {
|
448 david 1.28 #if defined(PEGASUS_OS_OS400)
|
449 david 1.29 is.open(path.getCString(), PEGASUS_STD(_CCSID_T(1208)));
|
450 david 1.27 #else
|
451 kumpf 1.24 is.open(path.getCString());
|
452 david 1.27 #endif
|
453 kumpf 1.18 return !!is;
454 }
455
456 inline Boolean Open(PEGASUS_STD(ofstream)& os, const String& path)
457 {
|
458 david 1.28 #if defined(PEGASUS_OS_OS400)
|
459 david 1.29 os.open(path.getCString(), PEGASUS_STD(_CCSID_T(1208)));
|
460 david 1.27 #else
|
461 kumpf 1.24 os.open(path.getCString());
|
462 david 1.27 #endif
|
463 kumpf 1.18 return !!os;
464 }
465
466 inline Boolean OpenAppend(PEGASUS_STD(ofstream)& os, const String& path)
467 {
|
468 david 1.28 #if defined(PEGASUS_OS_OS400)
|
469 kumpf 1.42 os.open(
470 path.getCString(), PEGASUS_STD(ios::app), PEGASUS_STD(_CCSID_T(1208)));
|
471 david 1.27 #else
|
472 kumpf 1.24 os.open(path.getCString(), PEGASUS_STD(ios::app));
|
473 david 1.27 #endif
|
474 kumpf 1.18 return !!os;
|
475 konrad.r 1.32 }
476
|
477 kumpf 1.43 inline String FileSystem::getPathDelimiter()
|
478 konrad.r 1.32 {
|
479 david.dillard 1.38 #if defined(PEGASUS_OS_TYPE_WINDOWS)
|
480 kumpf 1.42 return String(";");
|
481 konrad.r 1.32 #else
|
482 kumpf 1.42 return String(":");
|
483 konrad.r 1.32 #endif
|
484 kumpf 1.18 }
485
486 /** Get the next line from the input file.
487 */
488 PEGASUS_COMMON_LINKAGE Boolean GetLine(PEGASUS_STD(istream)& is, String& line);
489
|
490 mike 1.15 PEGASUS_NAMESPACE_END
491
492 #endif /* Pegasus_FileSystem_h */
|