6 #ifdef STAT_MACROS_BROKEN
7 #error Sorry, S_ISDIR, S_ISREG et. al. appear to be broken on this system.
13 #ifdef HAVE_SYS_MKDEV_H
14 #include <sys/mkdev.h>
16 #ifdef HAVE_SYS_TYPES_H
17 #include <sys/types.h>
19 #ifdef HAVE_SYS_STAT_H
26 #ifdef TIME_WITH_SYS_TIME
30 #ifdef HAVE_SYS_TIME_H
39 #define NAMELEN(dirent) strlen((dirent)->d_name)
42 #define NAMELEN(dirent) (dirent)->d_namlen
43 #ifdef HAVE_SYS_NDIR_H
69 #define S_IFMT (S_IFREG|S_IFCHR|S_IFBLK|S_IFIFO)
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\
83 #define S_ISFIFO(mode) (((mode) & S_IFMT) == S_IFIFO)
89 #define S_ISCHR(mode) (((mode) & S_IFMT) == S_IFCHR)
95 #define S_ISDIR(mode) (((mode) & S_IFMT) == S_IFDIR)
101 #define S_ISBLK(mode) (((mode) & S_IFMT) == S_IFBLK)
107 #define S_ISREG(mode) (((mode) & S_IFMT) == S_IFREG)
113 #define S_ISLNK(mode) (((mode) & S_IFMT) == S_IFLNK)
119 #define S_ISSOCK(mode) (((mode) & S_IFMT) == S_IFSOCK)
125 #define S_ISDOOR(mode) (((mode) & S_IFMT) == S_IFDOOR)
130 #define S_IRWXU (S_IRUSR|S_IWUSR|S_IXUSR)
134 #define S_IRWXG (S_IRGRP|S_IWGRP|S_IXGRP)
138 #define S_IRWXO (S_IROTH|S_IWOTH|S_IXOTH)
142 #define ACCESSPERMS (S_IRWXU|S_IRWXG|S_IRWXO)
148 const std::string
cwd(
void)
151 char buf[PATH_MAX] = { 0 };
153 if (getcwd(buf, PATH_MAX) == 0)
154 throw(
ERROR(errno,
"Could not determine current directory"));
168 throw(
ERROR(errno,
"Could not determine PID"));
180 throw(
ERROR(errno,
"Could not determine PID"));
188 if ((a_path.size() > 0) && (a_path[0] ==
'/')) {
207 std::string::size_type idx;
212 while (idx != std::string::npos) {
213 while ((idx != str.size()-1) && (str[idx+1] ==
'/'))
215 idx = str.find(
'/',idx+1);
227 std::string::size_type idx;
230 idx = path.find(
'/');
231 while (idx != std::string::npos) {
232 if ((idx == 0) || (idx == path.size()-1))
236 idx = path.find(
'/');
238 if (path.size() == 0)
240 if (path.substr(0,2) ==
".-")
250 std::string::size_type idx;
252 idx = a_path.rfind(
'/');
253 if (idx == std::string::npos) {
267 std::string::size_type idx;
269 idx = a_path.rfind(
'/');
270 if (idx == std::string::npos) {
283 const std::string a_path,
284 const std::string a_rel_path
290 if (a_rel_path.size() == 0) {
291 TRY_nomem(es =
"Invalid relative path: \"");
297 TRY_nomem(es =
"Invalid absolute reference path: \"");
315 const std::string a_path_to,
316 const std::string a_path_from
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;
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));
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));
343 (path_to.size() > 0 && path_from.size() > 0)
344 && (path_to_substr == path_from_substr)
347 path_to.erase(0,path_to_substr.size());
348 if ((path_to.size() > 0) && (path_to[0] ==
'/'))
350 path_from.erase(0,path_from_substr.size());
351 if ((path_from.size() > 0) && (path_from[0] ==
'/'))
352 path_from.erase(0,1);
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));
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));
370 while (path_from.size() > 0) {
372 idx = path_from.find(
'/');
373 if (idx == std::string::npos)
376 path_from.erase(0,idx+1);
387 if (access(a_path.c_str(), F_OK) == 0)
return(
true);
390 if (is_fifo_special(a_path))
return(
true);
393 if (is_char_special(a_path))
return(
true);
396 if (is_dir(a_path))
return(
true);
399 if (is_file(a_path))
return(
true);
402 if (is_block_special(a_path))
return(
true);
405 if (is_link(a_path))
return(
true);
408 if (is_socket(a_path))
return(
true);
411 if (is_door(a_path))
return(
true);
419 if (access(a_path.c_str(), R_OK) != 0) {
429 if (access(a_path.c_str(), W_OK) != 0) {
439 if (access(a_path.c_str(), X_OK) != 0) {
448 bool is_fifo_special(
const std::string& a_path)
454 if (fstat.is_fifo_special()) {
467 bool is_char_special(
const std::string& a_path)
473 if (fstat.is_character_special()) {
486 bool is_dir(
const std::string& a_path)
492 if (fstat.is_directory()) {
505 bool is_file(
const std::string& a_path)
511 if (fstat.is_regular_file()) {
524 bool is_block_special(
const std::string& a_path)
530 if (fstat.is_block_special()) {
543 bool is_link(
const std::string& a_path)
549 if (fstat.is_link()) {
562 bool is_socket(
const std::string& a_path)
568 if (fstat.is_socket()) {
581 bool is_door(
const std::string& a_path)
587 if (fstat.is_door()) {
604 TRY_nomem(es =
"Could not create directory: \"");
607 throw(
ERROR(errno,es));
614 if (!
exists(a_path))
return;
615 if ((rmdir(a_path.c_str()) != 0) &&
exists(a_path)) {
618 TRY_nomem(es =
"Could not remove directory: \"");
624 throw(
ERROR(errno,es));
639 if (!
exists(a_path))
return;
640 if ((unlink(a_path.c_str()) != 0) &&
exists(a_path)) {
643 TRY_nomem(es =
"Could not remove file: \"");
649 throw(
ERROR(errno,es));
664 std::string parent_dir;
667 if (a_path.size() == 0)
672 for (ce = a_path.size()-1; ((ce > 0) && (a_path[ce] !=
'/')); ce--);
675 TRY_nomem(parent_dir = a_path.substr(0,ce));
685 if (a_path.size() == 0)
696 TRY_nomem(es =
"Could not create directory hierarchy: \"");
709 void rename_file(
const std::string a_from,
const std::string a_to)
713 if (a_from.size() == 0) {
714 TRY_nomem(es =
"Illegal from filename: \"");
720 TRY_nomem(es =
"From filename does not exist: \"");
725 if (a_to.size() == 0) {
726 TRY_nomem(es =
"Illegal to filename: \"");
732 TRY_nomem(es =
"To filename already exists: \"");
738 TRY_nomem(es =
"From filename is not writable: \"");
743 if (rename(a_from.c_str(), a_to.c_str()) != 0) {
744 TRY_nomem(es =
"Could not rename file: \"");
749 throw(
ERROR(errno,es));
754 void mk_symlink(
const std::string a_from,
const std::string a_to)
756 if (symlink(a_from.c_str(), a_to.c_str()) != 0) {
765 throw(
ERROR(errno,es));
772 std::string from_dirname, to_dirname, from_basename;
779 if (rel.size() != 0) {
827 struct passwd *passwd_ptr = 0;
828 struct group *group_ptr = 0;
830 char path_buf[PATH_MAX] = { 0 };
834 if (lstat(
m_path.c_str(), &statbuf) < 0) {
838 throw(
ERROR(errno,es));
844 throw(
ERROR(errno,es));
847 if (S_ISFIFO(
m_stat.st_mode)) {
853 if (S_ISCHR(
m_stat.st_mode)) {
859 if (S_ISBLK(
m_stat.st_mode)) {
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: \"");
870 throw(
ERROR(errno,es));
875 passwd_ptr = getpwuid(
m_stat.st_uid);
876 if (passwd_ptr != 0) {
880 group_ptr = getgrgid(
m_stat.st_gid);
881 if (group_ptr != 0) {
897 if (S_ISFIFO(
m_stat.st_mode)) {
898 return(type_fifo_special);
902 if (S_ISCHR(
m_stat.st_mode)) {
903 return(type_character_special);
907 if (S_ISDIR(
m_stat.st_mode)) {
908 return(type_directory);
912 if (S_ISBLK(
m_stat.st_mode)) {
913 return(type_block_special);
917 if (S_ISREG(
m_stat.st_mode)) {
918 return(type_regular_file);
922 if (S_ISLNK(
m_stat.st_mode)) {
927 if (S_ISSOCK(
m_stat.st_mode)) {
932 if (S_ISDOOR(
m_stat.st_mode)) {
1004 value =
static_cast<uint64
>(
m_stat.st_size);
1032 value =
static_cast<uint64
>(
m_stat.st_blksize);
1042 value =
static_cast<uint64
>(
m_stat.st_blocks);
1073 const bool filestatus::is_fifo_special(
void)
const
1077 value = (
type() == type_fifo_special);
1085 const bool filestatus::is_character_special(
void)
const
1089 value = (
type() == type_character_special);
1097 const bool filestatus::is_block_special(
void)
const
1101 value = (
type() == type_block_special);
1109 const bool filestatus::is_link(
void)
const
1113 value = (
type() == type_link);
1121 const bool filestatus::is_socket(
void)
const
1125 value = (
type() == type_socket);
1133 const bool filestatus::is_door(
void)
const
1137 value = (
type() == type_door);
1145 const bool filestatus::is_directory(
void)
const
1149 value = (
type() == type_directory);
1157 const bool filestatus::is_regular_file(
void)
const
1161 value = (
type() == type_regular_file);
1169 const bool filestatus::user_can_read(
void)
const
1173 value = ((
m_stat.st_mode & S_IRUSR) != 0);
1181 const bool filestatus::user_can_write(
void)
const
1185 value = ((
m_stat.st_mode & S_IWUSR) != 0);
1193 const bool filestatus::user_can_execute(
void)
const
1197 value = ((
m_stat.st_mode & S_IXUSR) != 0);
1205 const bool filestatus::group_can_read(
void)
const
1209 value = ((
m_stat.st_mode & S_IRGRP) != 0);
1217 const bool filestatus::group_can_write(
void)
const
1221 value = ((
m_stat.st_mode & S_IWGRP) != 0);
1229 const bool filestatus::group_can_execute(
void)
const
1233 value = ((
m_stat.st_mode & S_IXGRP) != 0);
1241 const bool filestatus::other_can_read(
void)
const
1245 value = ((
m_stat.st_mode & S_IROTH) != 0);
1253 const bool filestatus::other_can_write(
void)
const
1257 value = ((
m_stat.st_mode & S_IWOTH) != 0);
1265 const bool filestatus::other_can_execute(
void)
const
1269 value = ((
m_stat.st_mode & S_IXOTH) != 0);
1277 const bool filestatus::is_set_uid(
void)
const
1281 value = ((
m_stat.st_mode & S_ISUID) != 0);
1289 const bool filestatus::is_set_gid(
void)
const
1293 value = ((
m_stat.st_mode & S_ISGID) != 0);
1301 const bool filestatus::is_set_sticky(
void)
const
1305 value = ((
m_stat.st_mode & S_ISVTX) != 0);
1339 const std::string a_path,
const std::string a_filter)
1341 path(a_path, a_filter);
1352 type::assign(a_class.begin(), a_class.end());
1366 struct dirent *dirp = 0;
1371 TRY(filestat.
path(a_path),
"Could not stat directory");
1373 dp = opendir(a_path.c_str());
1378 throw(
ERROR(errno,es));
1380 while ( (dirp = readdir(dp)) != 0 ) {
1381 name = dirp->d_name;
1383 ((a_filter !=
".") && (a_filter !=
".."))
1385 ((name ==
".") || (name ==
".."))
1388 if (fnmatch(a_filter.c_str(), name.c_str(), 0) == 0) {
1392 if (closedir(dp) < 0) {
1393 TRY_nomem(es =
"Error closing directory \"");
1396 throw(
ERROR(errno,es));
1399 std::sort(begin(), end());
1417 subdirectory::const_iterator di;
1419 std::string pathstr;
1424 mode |= S_IWUSR|S_IXUSR;
1425 mode |= S_IWGRP|S_IXGRP;
1426 mode |= S_IWOTH|S_IXOTH;
1428 TRY_nomem(es =
"Could not recursively delete: \"");
1433 if (is_link(a_path)) {
1435 if (chmod(a_path.c_str(), mode) != 0)
1436 throw(
ERROR(errno,es));
1443 if (f.is_directory()) {
1445 if (d.size() != 0) {
1447 for (di = d.begin(); di != d.end(); ++di) {
1449 pathstr = static_cast<std::string>(a_path)
1450 + static_cast<std::string>(
"/")
1451 + static_cast<std::string>(*di)
1454 if (f.is_directory()) {
1456 if (chmod(a_path.c_str(), mode) != 0)
1457 throw(
ERROR(errno,es));
1463 if (chmod(a_path.c_str(), mode) != 0)
1464 throw(
ERROR(errno,es));
1471 if (chmod(a_path.c_str(), mode) != 0)
1472 throw(
ERROR(errno,es));
1478 if (chmod(a_path.c_str(), mode) != 0)
1479 throw(
ERROR(errno,es));
1513 std::string::size_type idx;
1515 std::string subdir_path;
1516 std::string new_subdir_path;
1518 subdirectory::const_iterator sdi;
1524 if (path.size() == 0) {
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);
1537 if (subdir_path.size() == 0)
1540 if (!
exists(subdir_path)) {
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);
1556 for (di = begin(); di != end(); di++) {
1560 for (di = list.begin(); di != list.end(); di++) {
1562 if (!filestat.is_directory())
1564 subdir.
path(*di, subdir_path);
1565 for (sdi = subdir.begin(); sdi != subdir.end(); sdi++) {
1606 TRY_nomem(es =
"Could not stat filesystem: \"");
1609 throw(
ERROR(errno,es));
1624 value =
static_cast<uint64
>(
m_statfs.f_bsize);
1634 value =
static_cast<uint64
>(
m_statfs.f_blocks);
1644 value =
static_cast<uint64
>(
m_statfs.f_bfree);
1666 value =
static_cast<uint64
>(
m_statfs.f_files);
1678 value =
static_cast<uint64
>(
m_statfs.f_ffree);
1755 if (!in.is_open())
return(0);
1770 if (pid == 0)
return(
false);
1771 if (pid == getpid())
return(
true);
1772 if (kill(pid,0) >= 0)
return(
true);
1786 if (!out.is_open())
return(
false);
1788 out << pid << std::endl;
const pid_t pid(void)
Return the PID of this process.
void mk_dirhier_recursive_(const std::string a_path)
Recursively create a directory heirarchy.
std::string reform_path(const std::string &a_path)
Reformat a path to remove double slashes.
const std::string cwd(void)
Return the current working directory.
Retrieve information about a filesystem.
const size_type total_inodes(void) const
Return the filesystem's total number of inodes, if supported by the filesystem, otherwise the result ...
void mk_dir(const std::string &a_path)
Create a directory.
void path(const std::string a_path)
Retrieve information about a pathname.
std::string path_basename(const std::string &a_path)
Return everything after the last slash from a path.
const type & path(const std::string &a_path)
Retrieve a list of paths that match the wildcard path given.
bool executable(const std::string &a_path)
Return true if the file or directory exists and is executable.
const pid_t parent_pid(void)
Return the PID of the parent process.
const size_type blocks(void) const
Return the number of blocks used to store this file.
void push_back(const error_instance &a_e)
void mk_dirhier(const std::string a_path)
Recursively create a directory heirarchy.
const bool gid_is_found(void) const
If the file's owner's GID is found in the passwd file, return true.
bool writable(const std::string &a_path)
Return true if the file or directory exists and is writable.
const bool uid_is_found(void) const
If the file's owner's UID is found in the passwd file, return true.
const size_type blocksize(void) const
Return the filesystem block size.
const inode_type inode(void) const
Return the file inode.
const std::string link(void) const
If the pathname is a link, return the path it is linked to.
bool readable(const std::string &a_path)
Return true if the file or directory exists and is readable.
const size_type used_blocks(void) const
Return the filesystem's number of used blocks.
Retrieve a list of pathnames that match a given wildcard path.
const time_type last_status_change_time(void) const
Return the last status change time of this file.
const size_type blocksize(void) const
Return the blocksize used to store this file.
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...
const std::string lockfile(void) const
Get the lockfile path.
const mode_type mode(void) const
Return the file mode.
filesystem & operator=(const filesystem &a_class)
Copy values from another instance.
std::vector< std::string > type
bool relative_path(const std::string &a_path)
Return true if the string looks like a relative path.
bool exists(const std::string &a_path)
Return true if the file or directory exists.
void rm_dir(const std::string a_path)
Remove a directory.
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.
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.
const pid_type locked_by(void) const
Get the PID of the locking process.
const filetype type(void) const
Return the type of file.
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.
void rm_recursive(const std::string a_path)
Recursively delete the contents of a directory.
const std::string uid_name(void) const
Return the file's owner's user name (from UID)
#define INTERNAL_ERROR(e, s)
const uid_type uid(void) const
Return the file's owner's UID.
const time_type last_modification_time(void) const
Return the last modification time of this file.
const minor_type get_minor(void) const
If the pathname is a special file, return it's minor number.
const device_type dev(void) const
Return the file's device.
Retrieve information about a file or directory.
void clear(void)
Clear the simple_lock object.
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...
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...
const std::string path(void) const
Return the pathname that this filestatus object has information about.
const size_type used_inodes(void) const
Return the filesystem's number of used inodes.
bool absolute_path(const std::string &a_path)
Return true if the string looks like an absolute path.
void clear(void)
Clear all values.
const size_type free_blocks(void) const
Return the filesystem's number of free blocks.
const std::string gid_name(void) const
Return the file's owner's group name (from UID)
#define ERROR_INSTANCE(s)
const size_type size(void) const
Return the file size in bytes.
void assign(const subdirectory &a_class)
Assign the contents of a given subdirectory to this subdirectory.
const gid_type gid(void) const
Return the file's owner's GID.
void rm_file(const std::string a_path)
Remove a file.
std::vector< std::string > type
void rename_file(const std::string a_from, const std::string a_to)
Rename a file or directory.
const num_links_type num_links(void) const
Return the number of links to this file.
const time_type last_access_time(void) const
Return the last access time of this file.
Retrieve a list of files in a subdirectory that match a given wildcard filename.
void clear(void)
Clear the filesystem object.
const device_type rdev(void) const
Return the file's raw device.
std::string path_dirname(const std::string &a_path)
Return everything up to the last slash from a path.
const std::string path(void) const
Return the path from which this filesystem information was obtained.
const major_type get_major(void) const
If the pathname is a special file, return it's major number.
const size_type total_blocks(void) const
Return the filesystem's total number of blocks.
const bool is_locked(void) const
Find out whether or not the lock is in place.
subdirectory & operator=(const subdirectory &a_class)
void mk_symlink(const std::string a_from, const std::string a_to)
Create a symbolic link.