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=780997f1826159a012466f5437564d75326f78ed;hpb=de3e1dc1eae2d6bd6aa11c34290498d966885245;p=util-vserver.git diff --git a/util-vserver/src/fstool.c b/util-vserver/src/fstool.c index 780997f..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,36 +178,14 @@ 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; -} - int main(int argc, char *argv[]) { uint64_t err_cnt = 0; @@ -200,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; @@ -211,16 +215,24 @@ 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; 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(".");