19 *
20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 */
32
33
34 #include "FilePath.h"
35
36 #include <algorithm>
37 #include <list>
38
39 #ifdef POSIX
40 #include <sys/stat.h>
41 #endif //POSIX
42
43
44 bool FilePath::FileExists(const TString FileName) {
45 bool result = false;
46 #ifdef WINDOWS
47 WIN32_FIND_DATA FindFileData;
48 HANDLE handle = FindFirstFile(FileName.data(), &FindFileData);
49
50 if (handle != INVALID_HANDLE_VALUE) {
51 if (FILE_ATTRIBUTE_DIRECTORY & FindFileData.dwFileAttributes) {
52 result = true;
53 }
54 else {
55 result = true;
56 }
57
58 FindClose(handle);
75 HANDLE handle = FindFirstFile(DirectoryName.data(), &FindFileData);
76
77 if (handle != INVALID_HANDLE_VALUE) {
78 if (FILE_ATTRIBUTE_DIRECTORY & FindFileData.dwFileAttributes) {
79 result = true;
80 }
81
82 FindClose(handle);
83 }
84 #endif //WINDOWS
85 #ifdef POSIX
86 struct stat buf;
87
88 if ((stat(StringToFileSystemString(DirectoryName), &buf) == 0) && (S_ISDIR(buf.st_mode) != 0)) {
89 result = true;
90 }
91 #endif //POSIX
92 return result;
93 }
94
95 bool FilePath::DeleteFile(const TString FileName) {
96 bool result = false;
97
98 if (FileExists(FileName) == true) {
99 #ifdef WINDOWS
100 result = DeleteFile(FileName.data());
101 #endif //WINDOWS
102 #ifdef POSIX
103 if (unlink(StringToFileSystemString(FileName)) == 0) {
104 result = true;
105 }
106 #endif //POSIX
107 }
108
109 return result;
110 }
111
112 TString FilePath::IncludeTrailingSlash(const TString value) {
113 TString result = value;
114 TString::iterator i = result.end();
115 i--;
116
117 if (*i != TRAILING_SLASH) {
118 result += TRAILING_SLASH;
119 }
120
121 return result;
122 }
123
124 TString FilePath::IncludeTrailingSlash(const char* value) {
125 TString lvalue = PlatformString(value).toString();
126 return IncludeTrailingSlash(lvalue);
127 }
128
129 TString FilePath::IncludeTrailingSlash(const wchar_t* value) {
130 TString lvalue = PlatformString(value).toString();
131 return IncludeTrailingSlash(lvalue);
132 }
133
134 TString FilePath::ExtractFilePath(TString Path) {
135 #ifdef WINDOWS
136 TString result;
137 size_t slash = Path.find_last_of(TRAILING_SLASH);
138 if (slash != TString::npos)
139 result = Path.substr(0, slash);
140 return result;
141 #endif //WINDOWS
142 #ifdef POSIX
143 return dirname(StringToFileSystemString(Path));
144 #endif //POSIX
145 }
146
147 TString FilePath::ExtractFileExt(TString Path) {
148 TString result;
149 size_t dot = Path.find_last_of('.');
150
151 if (dot != TString::npos) {
152 result = Path.substr(dot, Path.size() - dot);
153 }
154
155 return result;
156 }
157
158 TString FilePath::ExtractFileName(TString Path) {
159 #ifdef WINDOWS
160 TString result;
161
162 size_t slash = Path.find_last_of(TRAILING_SLASH);
163 if (slash != TString::npos)
164 result = Path.substr(slash + 1, Path.size() - slash - 1);
165
166 return result;
167 #endif // WINDOWS
168 #ifdef POSIX
169 return basename(StringToFileSystemString(Path));
170 #endif //POSIX
171 }
172
173 TString FilePath::ChangeFileExt(TString Path, TString Extension) {
174 TString result;
175 size_t dot = Path.find_last_of('.');
176
177 if (dot != TString::npos) {
178 result = Path.substr(0, dot) + Extension;
179 }
180
181 if (result.empty() == true) {
182 result = Path;
183 }
184
185 return result;
186 }
187
188 TString FilePath::FixPathSeparatorForPlatform(TString Path) {
189 TString result = Path;
190 std::replace(result.begin(), result.end(), ' ', PATH_SEPARATOR);
191 std::replace(result.begin(), result.end(), BAD_PATH_SEPARATOR, PATH_SEPARATOR);
192 return result;
193 }
194
195 TString FilePath::PathSeparator() {
196 TString result;
197 result = PATH_SEPARATOR;
198 return result;
199 }
200
201 bool FilePath::CreateDirectory(TString Path, bool ownerOnly) {
202 bool result = false;
203
204 std::list<TString> paths;
205 TString lpath = Path;
206
207 while (lpath.empty() == false && DirectoryExists(lpath) == false) {
208 paths.push_front(lpath);
209 lpath = ExtractFilePath(lpath);
210 }
217 #endif // WINDOWS
218 #ifdef POSIX
219 mode_t mode = S_IRWXU;
220 if (!ownerOnly) {
221 mode |= S_IRWXG | S_IROTH | S_IXOTH;
222 }
223 if (mkdir(StringToFileSystemString(lpath), mode) == 0) {
224 #endif //POSIX
225 result = true;
226 }
227 else {
228 result = false;
229 break;
230 }
231 }
232
233 return result;
234 }
235
236 void FilePath::ChangePermissions(TString FileName, bool ownerOnly) {
237
238 #ifdef POSIX
239 mode_t mode = S_IRWXU;
240 if (!ownerOnly) {
241 mode |= S_IRWXG | S_IROTH | S_IXOTH;
242 }
243 chmod(FileName.data(), mode);
244 #endif // POSIX
245
246 }
|
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 */
32
33
34 #include "FilePath.h"
35
36 #include <algorithm>
37 #include <list>
38
39 #ifdef WINDOWS
40 #include <ShellAPI.h>
41 #endif //WINDOWS
42
43 #ifdef POSIX
44 #include <sys/stat.h>
45 #endif //POSIX
46
47
48 bool FilePath::FileExists(const TString FileName) {
49 bool result = false;
50 #ifdef WINDOWS
51 WIN32_FIND_DATA FindFileData;
52 HANDLE handle = FindFirstFile(FileName.data(), &FindFileData);
53
54 if (handle != INVALID_HANDLE_VALUE) {
55 if (FILE_ATTRIBUTE_DIRECTORY & FindFileData.dwFileAttributes) {
56 result = true;
57 }
58 else {
59 result = true;
60 }
61
62 FindClose(handle);
79 HANDLE handle = FindFirstFile(DirectoryName.data(), &FindFileData);
80
81 if (handle != INVALID_HANDLE_VALUE) {
82 if (FILE_ATTRIBUTE_DIRECTORY & FindFileData.dwFileAttributes) {
83 result = true;
84 }
85
86 FindClose(handle);
87 }
88 #endif //WINDOWS
89 #ifdef POSIX
90 struct stat buf;
91
92 if ((stat(StringToFileSystemString(DirectoryName), &buf) == 0) && (S_ISDIR(buf.st_mode) != 0)) {
93 result = true;
94 }
95 #endif //POSIX
96 return result;
97 }
98
99 #ifdef WINDOWS
100 std::string GetLastErrorAsString() {
101 //Get the error message, if any.
102 DWORD errorMessageID = ::GetLastError();
103
104 if (errorMessageID == 0) {
105 return "No error message has been recorded";
106 }
107
108 LPSTR messageBuffer = NULL;
109 size_t size = FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
110 NULL, errorMessageID, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPSTR)&messageBuffer, 0, NULL);
111
112 std::string message(messageBuffer, size);
113
114 // Free the buffer.
115 LocalFree(messageBuffer);
116
117 return message;
118 }
119 #endif //WINDOWS
120
121 bool FilePath::DeleteFile(const TString FileName) {
122 bool result = false;
123
124 if (FileExists(FileName) == true) {
125 #ifdef WINDOWS
126 TString lFileName = FileName;
127 FileAttributes attributes(lFileName);
128
129 if (attributes.Contains(faReadOnly) == true) {
130 attributes.Remove(faReadOnly);
131 }
132
133 result = ::DeleteFile(lFileName.data()) == TRUE;
134 #endif //WINDOWS
135 #ifdef POSIX
136 if (unlink(StringToFileSystemString(FileName)) == 0) {
137 result = true;
138 }
139 #endif //POSIX
140 }
141
142 return result;
143 }
144
145 bool FilePath::DeleteDirectory(const TString DirectoryName) {
146 bool result = false;
147
148 if (DirectoryExists(DirectoryName) == true) {
149 #ifdef WINDOWS
150 SHFILEOPSTRUCTW fos = {0};
151 DynamicBuffer<TCHAR> lDirectoryName(DirectoryName.size() + 2);
152 memcpy(lDirectoryName.GetData(), DirectoryName.data(), (DirectoryName.size() + 2) * sizeof(TCHAR));
153 lDirectoryName[DirectoryName.size() + 1] = NULL; // Double null terminate for SHFileOperation.
154
155 // Delete the folder and everything inside.
156 fos.wFunc = FO_DELETE;
157 fos.pFrom = lDirectoryName.GetData();
158 fos.fFlags = FOF_NO_UI;
159 result = SHFileOperation(&fos) == 0;
160 #endif //WINDOWS
161 #ifdef POSIX
162 if (unlink(StringToFileSystemString(DirectoryName)) == 0) {
163 result = true;
164 }
165 #endif //POSIX
166 }
167
168 return result;
169 }
170
171 TString FilePath::IncludeTrailingSeparater(const TString value) {
172 TString result = value;
173
174 if (value.size() > 0) {
175 TString::iterator i = result.end();
176 i--;
177
178 if (*i != TRAILING_PATHSEPARATOR) {
179 result += TRAILING_PATHSEPARATOR;
180 }
181 }
182
183 return result;
184 }
185
186 TString FilePath::IncludeTrailingSeparater(const char* value) {
187 TString lvalue = PlatformString(value).toString();
188 return IncludeTrailingSeparater(lvalue);
189 }
190
191 TString FilePath::IncludeTrailingSeparater(const wchar_t* value) {
192 TString lvalue = PlatformString(value).toString();
193 return IncludeTrailingSeparater(lvalue);
194 }
195
196 TString FilePath::ExtractFilePath(TString Path) {
197 #ifdef WINDOWS
198 TString result;
199 size_t slash = Path.find_last_of(TRAILING_PATHSEPARATOR);
200 if (slash != TString::npos)
201 result = Path.substr(0, slash);
202 return result;
203 #endif //WINDOWS
204 #ifdef POSIX
205 return dirname(StringToFileSystemString(Path));
206 #endif //POSIX
207 }
208
209 TString FilePath::ExtractFileExt(TString Path) {
210 TString result;
211 size_t dot = Path.find_last_of('.');
212
213 if (dot != TString::npos) {
214 result = Path.substr(dot, Path.size() - dot);
215 }
216
217 return result;
218 }
219
220 TString FilePath::ExtractFileName(TString Path) {
221 #ifdef WINDOWS
222 TString result;
223
224 size_t slash = Path.find_last_of(TRAILING_PATHSEPARATOR);
225 if (slash != TString::npos)
226 result = Path.substr(slash + 1, Path.size() - slash - 1);
227
228 return result;
229 #endif // WINDOWS
230 #ifdef POSIX
231 return basename(StringToFileSystemString(Path));
232 #endif //POSIX
233 }
234
235 TString FilePath::ChangeFileExt(TString Path, TString Extension) {
236 TString result;
237 size_t dot = Path.find_last_of('.');
238
239 if (dot != TString::npos) {
240 result = Path.substr(0, dot) + Extension;
241 }
242
243 if (result.empty() == true) {
244 result = Path;
245 }
246
247 return result;
248 }
249
250 TString FilePath::FixPathForPlatform(TString Path) {
251 TString result = Path;
252 std::replace(result.begin(), result.end(), BAD_TRAILING_PATHSEPARATOR, TRAILING_PATHSEPARATOR);
253 return result;
254 }
255
256 TString FilePath::FixPathSeparatorForPlatform(TString Path) {
257 TString result = Path;
258 std::replace(result.begin(), result.end(), BAD_PATH_SEPARATOR, PATH_SEPARATOR);
259 return result;
260 }
261
262 TString FilePath::PathSeparator() {
263 TString result;
264 result = PATH_SEPARATOR;
265 return result;
266 }
267
268 bool FilePath::CreateDirectory(TString Path, bool ownerOnly) {
269 bool result = false;
270
271 std::list<TString> paths;
272 TString lpath = Path;
273
274 while (lpath.empty() == false && DirectoryExists(lpath) == false) {
275 paths.push_front(lpath);
276 lpath = ExtractFilePath(lpath);
277 }
284 #endif // WINDOWS
285 #ifdef POSIX
286 mode_t mode = S_IRWXU;
287 if (!ownerOnly) {
288 mode |= S_IRWXG | S_IROTH | S_IXOTH;
289 }
290 if (mkdir(StringToFileSystemString(lpath), mode) == 0) {
291 #endif //POSIX
292 result = true;
293 }
294 else {
295 result = false;
296 break;
297 }
298 }
299
300 return result;
301 }
302
303 void FilePath::ChangePermissions(TString FileName, bool ownerOnly) {
304 #ifdef POSIX
305 mode_t mode = S_IRWXU;
306 if (!ownerOnly) {
307 mode |= S_IRWXG | S_IROTH | S_IXOTH;
308 }
309 chmod(FileName.data(), mode);
310 #endif // POSIX
311 }
312
313 //--------------------------------------------------------------------------------------------------
314
315 #include <algorithm>
316
317 FileAttributes::FileAttributes(const TString FileName, bool FollowLink) {
318 FFileName = FileName;
319 FFollowLink = FollowLink;
320 ReadAttributes();
321 }
322
323 bool FileAttributes::WriteAttributes() {
324 bool result = false;
325
326 #ifdef WINDOWS
327 DWORD attributes = 0;
328
329 for (std::vector<FileAttribute>::const_iterator iterator = FAttributes.begin();
330 iterator != FAttributes.end(); iterator++) {
331 switch (*iterator) {
332 case faArchive: {
333 attributes = attributes & FILE_ATTRIBUTE_ARCHIVE;
334 break;
335 }
336 case faCompressed: {
337 attributes = attributes & FILE_ATTRIBUTE_COMPRESSED;
338 break;
339 }
340 case faDevice: {
341 attributes = attributes & FILE_ATTRIBUTE_DEVICE;
342 break;
343 }
344 case faDirectory: {
345 attributes = attributes & FILE_ATTRIBUTE_DIRECTORY;
346 break;
347 }
348 case faEncrypted: {
349 attributes = attributes & FILE_ATTRIBUTE_ENCRYPTED;
350 break;
351 }
352 case faHidden: {
353 attributes = attributes & FILE_ATTRIBUTE_HIDDEN;
354 break;
355 }
356 // case faIntegrityStream: {
357 // attributes = attributes & FILE_ATTRIBUTE_INTEGRITY_STREAM;
358 // break;
359 // }
360 case faNormal: {
361 attributes = attributes & FILE_ATTRIBUTE_NORMAL;
362 break;
363 }
364 case faNotContentIndexed: {
365 attributes = attributes & FILE_ATTRIBUTE_NOT_CONTENT_INDEXED;
366 break;
367 }
368 // case faNoScrubData: {
369 // attributes = attributes & FILE_ATTRIBUTE_NO_SCRUB_DATA;
370 // break;
371 // }
372 case faOffline: {
373 attributes = attributes & FILE_ATTRIBUTE_OFFLINE;
374 break;
375 }
376 case faSystem: {
377 attributes = attributes & FILE_ATTRIBUTE_SYSTEM;
378 break;
379 }
380 case faSymbolicLink: {
381 attributes = attributes & FILE_ATTRIBUTE_REPARSE_POINT;
382 break;
383 }
384 case faSparceFile: {
385 attributes = attributes & FILE_ATTRIBUTE_SPARSE_FILE;
386 break;
387 }
388 case faReadOnly: {
389 attributes = attributes & FILE_ATTRIBUTE_READONLY;
390 break;
391 }
392 case faTemporary: {
393 attributes = attributes & FILE_ATTRIBUTE_TEMPORARY;
394 break;
395 }
396 case faVirtual: {
397 attributes = attributes & FILE_ATTRIBUTE_VIRTUAL;
398 break;
399 }
400 }
401 }
402
403 if (::SetFileAttributes(FFileName.data(), attributes) != 0) {
404 result = true;
405 }
406 #endif // WINDOWS
407 #ifdef POSIX
408 mode_t attributes = 0;
409
410 for (std::vector<FileAttribute>::const_iterator iterator = FAttributes.begin();
411 iterator != FAttributes.end(); iterator++) {
412 switch (*iterator) {
413 case faBlockSpecial: {
414 attributes |= S_IFBLK;
415 break;
416 }
417 case faCharacterSpecial: {
418 attributes |= S_IFCHR;
419 break;
420 }
421 case faFIFOSpecial: {
422 attributes |= S_IFIFO;
423 break;
424 }
425 case faNormal: {
426 attributes |= S_IFREG;
427 break;
428 }
429 case faDirectory: {
430 attributes |= S_IFDIR;
431 break;
432 }
433 case faSymbolicLink: {
434 attributes |= S_IFLNK;
435 break;
436 }
437 case faSocket: {
438 attributes |= S_IFSOCK;
439 break;
440 }
441
442 // Owner
443 case faReadOnly: {
444 attributes |= S_IRUSR;
445 break;
446 }
447 case faWriteOnly: {
448 attributes |= S_IWUSR;
449 break;
450 }
451 case faReadWrite: {
452 attributes |= S_IRUSR;
453 attributes |= S_IWUSR;
454 break;
455 }
456 case faExecute: {
457 attributes |= S_IXUSR;
458 break;
459 }
460
461 // Group
462 case faGroupReadOnly: {
463 attributes |= S_IRGRP;
464 break;
465 }
466 case faGroupWriteOnly: {
467 attributes |= S_IWGRP;
468 break;
469 }
470 case faGroupReadWrite: {
471 attributes |= S_IRGRP;
472 attributes |= S_IWGRP;
473 break;
474 }
475 case faGroupExecute: {
476 attributes |= S_IXGRP;
477 break;
478 }
479
480 // Others
481 case faOthersReadOnly: {
482 attributes |= S_IROTH;
483 break;
484 }
485 case faOthersWriteOnly: {
486 attributes |= S_IWOTH;
487 break;
488 }
489 case faOthersReadWrite: {
490 attributes |= S_IROTH;
491 attributes |= S_IWOTH;
492 break;
493 }
494 case faOthersExecute: {
495 attributes |= S_IXOTH;
496 break;
497 }
498 }
499 }
500
501 if (chmod(FFileName.data(), attributes) == 0) {
502 result = true;
503 }
504 #endif //POSIX
505
506 return result;
507 }
508
509 #define S_ISRUSR(m) (((m) & S_IRWXU) == S_IRUSR)
510 #define S_ISWUSR(m) (((m) & S_IRWXU) == S_IWUSR)
511 #define S_ISXUSR(m) (((m) & S_IRWXU) == S_IXUSR)
512
513 #define S_ISRGRP(m) (((m) & S_IRWXG) == S_IRGRP)
514 #define S_ISWGRP(m) (((m) & S_IRWXG) == S_IWGRP)
515 #define S_ISXGRP(m) (((m) & S_IRWXG) == S_IXGRP)
516
517 #define S_ISROTH(m) (((m) & S_IRWXO) == S_IROTH)
518 #define S_ISWOTH(m) (((m) & S_IRWXO) == S_IWOTH)
519 #define S_ISXOTH(m) (((m) & S_IRWXO) == S_IXOTH)
520
521 bool FileAttributes::ReadAttributes() {
522 bool result = false;
523
524 #ifdef WINDOWS
525 DWORD attributes = ::GetFileAttributes(FFileName.data());
526
527 if (attributes != INVALID_FILE_ATTRIBUTES) {
528 result = true;
529
530 if (attributes | FILE_ATTRIBUTE_ARCHIVE) { FAttributes.push_back(faArchive); }
531 if (attributes | FILE_ATTRIBUTE_COMPRESSED) { FAttributes.push_back(faCompressed); }
532 if (attributes | FILE_ATTRIBUTE_DEVICE) { FAttributes.push_back(faDevice); }
533 if (attributes | FILE_ATTRIBUTE_DIRECTORY) { FAttributes.push_back(faDirectory); }
534 if (attributes | FILE_ATTRIBUTE_ENCRYPTED) { FAttributes.push_back(faEncrypted); }
535 if (attributes | FILE_ATTRIBUTE_HIDDEN) { FAttributes.push_back(faHidden); }
536 //if (attributes | FILE_ATTRIBUTE_INTEGRITY_STREAM) { FAttributes.push_back(faIntegrityStream); }
537 if (attributes | FILE_ATTRIBUTE_NORMAL) { FAttributes.push_back(faNormal); }
538 if (attributes | FILE_ATTRIBUTE_NOT_CONTENT_INDEXED) { FAttributes.push_back(faNotContentIndexed); }
539 //if (attributes | FILE_ATTRIBUTE_NO_SCRUB_DATA) { FAttributes.push_back(faNoScrubData); }
540 if (attributes | FILE_ATTRIBUTE_SYSTEM) { FAttributes.push_back(faSystem); }
541 if (attributes | FILE_ATTRIBUTE_OFFLINE) { FAttributes.push_back(faOffline); }
542 if (attributes | FILE_ATTRIBUTE_REPARSE_POINT) { FAttributes.push_back(faSymbolicLink); }
543 if (attributes | FILE_ATTRIBUTE_SPARSE_FILE) { FAttributes.push_back(faSparceFile); }
544 if (attributes | FILE_ATTRIBUTE_READONLY ) { FAttributes.push_back(faReadOnly); }
545 if (attributes | FILE_ATTRIBUTE_TEMPORARY) { FAttributes.push_back(faTemporary); }
546 if (attributes | FILE_ATTRIBUTE_VIRTUAL) { FAttributes.push_back(faVirtual); }
547 }
548 #endif // WINDOWS
549 #ifdef POSIX
550 struct stat status;
551
552 if (stat(StringToFileSystemString(FFileName), &status) == 0) {
553 result = true;
554
555 if (S_ISBLK(status.st_mode) != 0) { FAttributes.push_back(faBlockSpecial); }
556 if (S_ISCHR(status.st_mode) != 0) { FAttributes.push_back(faCharacterSpecial); }
557 if (S_ISFIFO(status.st_mode) != 0) { FAttributes.push_back(faFIFOSpecial); }
558 if (S_ISREG(status.st_mode) != 0) { FAttributes.push_back(faNormal); }
559 if (S_ISDIR(status.st_mode) != 0) { FAttributes.push_back(faDirectory); }
560 if (S_ISLNK(status.st_mode) != 0) { FAttributes.push_back(faSymbolicLink); }
561 if (S_ISSOCK(status.st_mode) != 0) { FAttributes.push_back(faSocket); }
562
563 // Owner
564 if (S_ISRUSR(status.st_mode) != 0) {
565 if (S_ISWUSR(status.st_mode) != 0) { FAttributes.push_back(faReadWrite); }
566 else { FAttributes.push_back(faReadOnly); }
567 }
568 else if (S_ISWUSR(status.st_mode) != 0) { FAttributes.push_back(faWriteOnly); }
569
570 if (S_ISXUSR(status.st_mode) != 0) { FAttributes.push_back(faExecute); }
571
572 // Group
573 if (S_ISRGRP(status.st_mode) != 0) {
574 if (S_ISWGRP(status.st_mode) != 0) { FAttributes.push_back(faGroupReadWrite); }
575 else { FAttributes.push_back(faGroupReadOnly); }
576 }
577 else if (S_ISWGRP(status.st_mode) != 0) { FAttributes.push_back(faGroupWriteOnly); }
578
579 if (S_ISXGRP(status.st_mode) != 0) { FAttributes.push_back(faGroupExecute); }
580
581
582 // Others
583 if (S_ISROTH(status.st_mode) != 0) {
584 if (S_ISWOTH(status.st_mode) != 0) { FAttributes.push_back(faOthersReadWrite); }
585 else { FAttributes.push_back(faOthersReadOnly); }
586 }
587 else if (S_ISWOTH(status.st_mode) != 0) { FAttributes.push_back(faOthersWriteOnly); }
588
589 if (S_ISXOTH(status.st_mode) != 0) { FAttributes.push_back(faOthersExecute); }
590
591 if (FFileName.size() > 0 && FFileName[0] == '.') {
592 FAttributes.push_back(faHidden);
593 }
594 }
595 #endif //POSIX
596
597 return result;
598 }
599
600 bool FileAttributes::Valid(const FileAttribute Value) {
601 bool result = false;
602
603 switch (Value) {
604 #ifdef WINDOWS
605 case faHidden:
606 #endif // WINDOWS
607 #ifdef POSIX
608 case faReadWrite:
609 case faWriteOnly:
610 case faExecute:
611
612 case faGroupReadWrite:
613 case faGroupWriteOnly:
614 case faGroupReadOnly:
615 case faGroupExecute:
616
617 case faOthersReadWrite:
618 case faOthersWriteOnly:
619 case faOthersReadOnly:
620 case faOthersExecute:
621 #endif //POSIX
622
623 case faReadOnly: {
624 result = true;
625 break;
626 }
627 }
628
629 return result;
630 }
631
632 void FileAttributes::Append(FileAttribute Value) {
633 if (Valid(Value) == true) {
634 #ifdef POSIX
635 if ((Value == faReadOnly && Contains(faWriteOnly) == true) ||
636 (Value == faWriteOnly && Contains(faReadOnly) == true)) {
637 Value = faReadWrite;
638 }
639 #endif //POSIX
640
641 FAttributes.push_back(Value);
642 WriteAttributes();
643 }
644 }
645
646 bool FileAttributes::Contains(FileAttribute Value) {
647 bool result = false;
648
649 std::vector<FileAttribute>::const_iterator iterator = std::find(FAttributes.begin(), FAttributes.end(), Value);
650
651 if (iterator != FAttributes.end()) {
652 result = true;
653 }
654
655 return result;
656 }
657
658 void FileAttributes::Remove(FileAttribute Value) {
659 if (Valid(Value) == true) {
660 #ifdef POSIX
661 if (Value == faReadOnly && Contains(faReadWrite) == true) {
662 Append(faWriteOnly);
663 Remove(faReadWrite);
664 }
665 else if (Value == faWriteOnly && Contains(faReadWrite) == true) {
666 Append(faReadOnly);
667 Remove(faReadWrite);
668 }
669 #endif //POSIX
670
671 std::vector<FileAttribute>::iterator iterator = std::find(FAttributes.begin(), FAttributes.end(), Value);
672
673 if (iterator != FAttributes.end()) {
674 FAttributes.erase(iterator);
675 WriteAttributes();
676 }
677 }
678 }
|