X-Git-Url: http://git.linux-vserver.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=util-vserver%2Fsrc%2Fvcopy.c;h=4bfac3b9cf4a4d42555e5a0f8dcb307c71d8ebdd;hb=a917f24ef7b003dcef54a3db2644cf9cb4bc2db2;hp=295e94ba5c6056e7dee693fa6baceb81adcb0828;hpb=9f52547ae6ad8bde3d17856480453498e4bd0ab1;p=util-vserver.git diff --git a/util-vserver/src/vcopy.c b/util-vserver/src/vcopy.c index 295e94b..4bfac3b 100644 --- a/util-vserver/src/vcopy.c +++ b/util-vserver/src/vcopy.c @@ -34,6 +34,7 @@ #include #include #include +#include #define ENSC_WRAPPERS_UNISTD 1 #define ENSC_WRAPPERS_FCNTL 1 @@ -126,18 +127,39 @@ bool Global_doRenew() { static Operation checkDirEntry(PathInfo const *path, struct stat const *st) { - struct WalkdownInfo const * const info = &global_info; + struct WalkdownInfo const * const info = &global_info; + MatchType res; + + // when marked as 'skip' in the first excludelist already, we do not need to + // visit the second one since it could not change that. + res=MatchList_compare(&info->dst_list, path->d); + if (res!=stSKIP) { + MatchType tmp = MatchList_compare(&info->src_list, path->d); + + // stINCLUDE gets overridden by stEXCLUDE+stSKIP, and stEXCLUDE by stSKIP. + // Using the MAX() macro is a hack but it works + res=MAX(res,tmp); + } - if (S_ISDIR(st->st_mode)) return opDIR; - if (S_ISLNK(st->st_mode) || - !S_ISREG(st->st_mode)) return opSKIP; - - // Check if it is in the exclude/include list of the destination vserver and - // abort when it is not matching an allowed entry - if (!MatchList_compare(&info->dst_list, path->d) || - !MatchList_compare(&info->src_list, path->d)) return opCOPY; + // non-skipped directories are marked as opDIR + if (res!=stSKIP && S_ISDIR(st->st_mode)) + return opDIR; + + // non-skipped symlinks will be copied always + if (res!=stSKIP && S_ISLNK(st->st_mode)) + return opCOPY; - return opUNIFY; + // skipped files or non regular files (character/block devices) will be skipped + // always + if (res==stSKIP || !S_ISREG(st->st_mode)) + return opSKIP; + + switch (res) { + case stINCLUDE : return opUNIFY; + case stEXCLUDE : return opCOPY; + case stSKIP : assert(false); // already handled above + default : assert(false); abort(); + } } static bool @@ -146,7 +168,25 @@ doit(Operation op, PathInfo const *src_path, struct stat const *exp_stat, PathInfo const *show_path) { - if (global_args->do_dry_run || global_args->verbosity>0) { +#if 0 + struct stat st; + + if (lstat(dst_path->d, &st)!=-1) { + if (global_args->do_keep && + (!S_ISDIR(exp_stat->st_mode) || S_ISDIR(st.st_mode))) { + // when keep-mode is enable and, do nothing + if (global_args->do_dry_run || global_args->verbosity>1) { + WRITE_MSG(1, "keeping '"); + write(1, show_path->d, show_path->l); + WRITE_MSG(1, "'\n"); + } + return true; + } + + } +#endif + + if (global_args->do_dry_run || global_args->verbosity>1) { if (op==opUNIFY) WRITE_MSG(1, "linking '"); else if (op==opCOPY) WRITE_MSG(1, "copying '"); else if (op==opDIR) WRITE_MSG(1, "creating '");