rvm  1.11
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
fs.cc
Go to the documentation of this file.
1 #include "config.h"
2 
3 #include <iostream>
4 #include <fstream>
5 
6 #ifdef STAT_MACROS_BROKEN
7 #error Sorry, S_ISDIR, S_ISREG et. al. appear to be broken on this system.
8 #endif
9 
10 #include <cstring>
11 #include <cerrno>
12 
13 #ifdef HAVE_SYS_MKDEV_H
14 #include <sys/mkdev.h>
15 #endif
16 #ifdef HAVE_SYS_TYPES_H
17 #include <sys/types.h>
18 #endif
19 #ifdef HAVE_SYS_STAT_H
20 #include <sys/stat.h>
21 #endif
22 #ifdef HAVE_UNISTD_H
23 #include <unistd.h>
24 #endif
25 
26 #ifdef TIME_WITH_SYS_TIME
27  #include <sys/time.h>
28  #include <time.h>
29 #else
30  #ifdef HAVE_SYS_TIME_H
31  #include <sys/time.h>
32  #else
33  #include <time.h>
34  #endif
35 #endif
36 
37 #ifdef HAVE_DIRENT_H
38  #include <dirent.h>
39  #define NAMELEN(dirent) strlen((dirent)->d_name)
40 #else
41  #define dirent direct
42  #define NAMELEN(dirent) (dirent)->d_namlen
43  #ifdef HAVE_SYS_NDIR_H
44  #include <sys/ndir.h>
45  #endif
46  #ifdef HAVE_SYS_DIR_H
47  #include <sys/dir.h>
48  #endif
49  #ifdef HAVE_NDIR_H
50  #include <ndir.h>
51  #endif
52 #endif
53 
54 #ifdef HAVE_FNMATCH_H
55 #include <fnmatch.h>
56 #endif
57 
58 #include <stdio.h>
59 
60 #include "asserts.h"
61 #include "error.h"
62 #include "estring.h"
63 #include "fs.h"
64 
65 //
66 // Define certain file attribute elements if they don't already exist
67 //
68 #ifndef S_IFMT
69 #define S_IFMT (S_IFREG|S_IFCHR|S_IFBLK|S_IFIFO)
70 #endif
71 
72 #ifndef S_IAMB
73 #define S_IAMB (S_ISUID|S_ISGID|S_ISVTX\
74  |S_IRUSR|S_IWUSR|S_IXUSR\
75  |S_IRGRP|S_IWGRP|S_IXGRP\
76  |S_IROTH|S_IWOTH|S_IXOTH\
77  )
78 
79 #endif
80 
81 #ifdef S_IFIFO
82 #ifndef S_ISFIFO
83 #define S_ISFIFO(mode) (((mode) & S_IFMT) == S_IFIFO)
84 #endif
85 #endif
86 
87 #ifdef S_IFCHR
88 #ifndef S_ISCHR
89 #define S_ISCHR(mode) (((mode) & S_IFMT) == S_IFCHR)
90 #endif
91 #endif
92 
93 #ifdef S_IFDIR
94 #ifndef S_ISDIR
95 #define S_ISDIR(mode) (((mode) & S_IFMT) == S_IFDIR)
96 #endif
97 #endif
98 
99 #ifdef S_IFBLK
100 #ifndef S_ISBLK
101 #define S_ISBLK(mode) (((mode) & S_IFMT) == S_IFBLK)
102 #endif
103 #endif
104 
105 #ifdef S_IFREG
106 #ifndef S_ISREG
107 #define S_ISREG(mode) (((mode) & S_IFMT) == S_IFREG)
108 #endif
109 #endif
110 
111 #ifdef S_IFLNK
112 #ifndef S_ISLNK
113 #define S_ISLNK(mode) (((mode) & S_IFMT) == S_IFLNK)
114 #endif
115 #endif
116 
117 #ifdef S_IFSOCK
118 #ifndef S_ISSOCK
119 #define S_ISSOCK(mode) (((mode) & S_IFMT) == S_IFSOCK)
120 #endif
121 #endif
122 
123 #ifdef S_IFDOOR
124 #ifndef S_ISDOOR
125 #define S_ISDOOR(mode) (((mode) & S_IFMT) == S_IFDOOR)
126 #endif
127 #endif
128 
129 #ifndef S_IRWXU
130 #define S_IRWXU (S_IRUSR|S_IWUSR|S_IXUSR)
131 #endif
132 
133 #ifndef S_IRWXG
134 #define S_IRWXG (S_IRGRP|S_IWGRP|S_IXGRP)
135 #endif
136 
137 #ifndef S_IRWXO
138 #define S_IRWXO (S_IROTH|S_IWOTH|S_IXOTH)
139 #endif
140 
141 #ifndef ACCESSPERMS
142 #define ACCESSPERMS (S_IRWXU|S_IRWXG|S_IRWXO)
143 #endif
144 
145 //----------------------------------------------------------------------------
146 
147 /** Return the current working directory */
148 const std::string cwd(void)
149 {
150  std::string s;
151  char buf[PATH_MAX] = { 0 };
152 
153  if (getcwd(buf, PATH_MAX) == 0)
154  throw(ERROR(errno,"Could not determine current directory"));
155 
156  TRY_nomem(s = buf);
157 
158  return(s);
159 }
160 
161 /** Return the PID of this process */
162 const pid_t pid(void)
163 {
164  pid_t pid;
165 
166  pid = getpid();
167  if (pid == -1)
168  throw(ERROR(errno,"Could not determine PID"));
169 
170  return(pid);
171 }
172 
173 /** Return the PID of the parent process */
174 const pid_t parent_pid(void)
175 {
176  pid_t pid;
177 
178  pid = getppid();
179  if (pid == -1)
180  throw(ERROR(errno,"Could not determine PID"));
181 
182  return(pid);
183 }
184 
185 /** Return true if the string looks like an absolute path */
186 bool absolute_path(const std::string& a_path)
187 {
188  if ((a_path.size() > 0) && (a_path[0] == '/')) {
189  return(true);
190  }
191  return(false);
192 }
193 
194 /** Return true if the string looks like a relative path */
195 bool relative_path(const std::string& a_path)
196 {
197  bool value;
198 
199  value = !absolute_path(a_path);
200 
201  return(value);
202 }
203 
204 /** Reformat a path to remove double slashes */
205 std::string reform_path(const std::string& a_path)
206 {
207  std::string::size_type idx;
208  std::string str;
209 
210  TRY_nomem(str = a_path);
211  idx = str.find('/');
212  while (idx != std::string::npos) {
213  while ((idx != str.size()-1) && (str[idx+1] == '/'))
214  str.erase(idx+1,1);
215  idx = str.find('/',idx+1);
216  }
217 
218  return(str);
219 }
220 
221 /** Reformat a path to remove the begining and trailing slashes, and replace
222  all other slashes with underscores
223  */
224 std::string permute_path(const std::string& a_path)
225 {
226  std::string path;
227  std::string::size_type idx;
228 
229  TRY_nomem(path = reform_path(a_path));
230  idx = path.find('/');
231  while (idx != std::string::npos) {
232  if ((idx == 0) || (idx == path.size()-1))
233  path.erase(idx,1);
234  else
235  path[idx] = '-';
236  idx = path.find('/');
237  }
238  if (path.size() == 0)
239  TRY_nomem(path = "root");
240  if (path.substr(0,2) == ".-")
241  path.erase(0,2);
242 
243  return(path);
244 }
245 
246 /** Return everything after the last slash from a path */
247 std::string path_basename(const std::string& a_path)
248 {
249  std::string path;
250  std::string::size_type idx;
251 
252  idx = a_path.rfind('/');
253  if (idx == std::string::npos) {
254  TRY_nomem(path = a_path);
255  }
256  else {
257  TRY_nomem(path = a_path.substr(idx+1));
258  }
259 
260  return(path);
261 }
262 
263 /** Return everything up to the last slash from a path */
264 std::string path_dirname(const std::string& a_path)
265 {
266  std::string path;
267  std::string::size_type idx;
268 
269  idx = a_path.rfind('/');
270  if (idx == std::string::npos) {
271  TRY_nomem(path = ".");
272  }
273  else {
274  TRY_nomem(path = a_path.substr(0,idx));
275  }
276 
277  return(path);
278 }
279 
280 /** Make the path a_rel_path absolute with respect to a_path, where a_rel_path
281  * and a_path are directory names */
282 std::string mk_absolute_path(
283  const std::string a_path,
284  const std::string a_rel_path
285  )
286 {
287  std::string es;
288  std::string path;
289 
290  if (a_rel_path.size() == 0) {
291  TRY_nomem(es = "Invalid relative path: \"");
292  TRY_nomem(es += a_rel_path);
293  TRY_nomem(es += "\"");
294  throw(ERROR(0,es));
295  }
296  if (relative_path(a_path)) {
297  TRY_nomem(es = "Invalid absolute reference path: \"");
298  TRY_nomem(es += a_path);
299  TRY_nomem(es += "\"");
300  throw(INTERNAL_ERROR(0,es));
301  }
302  if (relative_path(a_rel_path)) {
303  TRY_nomem(path = a_path);
304  TRY_nomem(path += "/");
305  }
306  TRY_nomem(path += a_rel_path);
307  path = reform_path(path);
308 
309  return(path);
310 }
311 
312 /** Make the path a_path_to relative from a_path_from, where a_path_to and
313  * a_path_from are directory names */
314 std::string mk_relative_path(
315  const std::string a_path_to,
316  const std::string a_path_from
317  )
318 {
319  std::string::size_type idx_to, idx_from, idx;
320  std::string path_to, path_from, path;
321  std::string path_to_substr, path_from_substr;
322 
323  TRY_nomem(path_to = a_path_to);
324  TRY_nomem(path_from = a_path_from);
325  TRY_nomem(path = "");
326 
327  idx_to = path_to.find("/");
328  if (idx_to != std::string::npos) {
329  TRY_nomem(path_to_substr = path_to.substr(0,idx_to));
330  }
331  else {
332  TRY_nomem(path_to_substr = path_to);
333  }
334  idx_from = path_from.find("/");
335  if (idx_from != std::string::npos) {
336  TRY_nomem(path_from_substr = path_from.substr(0,idx_from));
337  }
338  else {
339  TRY_nomem(path_from_substr = path_from);
340  }
341 
342  while (
343  (path_to.size() > 0 && path_from.size() > 0)
344  && (path_to_substr == path_from_substr)
345  )
346  {
347  path_to.erase(0,path_to_substr.size());
348  if ((path_to.size() > 0) && (path_to[0] == '/'))
349  path_to.erase(0,1);
350  path_from.erase(0,path_from_substr.size());
351  if ((path_from.size() > 0) && (path_from[0] == '/'))
352  path_from.erase(0,1);
353 
354  idx_to = path_to.find("/");
355  if (idx_to != std::string::npos) {
356  TRY_nomem(path_to_substr = path_to.substr(0,idx_to));
357  }
358  else {
359  TRY_nomem(path_to_substr = path_to);
360  }
361  idx_from = path_from.find("/");
362  if (idx_from != std::string::npos) {
363  TRY_nomem(path_from_substr = path_from.substr(0,idx_from));
364  }
365  else {
366  TRY_nomem(path_from_substr = path_from);
367  }
368  }
369 
370  while (path_from.size() > 0) {
371  TRY_nomem(path += "../");
372  idx = path_from.find('/');
373  if (idx == std::string::npos)
374  path_from.erase();
375  else
376  path_from.erase(0,idx+1);
377  }
378  TRY_nomem(path += path_to);
379  TRY_nomem(path = reform_path(path));
380 
381  return(path);
382 }
383 
384 /** Return true if the file or directory exists */
385 bool exists(const std::string& a_path)
386 {
387  if (access(a_path.c_str(), F_OK) == 0) return(true);
388  errno = 0;
389 #ifdef S_ISFIFO
390  if (is_fifo_special(a_path)) return(true);
391 #endif
392 #ifdef S_ISCHR
393  if (is_char_special(a_path)) return(true);
394 #endif
395 #ifdef S_ISDIR
396  if (is_dir(a_path)) return(true);
397 #endif
398 #ifdef S_ISREG
399  if (is_file(a_path)) return(true);
400 #endif
401 #ifdef S_ISBLK
402  if (is_block_special(a_path)) return(true);
403 #endif
404 #ifdef S_ISLNK
405  if (is_link(a_path)) return(true);
406 #endif
407 #ifdef S_ISSOCK
408  if (is_socket(a_path)) return(true);
409 #endif
410 #ifdef S_ISDOOR
411  if (is_door(a_path)) return(true);
412 #endif
413  return(false);
414 }
415 
416 /** Return true if the file or directory exists and is readable */
417 bool readable(const std::string& a_path)
418 {
419  if (access(a_path.c_str(), R_OK) != 0) {
420  errno = 0;
421  return(false);
422  }
423  return(true);
424 }
425 
426 /** Return true if the file or directory exists and is writable */
427 bool writable(const std::string& a_path)
428 {
429  if (access(a_path.c_str(), W_OK) != 0) {
430  errno = 0;
431  return(false);
432  }
433  return(true);
434 }
435 
436 /** Return true if the file or directory exists and is executable */
437 bool executable(const std::string& a_path)
438 {
439  if (access(a_path.c_str(), X_OK) != 0) {
440  errno = 0;
441  return(false);
442  }
443  return(true);
444 }
445 
446 #ifdef S_ISFIFO
447 /** Return true if the file is a fifo-special */
448 bool is_fifo_special(const std::string& a_path)
449 {
450  filestatus fstat;
451 
452  try {
453  fstat.path(a_path);
454  if (fstat.is_fifo_special()) {
455  return(true);
456  }
457  }
458  catch(...) {
459  return(false);
460  }
461  return(false);
462 }
463 #endif
464 
465 #ifdef S_ISCHR
466 /** Return true if the file is a char-special */
467 bool is_char_special(const std::string& a_path)
468 {
469  filestatus fstat;
470 
471  try {
472  fstat.path(a_path);
473  if (fstat.is_character_special()) {
474  return(true);
475  }
476  }
477  catch(...) {
478  return(false);
479  }
480  return(false);
481 }
482 #endif
483 
484 #ifdef S_ISDIR
485 /** Return true if the file is a directory */
486 bool is_dir(const std::string& a_path)
487 {
488  filestatus fstat;
489 
490  try {
491  fstat.path(a_path);
492  if (fstat.is_directory()) {
493  return(true);
494  }
495  }
496  catch(...) {
497  return(false);
498  }
499  return(false);
500 }
501 #endif
502 
503 #ifdef S_ISREG
504 /** Return true if the file is a regular file */
505 bool is_file(const std::string& a_path)
506 {
507  filestatus fstat;
508 
509  try {
510  fstat.path(a_path);
511  if (fstat.is_regular_file()) {
512  return(true);
513  }
514  }
515  catch(...) {
516  return(false);
517  }
518  return(false);
519 }
520 #endif
521 
522 #ifdef S_ISBLK
523 /** Return true if the file is a block-special */
524 bool is_block_special(const std::string& a_path)
525 {
526  filestatus fstat;
527 
528  try {
529  fstat.path(a_path);
530  if (fstat.is_block_special()) {
531  return(true);
532  }
533  }
534  catch(...) {
535  return(false);
536  }
537  return(false);
538 }
539 #endif
540 
541 #ifdef S_ISLNK
542 /** Return true is the file is a link */
543 bool is_link(const std::string& a_path)
544 {
545  filestatus fstat;
546 
547  try {
548  fstat.path(a_path);
549  if (fstat.is_link()) {
550  return(true);
551  }
552  }
553  catch(...) {
554  return(false);
555  }
556  return(false);
557 }
558 #endif
559 
560 #ifdef S_ISSOCK
561 /** Return true if the file is a socket */
562 bool is_socket(const std::string& a_path)
563 {
564  filestatus fstat;
565 
566  try {
567  fstat.path(a_path);
568  if (fstat.is_socket()) {
569  return(true);
570  }
571  }
572  catch(...) {
573  return(false);
574  }
575  return(false);
576 }
577 #endif
578 
579 #ifdef S_ISDOOR
580 /** Return true if the file is a door */
581 bool is_door(const std::string& a_path)
582 {
583  filestatus fstat;
584 
585  try {
586  fstat.path(a_path);
587  if (fstat.is_door()) {
588  return(true);
589  }
590  }
591  catch(...) {
592  return(false);
593  }
594  return(false);
595 }
596 #endif
597 
598 /** Create a directory */
599 void mk_dir(const std::string& a_path)
600 {
601  std::string es;
602 
603  if (mkdir(a_path.c_str(), ACCESSPERMS) != 0) {
604  TRY_nomem(es = "Could not create directory: \"");
605  TRY_nomem(es += a_path);
606  TRY_nomem(es += "\"");
607  throw(ERROR(errno,es));
608  }
609 }
610 
611 /** Remove a directory */
612 void rm_dir(const std::string a_path)
613 {
614  if (!exists(a_path)) return;
615  if ((rmdir(a_path.c_str()) != 0) && exists(a_path)) {
616  std::string es;
617 
618  TRY_nomem(es = "Could not remove directory: \"");
619  TRY_nomem(es += a_path);
620  TRY_nomem(es += "\"");
621 
622  if (exists(a_path)) {
623  if (writable(a_path)) {
624  throw(ERROR(errno,es));
625  }
626  else {
627  error e = ERROR(errno,es);
628 
629  e.push_back(ERROR_INSTANCE("No write permissions"));
630  throw(e);
631  }
632  }
633  }
634 }
635 
636 /** Remove a file */
637 void rm_file(const std::string a_path)
638 {
639  if (!exists(a_path)) return;
640  if ((unlink(a_path.c_str()) != 0) && exists(a_path)) {
641  std::string es;
642 
643  TRY_nomem(es = "Could not remove file: \"");
644  TRY_nomem(es += a_path);
645  TRY_nomem(es += "\"");
646 
647  if (exists(a_path)) {
648  if (writable(a_path)) {
649  throw(ERROR(errno,es));
650  }
651  else {
652  error e = ERROR(errno,es);
653 
654  e.push_back(ERROR_INSTANCE("No write permissions"));
655  throw(e);
656  }
657  }
658  }
659 }
660 
661 /** Recursively create a directory heirarchy */
662 void mk_dirhier_recursive_(const std::string a_path)
663 {
664  std::string parent_dir;
665  int ce;
666 
667  if (a_path.size() == 0)
668  return;
669  if (exists(a_path))
670  return;
671 
672  for (ce = a_path.size()-1; ((ce > 0) && (a_path[ce] != '/')); ce--);
673 
674  if (ce > 0) {
675  TRY_nomem(parent_dir = a_path.substr(0,ce));
676  mk_dirhier_recursive_(parent_dir);
677  }
678  if (!exists(a_path))
679  mk_dir(a_path);
680 }
681 
682 /** Recursively create a directory heirarchy */
683 void mk_dirhier(const std::string a_path)
684 {
685  if (a_path.size() == 0)
686  return;
687  if (exists(a_path))
688  return;
689 
690  try {
691  mk_dirhier_recursive_(a_path);
692  }
693  catch(error e) {
694  std::string es;
695 
696  TRY_nomem(es = "Could not create directory hierarchy: \"");
697  TRY_nomem(es += a_path);
698  TRY_nomem(es += "\"");
699 
700  e.push_back(ERROR_INSTANCE(es));
701  throw(e);
702  }
703  catch(...) {
704  throw(err_unknown);
705  }
706 }
707 
708 /** Rename a file or directory */
709 void rename_file(const std::string a_from, const std::string a_to)
710 {
711  std::string es;
712 
713  if (a_from.size() == 0) {
714  TRY_nomem(es = "Illegal from filename: \"");
715  TRY_nomem(es += a_from);
716  TRY_nomem(es += "\"");
717  throw(INTERNAL_ERROR(0,es));
718  }
719  if (!exists(a_from)) {
720  TRY_nomem(es = "From filename does not exist: \"");
721  TRY_nomem(es += a_from);
722  TRY_nomem(es += "\"");
723  throw(ERROR(0,es));
724  }
725  if (a_to.size() == 0) {
726  TRY_nomem(es = "Illegal to filename: \"");
727  TRY_nomem(es += a_to);
728  TRY_nomem(es += "\"");
729  throw(INTERNAL_ERROR(0,es));
730  }
731  if (exists(a_to)) {
732  TRY_nomem(es = "To filename already exists: \"");
733  TRY_nomem(es += a_to);
734  TRY_nomem(es += "\"");
735  throw(ERROR(0,es));
736  }
737  if (!writable(a_from)) {
738  TRY_nomem(es = "From filename is not writable: \"");
739  TRY_nomem(es += a_from);
740  TRY_nomem(es += "\"");
741  throw(ERROR(0,es));
742  }
743  if (rename(a_from.c_str(), a_to.c_str()) != 0) {
744  TRY_nomem(es = "Could not rename file: \"");
745  TRY_nomem(es += a_from);
746  TRY_nomem(es += "\" to \"");
747  TRY_nomem(es += a_to);
748  TRY_nomem(es += "\"");
749  throw(ERROR(errno,es));
750  }
751 }
752 
753 /** Create a symbolic link */
754 void mk_symlink(const std::string a_from, const std::string a_to)
755 {
756  if (symlink(a_from.c_str(), a_to.c_str()) != 0) {
757  std::string es;
758 
759  TRY_nomem(es = "Could not link: \"");
760  TRY_nomem(es += a_from);
761  TRY_nomem(es += "\" to: \"");
762  TRY_nomem(es += a_to);
763  TRY_nomem(es += "\"");
764 
765  throw(ERROR(errno,es));
766  }
767 }
768 
769 /** Given a from and to path, create a relative symbolic link */
770 void mk_relative_symlink(const std::string a_from, const std::string a_to)
771 {
772  std::string from_dirname, to_dirname, from_basename;
773  std::string rel;
774 
775  TRY_nomem(from_dirname = path_dirname(a_from));
776  TRY_nomem(to_dirname = path_dirname(a_to));
777  TRY_nomem(from_basename = path_basename(a_from));
778  TRY_nomem(rel = mk_relative_path(from_dirname, to_dirname));
779  if (rel.size() != 0) {
780  TRY_nomem(rel += "/");
781  }
782  TRY_nomem(rel += from_basename);
783  TRY_nomem(rel = reform_path(rel));
784 
785  try {
786  mk_symlink(rel,a_to);
787  }
788  catch(error e) {
789  std::string es;
790 
791  TRY_nomem(es = "Could not link: \"");
792  TRY_nomem(es += a_to);
793  TRY_nomem(es += "\" as: \"");
794  TRY_nomem(es += rel);
795  TRY_nomem(es += "\"");
796 
797  e.push_back(ERROR_INSTANCE(es));
798  throw(e);
799  }
800  catch(...) {
801  throw(err_unknown);
802  }
803 }
804 
805 //----------------------------------------------------------------------------
806 
807 /** C'tor */
809 {
810 }
811 
812 /** C'tor */
813 filestatus::filestatus(const std::string a_path)
814 {
815  path(a_path);
816 }
817 
818 /** D'tor */
820 {
821 }
822 
823 /** Retrieve information about a pathname */
824 void filestatus::path(const std::string a_path)
825 {
826  std::string es;
827  struct passwd *passwd_ptr = 0;
828  struct group *group_ptr = 0;
829  struct stat statbuf;
830  char path_buf[PATH_MAX] = { 0 };
831 
832  clear();
833  TRY_nomem(m_path = reform_path(a_path));
834  if (lstat(m_path.c_str(), &statbuf) < 0) {
835  TRY_nomem(es = "For path: \"");
836  TRY_nomem(es += a_path);
837  TRY_nomem(es += "\"");
838  throw(ERROR(errno,es));
839  }
840  if (lstat(m_path.c_str(), &m_stat) == -1) {
841  TRY_nomem(es = "For path: \"");
842  TRY_nomem(es += a_path);
843  TRY_nomem(es += "\"");
844  throw(ERROR(errno,es));
845  }
846 #ifdef S_ISFIFO
847  if (S_ISFIFO(m_stat.st_mode)) {
848  m_major = major(m_stat.st_rdev);
849  m_minor = minor(m_stat.st_rdev);
850  }
851 #endif
852 #ifdef S_ISCHR
853  if (S_ISCHR(m_stat.st_mode)) {
854  m_major = major(m_stat.st_rdev);
855  m_minor = minor(m_stat.st_rdev);
856  }
857 #endif
858 #ifdef S_ISBLK
859  if (S_ISBLK(m_stat.st_mode)) {
860  m_major = major(m_stat.st_rdev);
861  m_minor = minor(m_stat.st_rdev);
862  }
863 #endif
864 #ifdef S_ISLNK
865  if (S_ISLNK(m_stat.st_mode)) {
866  if (readlink(a_path.c_str(), path_buf, PATH_MAX) < 0) {
867  TRY_nomem(es = "Could not read path's link: \"");
868  TRY_nomem(es += a_path);
869  TRY_nomem(es += "\"");
870  throw(ERROR(errno,es));
871  }
872  TRY_nomem(m_link = path_buf);
873  }
874 #endif
875  passwd_ptr = getpwuid(m_stat.st_uid);
876  if (passwd_ptr != 0) {
877  m_uidfound = true;
878  TRY_nomem(m_uname = passwd_ptr->pw_name);
879  }
880  group_ptr = getgrgid(m_stat.st_gid);
881  if (group_ptr != 0) {
882  m_gidfound = true;
883  TRY_nomem(m_gname = group_ptr->gr_name);
884  }
885 }
886 
887 /** Return the pathname that this filestatus object has information about */
888 const std::string filestatus::path(void) const
889 {
890  return(m_path);
891 }
892 
893 /** Return the type of file */
895 {
896 #ifdef S_ISFIFO
897  if (S_ISFIFO(m_stat.st_mode)) {
898  return(type_fifo_special);
899  }
900 #endif
901 #ifdef S_ISCHR
902  if (S_ISCHR(m_stat.st_mode)) {
903  return(type_character_special);
904  }
905 #endif
906 #ifdef S_ISDIR
907  if (S_ISDIR(m_stat.st_mode)) {
908  return(type_directory);
909  }
910 #endif
911 #ifdef S_ISBLK
912  if (S_ISBLK(m_stat.st_mode)) {
913  return(type_block_special);
914  }
915 #endif
916 #ifdef S_ISREG
917  if (S_ISREG(m_stat.st_mode)) {
918  return(type_regular_file);
919  }
920 #endif
921 #ifdef S_ISLNK
922  if (S_ISLNK(m_stat.st_mode)) {
923  return(type_link);
924  }
925 #endif
926 #ifdef S_ISSOCK
927  if (S_ISSOCK(m_stat.st_mode)) {
928  return(type_socket);
929  }
930 #endif
931 #ifdef S_ISDOOR
932  if (S_ISDOOR(m_stat.st_mode)) {
933  return(type_door);
934  }
935 #endif
936  return(type_unknown);
937 }
938 
939 /** If the pathname is a link, return the path it is linked to */
940 const std::string filestatus::link(void) const
941 {
942  return(m_link);
943 }
944 
945 /** Return the file mode */
947 {
948  return(m_stat.st_mode);
949 }
950 
951 /** Return the file inode */
953 {
954  return(m_stat.st_ino);
955 }
956 
957 /** Return the file's device */
959 {
960  return(m_stat.st_dev);
961 }
962 
963 /** Return the file's raw device */
965 {
966  return(m_stat.st_rdev);
967 }
968 
969 /** If the pathname is a special file, return it's major number */
971 {
972  return(m_major);
973 }
974 
975 /** If the pathname is a special file, return it's minor number */
977 {
978  return(m_minor);
979 }
980 
981 /** Return the number of links to this file */
983 {
984  return(m_stat.st_nlink);
985 }
986 
987 /** Return the file's owner's UID */
989 {
990  return(m_stat.st_uid);
991 }
992 
993 /** Return the file's owner's GID */
995 {
996  return(m_stat.st_gid);
997 }
998 
999 /** Return the file size in bytes */
1001 {
1002  size_type value;
1003 
1004  value = static_cast<uint64>(m_stat.st_size);
1005 
1006  return(value);
1007 }
1008 
1009 /** Return the last access time of this file */
1011 {
1012  return(m_stat.st_atime);
1013 }
1014 
1015 /** Return the last modification time of this file */
1017 {
1018  return(m_stat.st_mtime);
1019 }
1020 
1021 /** Return the last status change time of this file */
1023 {
1024  return(m_stat.st_ctime);
1025 }
1026 
1027 /** Return the blocksize used to store this file */
1029 {
1030  size_type value;
1031 
1032  value = static_cast<uint64>(m_stat.st_blksize);
1033 
1034  return(value);
1035 }
1036 
1037 /** Return the number of blocks used to store this file */
1039 {
1040  size_type value;
1041 
1042  value = static_cast<uint64>(m_stat.st_blocks);
1043 
1044  return(value);
1045 }
1046 
1047 /** If the file's owner's UID is found in the passwd file, return true */
1048 const bool filestatus::uid_is_found(void) const
1049 {
1050  return(m_uidfound);
1051 }
1052 
1053 /** If the file's owner's GID is found in the passwd file, return true */
1054 const bool filestatus::gid_is_found(void) const
1055 {
1056  return(m_gidfound);
1057 }
1058 
1059 /** Return the file's owner's user name (from UID) */
1060 const std::string filestatus::uid_name(void) const
1061 {
1062  return(m_uname);
1063 }
1064 
1065 /** Return the file's owner's group name (from UID) */
1066 const std::string filestatus::gid_name(void) const
1067 {
1068  return(m_gname);
1069 }
1070 
1071 #ifdef S_ISFIFO
1072 /** Return true if the file is a fifo-special */
1073 const bool filestatus::is_fifo_special(void) const
1074 {
1075  bool value;
1076 
1077  value = (type() == type_fifo_special);
1078 
1079  return(value);
1080 }
1081 #endif
1082 
1083 #ifdef S_ISCHR
1084 /** Return true if the file is a char-special */
1085 const bool filestatus::is_character_special(void) const
1086 {
1087  bool value;
1088 
1089  value = (type() == type_character_special);
1090 
1091  return(value);
1092 }
1093 #endif
1094 
1095 #ifdef S_ISBLK
1096 /** Return true if the file is a block-special */
1097 const bool filestatus::is_block_special(void) const
1098 {
1099  bool value;
1100 
1101  value = (type() == type_block_special);
1102 
1103  return(value);
1104 }
1105 #endif
1106 
1107 #ifdef S_ISLNK
1108 /** Return true if the file is a link */
1109 const bool filestatus::is_link(void) const
1110 {
1111  bool value;
1112 
1113  value = (type() == type_link);
1114 
1115  return(value);
1116 }
1117 #endif
1118 
1119 #ifdef S_ISSOCK
1120 /** Return true if the file is a socket */
1121 const bool filestatus::is_socket(void) const
1122 {
1123  bool value;
1124 
1125  value = (type() == type_socket);
1126 
1127  return(value);
1128 }
1129 #endif
1130 
1131 #ifdef S_ISDOOR
1132 /** Return true if the file is a door */
1133 const bool filestatus::is_door(void) const
1134 {
1135  bool value;
1136 
1137  value = (type() == type_door);
1138 
1139  return(value);
1140 }
1141 #endif
1142 
1143 #ifdef S_ISDIR
1144 /** Return true if the file is a directory */
1145 const bool filestatus::is_directory(void) const
1146 {
1147  bool value;
1148 
1149  value = (type() == type_directory);
1150 
1151  return(value);
1152 }
1153 #endif
1154 
1155 #ifdef S_ISREG
1156 /** Return true if the file is a regular file */
1157 const bool filestatus::is_regular_file(void) const
1158 {
1159  bool value;
1160 
1161  value = (type() == type_regular_file);
1162 
1163  return(value);
1164 }
1165 #endif
1166 
1167 #ifdef S_IRUSR
1168 /** Return true if the file is readable by it's owner */
1169 const bool filestatus::user_can_read(void) const
1170 {
1171  bool value;
1172 
1173  value = ((m_stat.st_mode & S_IRUSR) != 0);
1174 
1175  return(value);
1176 }
1177 #endif
1178 
1179 #ifdef S_IWUSR
1180 /** Return true if the file is writable by it's owner */
1181 const bool filestatus::user_can_write(void) const
1182 {
1183  bool value;
1184 
1185  value = ((m_stat.st_mode & S_IWUSR) != 0);
1186 
1187  return(value);
1188 }
1189 #endif
1190 
1191 #ifdef S_IXUSR
1192 /** Return true if the file is executable by it's owner */
1193 const bool filestatus::user_can_execute(void) const
1194 {
1195  bool value;
1196 
1197  value = ((m_stat.st_mode & S_IXUSR) != 0);
1198 
1199  return(value);
1200 }
1201 #endif
1202 
1203 #ifdef S_IRGRP
1204 /** Return true if the file is readable by users in the same group */
1205 const bool filestatus::group_can_read(void) const
1206 {
1207  bool value;
1208 
1209  value = ((m_stat.st_mode & S_IRGRP) != 0);
1210 
1211  return(value);
1212 }
1213 #endif
1214 
1215 #ifdef S_IWGRP
1216 /** Return true if the file is writable by users in the same group */
1217 const bool filestatus::group_can_write(void) const
1218 {
1219  bool value;
1220 
1221  value = ((m_stat.st_mode & S_IWGRP) != 0);
1222 
1223  return(value);
1224 }
1225 #endif
1226 
1227 #ifdef S_IXGRP
1228 /** Return true if the file is executable by users in the same group */
1229 const bool filestatus::group_can_execute(void) const
1230 {
1231  bool value;
1232 
1233  value = ((m_stat.st_mode & S_IXGRP) != 0);
1234 
1235  return(value);
1236 }
1237 #endif
1238 
1239 #ifdef S_IROTH
1240 /** Return true if the file is readable by others */
1241 const bool filestatus::other_can_read(void) const
1242 {
1243  bool value;
1244 
1245  value = ((m_stat.st_mode & S_IROTH) != 0);
1246 
1247  return(value);
1248 }
1249 #endif
1250 
1251 #ifdef S_IWOTH
1252 /** Return true if the file is writable by others */
1253 const bool filestatus::other_can_write(void) const
1254 {
1255  bool value;
1256 
1257  value = ((m_stat.st_mode & S_IWOTH) != 0);
1258 
1259  return(value);
1260 }
1261 #endif
1262 
1263 #ifdef S_IXOTH
1264 /** Return true if the file is executable by others */
1265 const bool filestatus::other_can_execute(void) const
1266 {
1267  bool value;
1268 
1269  value = ((m_stat.st_mode & S_IXOTH) != 0);
1270 
1271  return(value);
1272 }
1273 #endif
1274 
1275 #ifdef S_ISUID
1276 /** Return true if the file's mode has it's set-uid bit set */
1277 const bool filestatus::is_set_uid(void) const
1278 {
1279  bool value;
1280 
1281  value = ((m_stat.st_mode & S_ISUID) != 0);
1282 
1283  return(value);
1284 }
1285 #endif
1286 
1287 #ifdef S_ISGID
1288 /** Return true if the file's mode has it's set-gid bit set */
1289 const bool filestatus::is_set_gid(void) const
1290 {
1291  bool value;
1292 
1293  value = ((m_stat.st_mode & S_ISGID) != 0);
1294 
1295  return(value);
1296 }
1297 #endif
1298 
1299 #ifdef S_ISVTX
1300 /** Return true if the file's mode has it's sticky bit set */
1301 const bool filestatus::is_set_sticky(void) const
1302 {
1303  bool value;
1304 
1305  value = ((m_stat.st_mode & S_ISVTX) != 0);
1306 
1307  return(value);
1308 }
1309 #endif
1310 
1311 /** Clear all values */
1313 {
1314  TRY_nomem(m_path = "");
1315  memset(&m_stat, 0, sizeof(m_stat));
1316  m_major = 0;
1317  m_minor = 0;
1318  m_uidfound = false;
1319  m_gidfound = false;
1320  TRY_nomem(m_uname = "");
1321  TRY_nomem(m_gname = "");
1322 }
1323 
1324 //----------------------------------------------------------------------------
1325 
1326 /** C'tor */
1328 {
1329 }
1330 
1331 /** C'tor */
1333 {
1334  assign(a_class);
1335 }
1336 
1337 /** C'or */
1339  const std::string a_path, const std::string a_filter)
1340 {
1341  path(a_path, a_filter);
1342 }
1343 
1344 /** D'tor */
1346 {
1347 }
1348 
1349 /** Assign the contents of a given subdirectory to this subdirectory */
1351 {
1352  type::assign(a_class.begin(), a_class.end());
1353 }
1354 
1355 /** Return a vector of strings of a list of files in a subdirectory
1356 
1357  Files in the list do not contain the pathname to the file. Only filenames
1358  that match the given wildcard filter will be listed.
1359  */
1360 const subdirectory::type&
1361  subdirectory::path(const std::string a_path, const std::string a_filter)
1362 {
1363  std::string es;
1364  std::string name;
1365  DIR *dp = 0;
1366  struct dirent *dirp = 0;
1367  filestatus filestat;
1368 
1369  clear();
1370 
1371  TRY(filestat.path(a_path),"Could not stat directory");
1372 
1373  dp = opendir(a_path.c_str());
1374  if (dp == 0) {
1375  TRY_nomem(es = "For path: \"");
1376  TRY_nomem(es += a_path);
1377  TRY_nomem(es += "\"");
1378  throw(ERROR(errno,es));
1379  }
1380  while ( (dirp = readdir(dp)) != 0 ) {
1381  name = dirp->d_name;
1382  if (
1383  ((a_filter != ".") && (a_filter != ".."))
1384  &&
1385  ((name == ".") || (name == ".."))
1386  )
1387  continue;
1388  if (fnmatch(a_filter.c_str(), name.c_str(), 0) == 0) {
1389  TRY_nomem(type::push_back(name));
1390  }
1391  }
1392  if (closedir(dp) < 0) {
1393  TRY_nomem(es = "Error closing directory \"");
1394  TRY_nomem(es += a_path);
1395  TRY_nomem(es += "\"");
1396  throw(ERROR(errno,es));
1397  }
1398 
1399  std::sort(begin(), end());
1400 
1401  return(*this);
1402 }
1403 
1405 {
1406  assign(a_class);
1407 
1408  return(*this);
1409 }
1410 
1411 //----------------------------------------------------------------------------
1412 
1413 /** Recursively delete the contents of a directory */
1414 void rm_recursive(const std::string a_path)
1415 {
1416  subdirectory d;
1417  subdirectory::const_iterator di;
1418  filestatus f;
1419  std::string pathstr;
1420  std::string es;
1421  mode_t mode = 0;
1422 
1423  mode = 0;
1424  mode |= S_IWUSR|S_IXUSR;
1425  mode |= S_IWGRP|S_IXGRP;
1426  mode |= S_IWOTH|S_IXOTH;
1427 
1428  TRY_nomem(es = "Could not recursively delete: \"");
1429  TRY_nomem(es += a_path);
1430  TRY_nomem(es += "\"");
1431 
1432  if (!exists(a_path)) {
1433  if (is_link(a_path)) {
1434  if (!writable(a_path)) {
1435  if (chmod(a_path.c_str(), mode) != 0)
1436  throw(ERROR(errno,es));
1437  }
1438  TRY(rm_file(a_path),es);
1439  }
1440  return;
1441  }
1442  TRY(f.path(a_path),es);
1443  if (f.is_directory()) {
1444  TRY(d.path(a_path),es);
1445  if (d.size() != 0) {
1446 
1447  for (di = d.begin(); di != d.end(); ++di) {
1448  TRY_nomem(
1449  pathstr = static_cast<std::string>(a_path)
1450  + static_cast<std::string>("/")
1451  + static_cast<std::string>(*di)
1452  );
1453  TRY(f.path(pathstr),es);
1454  if (f.is_directory()) {
1455  if (!writable(a_path)) {
1456  if (chmod(a_path.c_str(), mode) != 0)
1457  throw(ERROR(errno,es));
1458  }
1459  TRY(rm_recursive(pathstr),es);
1460  }
1461  else {
1462  if (!writable(a_path)) {
1463  if (chmod(a_path.c_str(), mode) != 0)
1464  throw(ERROR(errno,es));
1465  }
1466  rm_file(pathstr);
1467  }
1468  }
1469  }
1470  if (!writable(a_path)) {
1471  if (chmod(a_path.c_str(), mode) != 0)
1472  throw(ERROR(errno,es));
1473  }
1474  rm_dir(a_path);
1475  }
1476  else {
1477  if (!writable(a_path)) {
1478  if (chmod(a_path.c_str(), mode) != 0)
1479  throw(ERROR(errno,es));
1480  }
1481  rm_file(a_path);
1482  }
1483 }
1484 
1485 //----------------------------------------------------------------------------
1486 
1487 /** C'tor */
1489 {
1490 }
1491 
1492 /** C'tor */
1494 {
1495  // TODO: Isn't this supposed to do something!?
1496 }
1497 
1498 /** C'tor */
1499 directory::directory(const std::string& a_str)
1500 {
1501  path(a_str);
1502 }
1503 
1504 /** D'tor */
1506 {
1507 }
1508 
1509 /** Retrieve a list of paths that match the wildcard path given */
1510 const directory::type& directory::path(const std::string& a_path)
1511 {
1512  std::string es;
1513  std::string::size_type idx;
1514  std::string path;
1515  std::string subdir_path;
1516  std::string new_subdir_path;
1517  subdirectory subdir;
1518  subdirectory::const_iterator sdi;
1519  filestatus filestat;
1520  const_iterator di;
1521  type list;
1522 
1523  TRY_nomem(path = reform_path(a_path));
1524  if (path.size() == 0) {
1525  return(*this);
1526  }
1527 
1528  idx = path.find('/');
1529  if (idx != std::string::npos) {
1530  TRY_nomem(subdir_path = path.substr(0,idx));
1531  path.erase(0,idx+1);
1532  }
1533  else {
1534  TRY_nomem(subdir_path = path);
1535  path.erase();
1536  }
1537  if (subdir_path.size() == 0)
1538  TRY_nomem(subdir_path = "/");
1539 
1540  if (!exists(subdir_path)) {
1541  return(*this);
1542  }
1543  TRY_nomem(push_back(subdir_path));
1544 
1545  while (path.size() != 0) {
1546  idx = path.find('/');
1547  if (idx != std::string::npos) {
1548  TRY_nomem(subdir_path = path.substr(0,idx));
1549  path.erase(0,idx+1);
1550  }
1551  else {
1552  TRY_nomem(subdir_path = path);
1553  path.erase();
1554  }
1555  list.clear();
1556  for (di = begin(); di != end(); di++) {
1557  TRY_nomem(list.push_back(*di));
1558  }
1559  clear();
1560  for (di = list.begin(); di != list.end(); di++) {
1561  filestat.path(*di);
1562  if (!filestat.is_directory())
1563  continue;
1564  subdir.path(*di, subdir_path);
1565  for (sdi = subdir.begin(); sdi != subdir.end(); sdi++) {
1566  TRY_nomem(new_subdir_path = *di);
1567  TRY_nomem(new_subdir_path += "/");
1568  TRY_nomem(new_subdir_path += *sdi);
1569  TRY_nomem(new_subdir_path = reform_path(new_subdir_path));
1570  TRY_nomem(push_back(new_subdir_path));
1571  }
1572  }
1573  }
1574  return(*this);
1575 }
1576 
1577 //----------------------------------------------------------------------------
1578 
1579 /** C'tor */
1581 {
1582  clear();
1583 }
1584 
1585 /** C'tor */
1586 filesystem::filesystem(const std::string& a_path)
1587 {
1588  clear();
1589  path(a_path);
1590 }
1591 
1592 /** Clear the filesystem object */
1594 {
1595  TRY_nomem(m_path = "");
1596  memset(&m_statfs, 0, sizeof(m_statfs));
1597 }
1598 
1599 /** Retrieve information about the filesystem on which the given path resides */
1600 void filesystem::path(const std::string& a_path)
1601 {
1602  std::string es;
1603 
1604  TRY_nomem(m_path = reform_path(a_path));
1605  if (STATFS(a_path.c_str(), &m_statfs) != 0) {
1606  TRY_nomem(es = "Could not stat filesystem: \"");
1607  TRY_nomem(es += a_path);
1608  TRY_nomem(es += "\"");
1609  throw(ERROR(errno,es));
1610  }
1611 }
1612 
1613 /** Return the path from which this filesystem information was obtained */
1614 const std::string filesystem::path(void) const
1615 {
1616  return(m_path);
1617 }
1618 
1619 /** Return the filesystem block size */
1621 {
1622  size_type value;
1623 
1624  value = static_cast<uint64>(m_statfs.f_bsize);
1625 
1626  return(value);
1627 }
1628 
1629 /** Return the filesystem's total number of blocks */
1631 {
1632  size_type value;
1633 
1634  value = static_cast<uint64>(m_statfs.f_blocks);
1635 
1636  return(value);
1637 }
1638 
1639 /** Return the filesystem's number of free blocks */
1641 {
1642  size_type value;
1643 
1644  value = static_cast<uint64>(m_statfs.f_bfree);
1645 
1646  return(value);
1647 }
1648 
1649 /** Return the filesystem's number of used blocks */
1651 {
1652  size_type value;
1653 
1654  value = total_blocks() - free_blocks();
1655 
1656  return(value);
1657 }
1658 
1659 /** Return the filesystem's total number of inodes, if supported by the
1660  filesystem, otherwise the result is system-dependent, but usually 0.
1661  */
1663 {
1664  size_type value;
1665 
1666  value = static_cast<uint64>(m_statfs.f_files);
1667 
1668  return(value);
1669 }
1670 
1671 /** Return the filesystem's total number of free inodes, if supported by the
1672  filesystem, otherwise the result is system-dependent, but usually 0.
1673  */
1675 {
1676  size_type value;
1677 
1678  value = static_cast<uint64>(m_statfs.f_ffree);
1679 
1680  return(value);
1681 }
1682 
1683 /** Return the filesystem's number of used inodes */
1685 {
1686  size_type value;
1687 
1688  value = total_inodes() - free_inodes();
1689 
1690  return(value);
1691 }
1692 
1693 /** Copy values from another instance */
1695 {
1696  TRY_nomem(m_path = a_class.m_path);
1697  memcpy(&m_statfs, &a_class.m_statfs, sizeof(m_statfs));
1698 
1699  return(*this);
1700 }
1701 
1702 //----------------------------------------------------------------------------
1703 
1704 /** C'tor */
1706 {
1707  clear();
1708 }
1709 
1710 /** C'tor */
1711 simple_lock::simple_lock(const std::string& a_lockfile)
1712 {
1713  clear();
1714  lockfile(a_lockfile);
1715 }
1716 
1717 /** D'tor */
1719 {
1720  clear();
1721 }
1722 
1723 /** Clear the simple_lock object */
1725 {
1726  if (is_locked() && (locked_by() == getpid())) {
1727  unlock();
1728  }
1729  m_lockfile.clear();
1730 }
1731 
1732 /** Set the lockfile path */
1733 void simple_lock::lockfile(const std::string& a_lockfile)
1734 {
1735  clear();
1736  m_lockfile = a_lockfile;
1737 }
1738 
1739 /** Get the lockfile path */
1740 const std::string simple_lock::lockfile(void) const
1741 {
1742  return(m_lockfile);
1743 }
1744 
1745 /** Get the PID of the locking process */
1747 {
1749  std::ifstream in;
1750 
1751  pid = 0;
1752  if (m_lockfile.size() == 0) return(0);
1753  if (!exists(m_lockfile)) return(0);
1754  in.open(m_lockfile.c_str());
1755  if (!in.is_open()) return(0);
1756  in >> pid;
1757  if (!in) {
1758  in.close();
1759  return(0);
1760  }
1761  return(pid);
1762 }
1763 
1764 /** Find out whether or not the lock is in place */
1765 const bool simple_lock::is_locked(void) const
1766 {
1768 
1769  pid = locked_by();
1770  if (pid == 0) return(false);
1771  if (pid == getpid()) return(true);
1772  if (kill(pid,0) >= 0) return(true);
1773  errno = 0;
1774  return(false);
1775 }
1776 
1777 /** Lock */
1779 {
1780  std::ofstream out;
1782 
1783  if (is_locked()) return(false);
1784  if (m_lockfile.size() == 0) return(false);
1785  out.open(m_lockfile.c_str());
1786  if (!out.is_open()) return(false);
1787  pid = getpid();
1788  out << pid << std::endl;
1789  if (!out) {
1790  clear();
1791  return(false);
1792  }
1793  out.close();
1794  return(true);
1795 }
1796 
1797 /** Unlock */
1799 {
1800  std::string es;
1801 
1802  if (m_lockfile.size() == 0) return;
1803  if (!exists(m_lockfile)) return;
1804  TRY_nomem(es = "Cannot unlock: \"");
1805  TRY_nomem(es += m_lockfile);
1806  TRY_nomem(es += "\"");
1807  TRY(rm_file(m_lockfile),es);
1808 }
1809 
1810 //----------------------------------------------------------------------------
1811 
const pid_t pid(void)
Return the PID of this process.
Definition: fs.cc:162
void mk_dirhier_recursive_(const std::string a_path)
Recursively create a directory heirarchy.
Definition: fs.cc:662
std::string reform_path(const std::string &a_path)
Reformat a path to remove double slashes.
Definition: fs.cc:205
filesystem()
C'tor.
Definition: fs.cc:1580
const std::string cwd(void)
Return the current working directory.
Definition: fs.cc:148
Retrieve information about a filesystem.
Definition: fs.h:316
const size_type total_inodes(void) const
Return the filesystem's total number of inodes, if supported by the filesystem, otherwise the result ...
Definition: fs.cc:1662
void mk_dir(const std::string &a_path)
Create a directory.
Definition: fs.cc:599
void path(const std::string a_path)
Retrieve information about a pathname.
Definition: fs.cc:824
uint64 size_type
Definition: fs.h:160
std::string path_basename(const std::string &a_path)
Return everything after the last slash from a path.
Definition: fs.cc:247
const type & path(const std::string &a_path)
Retrieve a list of paths that match the wildcard path given.
Definition: fs.cc:1510
~directory()
D'tor.
Definition: fs.cc:1505
bool executable(const std::string &a_path)
Return true if the file or directory exists and is executable.
Definition: fs.cc:437
const pid_t parent_pid(void)
Return the PID of the parent process.
Definition: fs.cc:174
dev_t device_type
Definition: fs.h:154
const size_type blocks(void) const
Return the number of blocks used to store this file.
Definition: fs.cc:1038
filetype
Definition: fs.h:125
void push_back(const error_instance &a_e)
Definition: error.cc:215
void mk_dirhier(const std::string a_path)
Recursively create a directory heirarchy.
Definition: fs.cc:683
uint32 minor_type
Definition: fs.h:156
const bool gid_is_found(void) const
If the file's owner's GID is found in the passwd file, return true.
Definition: fs.cc:1054
bool writable(const std::string &a_path)
Return true if the file or directory exists and is writable.
Definition: fs.cc:427
bool lock(void)
Lock.
Definition: fs.cc:1778
const bool uid_is_found(void) const
If the file's owner's UID is found in the passwd file, return true.
Definition: fs.cc:1048
const size_type blocksize(void) const
Return the filesystem block size.
Definition: fs.cc:1620
const inode_type inode(void) const
Return the file inode.
Definition: fs.cc:952
const std::string link(void) const
If the pathname is a link, return the path it is linked to.
Definition: fs.cc:940
struct STATFS m_statfs
Definition: fs.h:339
bool readable(const std::string &a_path)
Return true if the file or directory exists and is readable.
Definition: fs.cc:417
uint64 size_type
Definition: fs.h:318
std::string m_uname
Definition: fs.h:264
const size_type used_blocks(void) const
Return the filesystem's number of used blocks.
Definition: fs.cc:1650
std::string m_link
Definition: fs.h:259
#define err_unknown
Definition: error.h:114
Retrieve a list of pathnames that match a given wildcard path.
Definition: fs.h:300
~simple_lock()
D'tor.
Definition: fs.cc:1718
const time_type last_status_change_time(void) const
Return the last status change time of this file.
Definition: fs.cc:1022
filestatus()
C'tor.
Definition: fs.cc:808
std::string m_path
Definition: fs.h:338
uint32 major_type
Definition: fs.h:155
const size_type blocksize(void) const
Return the blocksize used to store this file.
Definition: fs.cc:1028
std::string mk_absolute_path(const std::string a_path, const std::string a_rel_path)
Make the path a_rel_path absolute with respect to a_path, where a_rel_path and a_path are directory n...
Definition: fs.cc:282
directory()
C'tor.
Definition: fs.cc:1488
struct stat m_stat
Definition: fs.h:258
const std::string lockfile(void) const
Get the lockfile path.
Definition: fs.cc:1740
const mode_type mode(void) const
Return the file mode.
Definition: fs.cc:946
filesystem & operator=(const filesystem &a_class)
Copy values from another instance.
Definition: fs.cc:1694
std::vector< std::string > type
Definition: fs.h:303
bool relative_path(const std::string &a_path)
Return true if the string looks like a relative path.
Definition: fs.cc:195
bool exists(const std::string &a_path)
Return true if the file or directory exists.
Definition: fs.cc:385
#define TRY_nomem(code)
Definition: error.h:144
mode_t mode_type
Definition: fs.h:152
void unlock(void)
Unlock.
Definition: fs.cc:1798
void rm_dir(const std::string a_path)
Remove a directory.
Definition: fs.cc:612
An error class.
Definition: error.h:72
nlink_t num_links_type
Definition: fs.h:157
std::string m_lockfile
Definition: fs.h:361
const type & path(const std::string a_path, const std::string a_filter="*")
Return a vector of strings of a list of files in a subdirectory.
Definition: fs.cc:1361
minor_type m_minor
Definition: fs.h:261
void mk_relative_symlink(const std::string a_from, const std::string a_to)
Given a from and to path, create a relative symbolic link.
Definition: fs.cc:770
const pid_type locked_by(void) const
Get the PID of the locking process.
Definition: fs.cc:1746
time_t time_type
Definition: fs.h:161
const filetype type(void) const
Return the type of file.
Definition: fs.cc:894
const size_type free_inodes(void) const
Return the filesystem's total number of free inodes, if supported by the filesystem, otherwise the result is system-dependent, but usually 0.
Definition: fs.cc:1674
#define TRY(code, es)
Definition: error.h:126
void rm_recursive(const std::string a_path)
Recursively delete the contents of a directory.
Definition: fs.cc:1414
gid_t gid_type
Definition: fs.h:159
const std::string uid_name(void) const
Return the file's owner's user name (from UID)
Definition: fs.cc:1060
#define INTERNAL_ERROR(e, s)
Definition: error.h:123
const uid_type uid(void) const
Return the file's owner's UID.
Definition: fs.cc:988
const time_type last_modification_time(void) const
Return the last modification time of this file.
Definition: fs.cc:1016
const minor_type get_minor(void) const
If the pathname is a special file, return it's minor number.
Definition: fs.cc:976
std::string m_gname
Definition: fs.h:265
const device_type dev(void) const
Return the file's device.
Definition: fs.cc:958
Retrieve information about a file or directory.
Definition: fs.h:122
uid_t uid_type
Definition: fs.h:158
major_type m_major
Definition: fs.h:260
void clear(void)
Clear the simple_lock object.
Definition: fs.cc:1724
std::string permute_path(const std::string &a_path)
Reformat a path to remove the begining and trailing slashes, and replace all other slashes with under...
Definition: fs.cc:224
std::string mk_relative_path(const std::string a_path_to, const std::string a_path_from)
Make the path a_path_to relative from a_path_from, where a_path_to and a_path_from are directory name...
Definition: fs.cc:314
const std::string path(void) const
Return the pathname that this filestatus object has information about.
Definition: fs.cc:888
const size_type used_inodes(void) const
Return the filesystem's number of used inodes.
Definition: fs.cc:1684
bool absolute_path(const std::string &a_path)
Return true if the string looks like an absolute path.
Definition: fs.cc:186
pid_t pid_type
Definition: fs.h:345
void clear(void)
Clear all values.
Definition: fs.cc:1312
const size_type free_blocks(void) const
Return the filesystem's number of free blocks.
Definition: fs.cc:1640
const std::string gid_name(void) const
Return the file's owner's group name (from UID)
Definition: fs.cc:1066
~subdirectory()
D'tor.
Definition: fs.cc:1345
#define ERROR_INSTANCE(s)
Definition: error.h:67
std::string m_path
Definition: fs.h:257
#define ACCESSPERMS
Definition: fs.cc:142
const size_type size(void) const
Return the file size in bytes.
Definition: fs.cc:1000
void assign(const subdirectory &a_class)
Assign the contents of a given subdirectory to this subdirectory.
Definition: fs.cc:1350
const gid_type gid(void) const
Return the file's owner's GID.
Definition: fs.cc:994
void rm_file(const std::string a_path)
Remove a file.
Definition: fs.cc:637
simple_lock()
C'tor.
Definition: fs.cc:1705
std::vector< std::string > type
Definition: fs.h:276
bool m_uidfound
Definition: fs.h:262
#define STATFS
Definition: fs.h:62
#define ERROR(e, s)
Definition: error.h:120
void rename_file(const std::string a_from, const std::string a_to)
Rename a file or directory.
Definition: fs.cc:709
const num_links_type num_links(void) const
Return the number of links to this file.
Definition: fs.cc:982
const time_type last_access_time(void) const
Return the last access time of this file.
Definition: fs.cc:1010
Retrieve a list of files in a subdirectory that match a given wildcard filename.
Definition: fs.h:273
ino_t inode_type
Definition: fs.h:153
void clear(void)
Clear the filesystem object.
Definition: fs.cc:1593
const device_type rdev(void) const
Return the file's raw device.
Definition: fs.cc:964
bool m_gidfound
Definition: fs.h:263
std::string path_dirname(const std::string &a_path)
Return everything up to the last slash from a path.
Definition: fs.cc:264
const std::string path(void) const
Return the path from which this filesystem information was obtained.
Definition: fs.cc:1614
const major_type get_major(void) const
If the pathname is a special file, return it's major number.
Definition: fs.cc:970
const size_type total_blocks(void) const
Return the filesystem's total number of blocks.
Definition: fs.cc:1630
const bool is_locked(void) const
Find out whether or not the lock is in place.
Definition: fs.cc:1765
~filestatus()
D'tor.
Definition: fs.cc:819
subdirectory & operator=(const subdirectory &a_class)
Definition: fs.cc:1404
subdirectory()
C'tor.
Definition: fs.cc:1327
void mk_symlink(const std::string a_from, const std::string a_to)
Create a symbolic link.
Definition: fs.cc:754