1 martin 1.83 //%LICENSE////////////////////////////////////////////////////////////////
|
2 martin 1.84 //
|
3 martin 1.83 // Licensed to The Open Group (TOG) under one or more contributor license
4 // agreements. Refer to the OpenPegasusNOTICE.txt file distributed with
5 // this work for additional information regarding copyright ownership.
6 // Each contributor licenses this file to you under the OpenPegasus Open
7 // Source License; you may not use this file except in compliance with the
8 // License.
|
9 martin 1.84 //
|
10 martin 1.83 // Permission is hereby granted, free of charge, to any person obtaining a
11 // copy of this software and associated documentation files (the "Software"),
12 // to deal in the Software without restriction, including without limitation
13 // the rights to use, copy, modify, merge, publish, distribute, sublicense,
14 // and/or sell copies of the Software, and to permit persons to whom the
15 // Software is furnished to do so, subject to the following conditions:
|
16 martin 1.84 //
|
17 martin 1.83 // The above copyright notice and this permission notice shall be included
18 // in all copies or substantial portions of the Software.
|
19 martin 1.84 //
|
20 martin 1.83 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
21 martin 1.84 // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
22 martin 1.83 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
23 // IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
24 // CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
25 // TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
26 // SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
27 martin 1.84 //
|
28 martin 1.83 //////////////////////////////////////////////////////////////////////////
|
29 marek 1.61 //
30 //%/////////////////////////////////////////////////////////////////////////////
31
32 #include <iostream>
33 #include <Pegasus/Common/Config.h>
34 #include <Pegasus/Common/System.h>
35 #include <Pegasus/Common/AutoPtr.h>
|
36 mike 1.74 #include <Executor/Match.h>
|
37 marek 1.61 #include "FileSystem.h"
38 #include "Dir.h"
|
39 msolomon 1.64 #ifndef PEGASUS_OS_TYPE_WINDOWS
40 #include <pwd.h>
41 #endif
42 #include <Pegasus/Common/Tracer.h>
|
43 karl 1.85.8.1
|
44 marek 1.61 PEGASUS_NAMESPACE_BEGIN
45
46 // Clone the path as a C String but discard trailing slash if any:
47
48 static CString _clonePath(const String& path)
49 {
50 String clone = path;
51
52 if (clone.size() && clone[clone.size()-1] == '/')
53 clone.remove(clone.size()-1);
54
55 return clone.getCString();
56 }
57
58 Boolean FileSystem::exists(const String& path)
59 {
60 return System::exists(_clonePath(path));
61 }
62
63 Boolean FileSystem::getCurrentDirectory(String& path)
64 {
65 marek 1.61 path.clear();
66 char tmp[4096];
67
68 if (!System::getCurrentDirectory(tmp, sizeof(tmp) - 1))
69 return false;
70
71 path.append(tmp);
72 return true;
73 }
74
75 Boolean FileSystem::existsNoCase(const String& path, String& realPath)
76 {
|
77 kumpf 1.80 #if !defined(PEGASUS_OS_VMS) && \
78 !defined(PEGASUS_OS_TYPE_WINDOWS) && \
79 !defined(PEGASUS_OS_DARWIN)
|
80 mike 1.75
|
81 mike 1.74 // If a file exists that has the same case as the path parmater,
82 // then we can bypass the expensive directory scanning below.
83
84 if (FileSystem::exists(path))
85 {
86 realPath = path;
87 return true;
88 }
89
|
90 mike 1.75 #endif
|
91 mike 1.74
|
92 marek 1.61 realPath.clear();
93 CString cpath = _clonePath(path);
94 const char* p = cpath;
95
96 const char* dirPath;
97 const char* fileName;
98 char* slash = (char *) strrchr(p, '/');
99
100 if (slash)
101 {
102 *slash = '\0';
103 fileName = slash + 1;
104 dirPath = p;
105
106 if (*fileName == '\0')
107 return false;
108 }
109 else
110 {
111 fileName = p;
112 dirPath = ".";
113 marek 1.61 }
114
115
116 for (Dir dir(dirPath); dir.more(); dir.next())
117 {
118 if (System::strcasecmp(fileName, dir.getName()) == 0)
119 {
120 if (strcmp(dirPath, ".") == 0)
121 realPath = dir.getName();
122 else
123 {
124 realPath = dirPath;
125 realPath.append('/');
126 realPath.append(dir.getName());
127 }
128 return true;
129 }
130 }
131
132 return false;
133 }
134 marek 1.61
135 Boolean FileSystem::canRead(const String& path)
136 {
137 return System::canRead(_clonePath(path));
138 }
139
140 Boolean FileSystem::canWrite(const String& path)
141 {
142 return System::canWrite(_clonePath(path));
143 }
144
145 Boolean FileSystem::getFileSize(const String& path, Uint32& size)
146 {
147 return System::getFileSize(_clonePath(path), size);
148 }
149
150 Boolean FileSystem::removeFile(const String& path)
151 {
152 return System::removeFile(_clonePath(path));
153 }
154
155 marek 1.61 void FileSystem::loadFileToMemory(
156 Buffer& array,
157 const String& fileName)
158 {
159 Uint32 fileSize;
160
161 if (!getFileSize(fileName, fileSize))
162 throw CannotOpenFile(fileName);
163
164 FILE* fp = fopen(fileName.getCString(), "rb");
165
166 if (fp == NULL)
167 throw CannotOpenFile(fileName);
168
169 array.reserveCapacity(fileSize);
170 char buffer[4096];
171 size_t n;
172
173 while ((n = fread(buffer, 1, sizeof(buffer), fp)) > 0)
174 array.append(buffer, static_cast<Uint32>(n));
175
176 marek 1.61 fclose(fp);
177 }
178
179 Boolean FileSystem::compareFiles(
180 const String& path1,
181 const String& path2)
182 {
183 Uint32 fileSize1;
184
185 if (!getFileSize(path1, fileSize1))
186 throw CannotOpenFile(path1);
187
188 Uint32 fileSize2;
189
190 if (!getFileSize(path2, fileSize2))
191 throw CannotOpenFile(path2);
192
193 if (fileSize1 != fileSize2)
194 return false;
195
196 FILE* fp1 = fopen(path1.getCString(), "rb");
197 marek 1.61
198 if (fp1 == NULL)
199 throw CannotOpenFile(path1);
200
201 FILE* fp2 = fopen(path2.getCString(), "rb");
202
203 if (fp2 == NULL)
204 {
205 fclose(fp1);
206 throw CannotOpenFile(path2);
207 }
208
209 int c1;
210 int c2;
211
212 while ((c1 = fgetc(fp1)) != EOF && (c2 = fgetc(fp2)) != EOF)
213 {
214 if (c1 != c2)
215 {
216 fclose(fp1);
217 fclose(fp2);
218 marek 1.61 return false;
219 }
220 }
221
222 fclose(fp1);
223 fclose(fp2);
224 return true;
225 }
226
227 Boolean FileSystem::renameFile(
228 const String& oldPath,
229 const String& newPath)
230 {
231 return System::renameFile(oldPath.getCString(), newPath.getCString());
232 }
233
234 Boolean FileSystem::copyFile(
235 const String& fromPath,
236 const String& toPath)
237 {
238 return System::copyFile(fromPath.getCString(), toPath.getCString());
239 marek 1.61 }
240
241 Boolean FileSystem::openNoCase(PEGASUS_STD(ifstream)& is, const String& path)
242 {
243 String realPath;
244
245 if (!existsNoCase(path, realPath))
246 return false;
247
248 is.open(_clonePath(realPath) PEGASUS_IOS_BINARY);
249
250 return !!is;
251 }
252
253 Boolean FileSystem::openNoCase(
|
254 kumpf 1.66 PEGASUS_STD(fstream)& fs,
|
255 marek 1.61 const String& path,
256 int mode)
257 {
258 String realPath;
259
260 if (!existsNoCase(path, realPath))
261 return false;
262 #if defined(__GNUC__) && GCC_VERSION >= 30200
263 fs.open(_clonePath(realPath), PEGASUS_STD(ios_base::openmode)(mode));
264 #else
265 fs.open(_clonePath(realPath), mode);
266 #endif
267 return !!fs;
268 }
269
270 Boolean FileSystem::isDirectory(const String& path)
271 {
272 return System::isDirectory(_clonePath(path));
273 }
274
275 Boolean FileSystem::changeDirectory(const String& path)
276 marek 1.61 {
277 return System::changeDirectory(_clonePath(path));
278 }
279
280 Boolean FileSystem::makeDirectory(const String& path)
281 {
282 return System::makeDirectory(_clonePath(path));
283 }
284
285 Boolean FileSystem::removeDirectory(const String& path)
286 {
287 return System::removeDirectory(_clonePath(path));
288 }
289
290 Boolean FileSystem::removeDirectoryHier(const String& path)
291 {
292 Array<String> fileList;
293
294 // Get contents of current directory
295
296 if (!FileSystem::getDirectoryContents(path,fileList))
297 marek 1.61 return false;
298
299 // for files-in-directory, delete or recall removedir
300
301 for (Uint32 i = 0, n = fileList.size(); i < n; i++)
|
302 kumpf 1.66 {
|
303 marek 1.61 String newPath = path; // extend path to subdir
304 newPath.append("/");
305 newPath.append(fileList[i]);
|
306 kumpf 1.66
|
307 marek 1.61 if (FileSystem::isDirectory(newPath))
308 {
309 // Recall ourselves with extended path
310 if (!FileSystem::removeDirectoryHier(newPath))
|
311 kumpf 1.66 return false;
|
312 marek 1.61 }
313
314 else
315 {
316 if (!FileSystem::removeFile(newPath))
317 return false;
318 }
319 }
320
|
321 kumpf 1.66 return removeDirectory(path);
|
322 marek 1.61 }
323
324 //
325 // Get the file list in the directory into the
326 // array of strings provided
327 // @return The function should return false under these circumstances:
328 //
329 //
330 // 1. The directory does not exist.
331 // 2. The file exists but is not a directory.
332 // 3. The directory is inaccessible.
333 //
334 //
335 Boolean FileSystem::getDirectoryContents(
336 const String& path,
337 Array<String>& paths)
338 {
339 paths.clear();
340
341 try
|
342 kumpf 1.66 {
|
343 marek 1.61 for (Dir dir(path); dir.more(); dir.next())
344 {
345 String name = dir.getName();
346
347 if (String::equal(name, ".") || String::equal(name, ".."))
348 continue;
349
350 paths.append(name);
351 }
352 return true;
353 }
354
355 // Catch the Dir exception
|
356 kumpf 1.66 catch (CannotOpenDirectory&)
|
357 marek 1.61 {
358 return false;
359 }
360 }
361
362 Boolean FileSystem::isDirectoryEmpty(const String& path)
363 {
364 for (Dir dir(path); dir.more(); dir.next())
365 {
366 const char* name = dir.getName();
367
368 if (strcmp(name, ".") != 0 && strcmp(name, "..") != 0)
369 return false;
370 }
371
372 return true;
373 }
374
375 void FileSystem::translateSlashes(String& path)
376 {
377 for (Uint32 i = 0; i < path.size(); i++)
378 marek 1.61 {
379 if (path[i] == '\\')
380 path[i] = '/';
381 }
382 }
383
384 // Return the just the base name from the path.
|
385 kumpf 1.65 String FileSystem::extractFileName(const String& path)
|
386 marek 1.61 {
|
387 kumpf 1.65 AutoArrayPtr<char> p_path(new char[path.size() + 1]);
388 String basename = System::extract_file_name(
389 (const char*)path.getCString(), p_path.get());
|
390 kumpf 1.66
|
391 kumpf 1.65 return basename;
|
392 marek 1.61 }
393
394 // Return just the path to the file or directory into path
395 String FileSystem::extractFilePath(const String& path)
396 {
|
397 kumpf 1.65 AutoArrayPtr<char> p_path(new char[path.size() + 1]);
398 String newpath = System::extract_file_path(
399 (const char*)path.getCString(), p_path.get());
|
400 kumpf 1.66
|
401 kumpf 1.65 return newpath;
|
402 marek 1.61 }
403
404 // Changes file permissions on the given file.
405 Boolean FileSystem::changeFilePermissions(const String& path, mode_t mode)
406 {
407 CString tempPath = path.getCString();
408
409 return System::changeFilePermissions(tempPath, mode);
410 }
411
|
412 kumpf 1.65 String FileSystem::getAbsoluteFileName(
413 const String& paths,
414 const String& filename)
415 {
416 Uint32 pos = 0;
417 Uint32 token = 0;
418 String path;
419 String root;
420 String tempPath = paths;
|
421 marek 1.61
|
422 kumpf 1.65 do
423 {
424 if ((pos = tempPath.find(FileSystem::getPathDelimiter())) ==
425 PEG_NOT_FOUND)
426 {
427 pos = tempPath.size();
428 token = 0;
|
429 marek 1.61 }
|
430 kumpf 1.65 else
431 {
432 token = 1;
|
433 marek 1.61 }
434 path = tempPath.subString(0, pos);
435 tempPath.remove(0,pos+token);
|
436 kumpf 1.65 if (FileSystem::exists(path + "/" + filename) == true)
437 {
438 root = path + "/" + filename;
439 break;
440 }
441 else
442 {
443 // cout << "File does not exist.\n";
444 }
445 } while (tempPath.size() > 0);
|
446 marek 1.61
|
447 kumpf 1.65 return root;
|
448 marek 1.61 }
449
|
450 karl 1.85.8.2
|
451 marek 1.61 String FileSystem::buildLibraryFileName(const String &libraryName)
452 {
453 String fileName;
454
455 //
456 // Add the necessary prefix and suffix to convert the library name to its
457 // corresponding file name.
458 //
|
459 david.dillard 1.62 #if defined(PEGASUS_OS_TYPE_WINDOWS)
|
460 marek 1.61 fileName = libraryName + String(".dll");
|
461 b.whiteley 1.76 #else
462 fileName = String("lib") + libraryName + getDynamicLibraryExtension();
463 #endif
464 return fileName;
465 }
466
467 String FileSystem::getDynamicLibraryExtension()
468 {
469 #if defined(PEGASUS_OS_TYPE_WINDOWS)
470 return String(".dll");
|
471 karl 1.85.8.1 #elif defined(PEGASUS_PLATFORM_HPUX_PARISC_ACC) || \
472 defined (PEGASUS_PLATFORM_HPUX_PARISC_GNU)
|
473 b.whiteley 1.76 return String(".sl");
|
474 marek 1.61 #elif defined(PEGASUS_OS_DARWIN)
|
475 b.whiteley 1.76 return String(".dylib");
|
476 marek 1.61 #elif defined(PEGASUS_OS_VMS)
|
477 b.whiteley 1.76 return String(".exe");
|
478 r.kieninger 1.79 #elif defined(PEGASUS_PLATFORM_ZOS_ZSERIES64_IBM)
479 return String("64.so");
|
480 marek 1.61 #else
|
481 b.whiteley 1.76 return String(".so");
|
482 marek 1.61 #endif
483 }
484
|
485 kumpf 1.81 Boolean GetLine(PEGASUS_STD(istream)& is, Buffer& line)
|
486 marek 1.61 {
|
487 kumpf 1.81 const Uint32 buffersize = 1024;
488 Uint32 gcount = 0;
489
|
490 marek 1.61 line.clear();
491
|
492 kumpf 1.81 // Read the input line in chunks. A non-full buffer indicates the end of
493 // the line has been reached.
494 do
495 {
496 char input[buffersize];
|
497 marek 1.61
|
498 kumpf 1.81 // This reads up to buffersize-1 char, but stops before consuming
499 // a newline character ('\n').
500 is.get(input, buffersize);
|
501 marek 1.61
|
502 kumpf 1.81 gcount = (Uint32)is.gcount();
503 line.append(input, gcount);
|
504 marek 1.61
|
505 kumpf 1.81 if (is.rdstate() & PEGASUS_STD(istream)::failbit)
506 {
507 // It is okay if we encounter the newline character without reading
508 // data.
509 is.clear();
|
510 marek 1.61 break;
|
511 kumpf 1.81 }
512 } while (gcount == buffersize-1);
|
513 marek 1.61
|
514 kumpf 1.81 if (!is.eof())
515 {
516 // we need to consume the '\n', because get() doesn't
517 char c = 0;
518 is.get(c);
|
519 marek 1.61 }
520
|
521 kumpf 1.81 return !!is;
|
522 marek 1.61 }
523
|
524 msolomon 1.64 //
525 // changes the file owner to one specified
526 //
|
527 kumpf 1.65 Boolean FileSystem::changeFileOwner(
528 const String& fileName,
529 const String& userName)
|
530 msolomon 1.64 {
531 #if defined(PEGASUS_OS_TYPE_WINDOWS)
532
533 return true;
534
535 #else
536
537 PEG_METHOD_ENTER(TRC_AUTHENTICATION, "FileSystem::changeFileOwner()");
538
|
539 kumpf 1.65 struct passwd* userPasswd;
|
540 karl 1.78 #if defined(PEGASUS_OS_SOLARIS) || \
|
541 msolomon 1.64 defined(PEGASUS_OS_HPUX) || \
|
542 carson.hovey 1.72 defined(PEGASUS_OS_LINUX) || \
|
543 cheng.sp 1.82 defined (PEGASUS_OS_VMS) || \
544 defined (PEGASUS_OS_AIX)
|
545 msolomon 1.64
546 const unsigned int PWD_BUFF_SIZE = 1024;
|
547 kumpf 1.65 struct passwd pwd;
|
548 msolomon 1.64 char pwdBuffer[PWD_BUFF_SIZE];
549
|
550 kumpf 1.66 if (getpwnam_r(userName.getCString(), &pwd, pwdBuffer, PWD_BUFF_SIZE,
|
551 msolomon 1.64 &userPasswd) != 0)
552 {
|
553 kumpf 1.65 userPasswd = (struct passwd*)NULL;
|
554 msolomon 1.64 }
555
556 #else
557
558 userPasswd = getpwnam(userName.getCString());
559 #endif
560
|
561 kumpf 1.65 if (userPasswd == NULL)
|
562 msolomon 1.64 {
563 PEG_METHOD_EXIT();
|
564 kumpf 1.65 return false;
|
565 msolomon 1.64 }
566
|
567 kumpf 1.65 Sint32 ret = chown(
568 fileName.getCString(), userPasswd->pw_uid, userPasswd->pw_gid);
|
569 kumpf 1.85
|
570 kumpf 1.65 if (ret == -1)
|
571 msolomon 1.64 {
572 PEG_METHOD_EXIT();
|
573 kumpf 1.65 return false;
|
574 msolomon 1.64 }
575
576 PEG_METHOD_EXIT();
577
|
578 kumpf 1.65 return true;
|
579 msolomon 1.64 #endif
580 }
|
581 mateus.baur 1.70
|
582 karl 1.85.8.1 #if defined(PEGASUS_OS_HPUX)
|
583 mateus.baur 1.70 void FileSystem::syncWithDirectoryUpdates(PEGASUS_STD(fstream)& fs)
584 {
|
585 karl 1.85.8.1 #if defined (PEGASUS_PLATFORM_HPUX_IA64_GNU) || \
586 defined (PEGASUS_PLATFORM_HPUX_PARISC_GNU)
587 // Writes the data from the iostream buffers to the OS buffers
588 fs.flush();
589 // Writes the data from the OS buffers to the disk
590 fs.rdbuf()->pubsync();
591 #else
|
592 mateus.baur 1.70 // Writes the data from the iostream buffers to the OS buffers
593 fs.flush();
594 // Writes the data from the OS buffers to the disk
595 fsync(fs.rdbuf()->fd());
|
596 karl 1.85.8.1 #endif
|
597 mateus.baur 1.70 }
|
598 karl 1.85.8.1 #else
599 void FileSystem::syncWithDirectoryUpdates(PEGASUS_STD(fstream)&)
600 {
601 //Not HP-UX, do nothing (compiler will remove this fct on optimization)
602 }
603 #endif
|
604 mateus.baur 1.70
|
605 mike 1.74 Boolean FileSystem::glob(
|
606 kumpf 1.85 const String& path,
|
607 mike 1.74 const String& pattern_,
608 Array<String>& filenames)
609 {
610 filenames.clear();
611
612 try
613 {
614 CString pattern(pattern_.getCString());
615
616 for (Dir dir(path); dir.more(); dir.next())
617 {
618 const char* name = dir.getName();
619
620 if (strcmp(name, ".") == 0 || strcmp(name, "..") == 0)
621 continue;
622
623 if (Match(pattern, name) == 0)
624 filenames.append(name);
625 }
626 }
627 catch (CannotOpenDirectory&)
628 mike 1.74 {
629 return false;
630 }
631
632 return true;
633 }
634
|
635 marek 1.61 PEGASUS_NAMESPACE_END
|