X-Git-Url: http://git.linux-vserver.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=util-vserver%2Fsrc%2Ffstool.c;h=7ae7a1de0f97846bfbeae83d2463c4ab3ce07908;hb=86a23427cca76a5a9befd60c85535a0e738bc3c6;hp=006d3aab225ecef29181ac8d30442ab8e40c2106;hpb=19f003f66c0d83ae8ade956fd2b357a109fc73e0;p=util-vserver.git diff --git a/util-vserver/src/fstool.c b/util-vserver/src/fstool.c index 006d3aa..7ae7a1d 100644 --- a/util-vserver/src/fstool.c +++ b/util-vserver/src/fstool.c @@ -22,15 +22,21 @@ #include "fstool.h" #include "util.h" -#include "wrappers.h" -#include "wrappers-dirent.h" #include #include #include #include +#include +#include +#include +#include +#define ENSC_WRAPPERS_DIRENT 1 +#define ENSC_WRAPPERS_FCNTL 1 +#define ENSC_WRAPPERS_UNISTD 1 +#include struct Arguments const * global_args = 0; @@ -62,7 +68,8 @@ checkForRace(int fd, char const * name, struct stat const *exp_st) inline static bool isSpecialDir(char const *d) { - return (d[0]=='.' && (d[1]=='\0' || (d[1]=='.' && d[2]=='\0'))); + return ( (d[0]=='.' && !global_args->do_display_dot) || + (d[0]=='.' && (d[1]=='\0' || (d[1]=='.' && d[2]=='\0'))) ); } #define CONCAT_PATHS(LHS, LHS_LEN, RHS) \ @@ -78,15 +85,23 @@ iterateFilesystem(char const *path) { bool do_again = false; size_t path_len = strlen(path); - DIR * dir = Eopendir("."); uint64_t err = 0; + struct stat cur_st; + DIR * dir = opendir("."); - { - struct stat st; - if (lstat(".", &st)==-1) perror("lstat()"); - else err += handleFile(".", path, &st) ? 0 : 1; + if (dir==0) { + perror("opendir()"); + return 1; } + // show current directory entry first + if (lstat(".", &cur_st)==-1) perror("lstat()"); + else err += handleFile(".", path, &cur_st) ? 0 : 1; + + // strip trailing '/' + while (path_len>0 && path[path_len-1]=='/') --path_len; + + // process regular files before directories for (;;) { struct dirent *ent = Ereaddir(dir); struct stat st; @@ -128,8 +143,16 @@ iterateFilesystem(char const *path) continue; } - if (!S_ISDIR(st.st_mode)) continue; - safeChdir(ent->d_name, &st); + if (!S_ISDIR(st.st_mode) || + (global_args->local_fs && st.st_dev!=cur_st.st_dev)) + continue; + + if (safeChdir(ent->d_name, &st)==-1) { + perror("chdir()"); + ++err; + continue; + } + { CONCAT_PATHS(path, path_len, ent->d_name); err += iterateFilesystem(new_path); @@ -155,8 +178,10 @@ processFile(char const *path) return 1; } - if (S_ISDIR(st.st_mode) && !global_args->do_display_dir) + if (S_ISDIR(st.st_mode) && !global_args->do_display_dir) { + Echdir(path); return iterateFilesystem(path); + } else return handleFile(path, path, &st); } @@ -176,6 +201,9 @@ int main(int argc, char *argv[]) .is_legacy = false, .do_set = false, .do_unset = false, + .local_fs = false, + .set_mask = 0, + .del_mask = 0 }; global_args = &args; @@ -187,9 +215,16 @@ int main(int argc, char *argv[]) switch (c) { case CMD_HELP : showHelp(1, argv[0], 0); case CMD_VERSION : showVersion(); - case CMD_IMMUTABLE : args.immutable = true; break; - case CMD_IMMULINK : args.immulink = true; break; - case CMD_LEGACY : args.is_legacy = true; break; + case CMD_IMMU : args.set_mask |= VC_IATTR_IUNLINK; break; + case CMD_ADMIN : args.set_mask |= VC_IATTR_ADMIN; break; + case CMD_WATCH : args.set_mask |= VC_IATTR_WATCH; break; + case CMD_HIDE : args.set_mask |= VC_IATTR_HIDE; break; + case CMD_BARRIER : args.set_mask |= VC_IATTR_BARRIER; break; + case CMD_UNSET_IMMU : args.del_mask |= VC_IATTR_IUNLINK; break; + case CMD_UNSET_ADMIN : args.del_mask |= VC_IATTR_ADMIN; break; + case CMD_UNSET_WATCH : args.del_mask |= VC_IATTR_WATCH; break; + case CMD_UNSET_HIDE : args.del_mask |= VC_IATTR_HIDE; break; + case CMD_UNSET_BARRIER : args.del_mask |= VC_IATTR_BARRIER; break; case 'R' : args.do_recurse = true; break; case 'a' : args.do_display_dot = true; break; case 'd' : args.do_display_dir = true; break; @@ -197,6 +232,7 @@ int main(int argc, char *argv[]) case 's' : args.do_set = true; break; case 'u' : args.do_unset = true; break; case 'c' : args.ctx_str = optarg; break; + case 'x' : args.local_fs = true; break; default : WRITE_MSG(2, "Try '"); WRITE_STR(2, argv[0]);