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 // $Log$
26 //
27 //END_HISTORY
28
29 #include <Pegasus/Common/Config.h>
30
31 #ifdef PEGASUS_OS_TYPE_WINDOWS
32 # include <io.h>
33 # include <direct.h>
34 #else
35 # include <unistd.h>
36 # include <dirent.h>
37 #endif
38
39 #include <sys/stat.h>
40 #include <sys/types.h>
41 #include <cstdio>
42 #include "Destroyer.h"
43 mike 1.1 #include "FileSystem.h"
44
45 // ATTN-B: porting!
46
47 PEGASUS_NAMESPACE_BEGIN
48
49 #ifdef PEGASUS_OS_TYPE_WINDOWS
50 static const int ACCESS_EXISTS = 0;
51 static const int ACCESS_WRITE = 2;
52 static const int ACCESS_READ = 4;
53 static const int ACCESS_READ_AND_WRITE = 6;
54 #endif
55
56 // Clone the path but discard trailing slash if any:
57
58 static char* _clonePath(const String& path)
59 {
60 char* p = path.allocateCString();
61
62 if (!*p)
63 return p;
64 mike 1.1
65 char* last = p + path.getLength() - 1;
66
67 if (*last == '/')
68 *last = '\0';
69
70 return p;
71 }
72
73 Boolean FileSystem::exists(const String& path)
74 {
75 Destroyer<char> p(_clonePath(path));
76
77 #ifdef PEGASUS_OS_TYPE_WINDOWS
78 return _access(p.getPointer(), ACCESS_EXISTS) == 0;
79 #else
80 return access(p.getPointer(), F_OK) == 0;
81 #endif
82 }
83
84 Boolean FileSystem::canRead(const String& path)
85 mike 1.1 {
86 Destroyer<char> p(_clonePath(path));
87
88 #ifdef PEGASUS_OS_TYPE_WINDOWS
89 return _access(p.getPointer(), ACCESS_READ) == 0;
90 #else
91 return access(p.getPointer(), R_OK) == 0;
92 #endif
93 }
94
95 Boolean FileSystem::canWrite(const String& path)
96 {
97 Destroyer<char> p(_clonePath(path));
98
99 #ifdef PEGASUS_OS_TYPE_WINDOWS
100 return _access(p.getPointer(), ACCESS_WRITE) == 0;
101 #else
102 return access(p.getPointer(), W_OK) == 0;
103 #endif
104 }
105
106 mike 1.1 #if 0
107 // ATTN: not implemented for NT. But not used by Pegasus.
108 Boolean FileSystem::canExecute(const String& path)
109 {
110 Destroyer<char> p(_clonePath(path));
111 return access(p.getPointer(), X_OK) == 0;
112 }
113 #endif
114
115 Boolean FileSystem::isDirectory(const String& path)
116 {
117 Destroyer<char> p(_clonePath(path));
118
119 struct stat st;
120
121 #ifdef PEGASUS_OS_TYPE_WINDOWS
122
123 if (stat(p.getPointer(), &st) != 0)
124 return false;
125
126 Boolean result = (st.st_mode & _S_IFDIR) != 0;
127 mike 1.1 return result;
128
129 #else
130
131 if (stat(p.getPointer(), &st) != 0)
132 return false;
133
134 Boolean result = S_ISDIR(st.st_mode);
135 return result;
136
137 #endif
138 }
139
140 Boolean FileSystem::changeDirectory(const String& path)
141 {
142 Destroyer<char> p(_clonePath(path));
143 return chdir(p.getPointer()) == 0;
144 }
145
146 Boolean FileSystem::makeDirectory(const String& path)
147 {
148 mike 1.1 Destroyer<char> p(_clonePath(path));
149 #ifdef PEGASUS_OS_TYPE_WINDOWS
150 return _mkdir(p.getPointer()) == 0;
151 #else
152 return mkdir(p.getPointer(), 0777) == 0;
153 #endif
154 }
155
156 Boolean FileSystem::getFileSize(const String& path, Uint32& size)
157 {
158 struct stat st;
159
160 Destroyer<char> p(_clonePath(path));
161
162 if (stat(p.getPointer(), &st) != 0)
163 return false;
164
165 size = st.st_size;
166 return true;
167 }
168
169 mike 1.1 Boolean FileSystem::removeDirectory(const String& path)
170 {
171 Destroyer<char> p(_clonePath(path));
172 return rmdir(p.getPointer()) == 0;
173 }
174
175 Boolean FileSystem::removeFile(const String& path)
176 {
177 Destroyer<char> p(_clonePath(path));
178 return unlink(p.getPointer()) == 0;
179 }
180
181 void FileSystem::loadFileToMemory(
182 Array<Sint8>& array,
183 const String& fileName)
184 {
185 Uint32 fileSize;
186
187 if (!getFileSize(fileName, fileSize))
188 throw CannotOpenFile(fileName);
189
190 mike 1.1 char* tmp = fileName.allocateCString();
191 FILE* fp = fopen(tmp, "rb");
192 delete [] tmp;
193
194 if (fp == NULL)
195 throw CannotOpenFile(fileName);
196
197 array.reserve(fileSize);
198 char buffer[4096];
199 size_t n;
200
201 while ((n = fread(buffer, 1, sizeof(buffer), fp)) > 0)
202 array.append(buffer, n);
203
204 fclose(fp);
205 }
206
207 Boolean FileSystem::compare(
208 const String& fileName1,
209 const String& fileName2)
210 {
211 mike 1.1 Uint32 fileSize1;
212
213 if (!getFileSize(fileName1, fileSize1))
214 throw CannotOpenFile(fileName1);
215
216 Uint32 fileSize2;
217
218 if (!getFileSize(fileName2, fileSize2))
219 throw CannotOpenFile(fileName2);
220
221 if (fileSize1 != fileSize2)
222 return false;
223
224 char* tmp1 = fileName1.allocateCString();
225 FILE* fp1 = fopen(tmp1, "rb");
226 delete [] tmp1;
227
228 if (fp1 == NULL)
229 throw CannotOpenFile(fileName1);
230
231 char* tmp2 = fileName2.allocateCString();
232 mike 1.1 FILE* fp2 = fopen(tmp2, "rb");
233 delete [] tmp2;
234
235 if (fp2 == NULL)
236 {
237 fclose(fp1);
238 throw CannotOpenFile(fileName2);
239 }
240
241 int c1;
242 int c2;
243
244 while ((c1 = fgetc(fp1)) != EOF && (c2 = fgetc(fp2)) != EOF)
245 {
246 if (c1 != c2)
247 {
248 fclose(fp1);
249 fclose(fp2);
250 return false;
251 }
252 }
253 mike 1.1
254 fclose(fp1);
255 fclose(fp2);
256 return true;
257 }
258
259 Boolean FileSystem::getDirectoryContents(
260 const String& path,
261 Array<String>& paths)
262 {
263 paths.clear();
264
265 #ifdef PEGASUS_OS_TYPE_WINDOWS
266
267 String tmp = path;
268 tmp += "/*";
269 Destroyer<char> p(tmp.allocateCString());
270
271 long file;
272 struct _finddata_t findData;
273
274 mike 1.1 if ((file = _findfirst(p.getPointer(), &findData)) == -1L)
275 return false;
276
277 do
278 {
279 const char* name = findData.name;
280
281 if (strcmp(name, ".") == 0 || strcmp(name, "..") == 0)
282 continue;
283
284 paths.append(name);
285
286 } while (_findnext(file, &findData) == 0);
287
288 _findclose(file);
289
290 #else
291
292 Destroyer<char> p(_clonePath(path));
293 DIR* dir = opendir(p.getPointer());
294
295 mike 1.1 if (!dir)
296 return false;
297
298 struct dirent* entry;
299
300 while ((entry = readdir(dir)) != NULL)
301 {
302 const char* name = entry->d_name;
303
304 if (strcmp(name, ".") == 0 || strcmp(name, "..") == 0)
305 continue;
306
307 paths.append(name);
308 }
309
310 closedir(dir);
311 #endif
312
313 return true;
314 }
315
316 mike 1.1 PEGASUS_NAMESPACE_END
|