X-Git-Url: http://git.linux-vserver.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=util-vserver%2Fsrc%2Ffstool.c;h=d49383184fd769bbd38f4bfc4ef88f94960dbe10;hb=a917f24ef7b003dcef54a3db2644cf9cb4bc2db2;hp=780997f1826159a012466f5437564d75326f78ed;hpb=de3e1dc1eae2d6bd6aa11c34290498d966885245;p=util-vserver.git diff --git a/util-vserver/src/fstool.c b/util-vserver/src/fstool.c index 780997f..d493831 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) ? 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; @@ -107,7 +122,7 @@ iterateFilesystem(char const *path) { CONCAT_PATHS(path, path_len, ent->d_name); - err += handleFile(ent->d_name, new_path, &st) ? 0 : 1; + err += handleFile(ent->d_name, new_path) ? 0 : 1; } } @@ -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,34 +178,12 @@ 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); -} - -static xid_t -resolveCtx(char const *str) -{ - xid_t res; - - if (*str==':') ++str; - else { - char *end_ptr; - long result = strtol(str, &end_ptr, 0); - - if (end_ptr>str && *end_ptr==0) return result; - } - - res = vc_getVserverCtx(str, vcCFG_AUTO, true, 0); - if (res==VC_NOCTX) { - WRITE_MSG(2, "Can not find a vserver with name '"); - WRITE_STR(2, str); - WRITE_MSG(2, "', or vserver does not have a static context\n"); - exit(1); } - - return res; + else + return handleFile(path, path) ? 0 : 1; } int main(int argc, char *argv[]) @@ -194,12 +195,13 @@ int main(int argc, char *argv[]) .do_display_dot = false, .do_display_dir = false, .do_mapping = true, - .immutable = false, - .immulink = false, .ctx = VC_NOCTX, .is_legacy = false, .do_set = false, .do_unset = false, + .local_fs = false, + .set_mask = 0, + .del_mask = 0 }; global_args = &args; @@ -211,16 +213,26 @@ 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_IMMUTABLE; /*@fallthrough@*/ + case CMD_IMMUX : 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_IMMUTABLE; /*@fallthrough@*/ + case CMD_UNSET_IMMUX : 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; case 'n' : args.do_mapping = false; break; case 's' : args.do_set = true; break; case 'u' : args.do_unset = true; break; - case 'c' : args.ctx = resolveCtx(optarg); 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]); @@ -230,7 +242,7 @@ int main(int argc, char *argv[]) } } - checkParams(&args, argc); + fixupParams(&args, argc); if (optind==argc) err_cnt = processFile(".");