X-Git-Url: http://git.linux-vserver.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=util-vserver%2Fsrc%2Fvcopy.c;h=82804d3cdee1d8535033c7a4f9b72e8ee895483b;hb=0e981c77a8a6215525e86fbe432cda11ee3ede40;hp=295e94ba5c6056e7dee693fa6baceb81adcb0828;hpb=9f52547ae6ad8bde3d17856480453498e4bd0ab1;p=util-vserver.git diff --git a/util-vserver/src/vcopy.c b/util-vserver/src/vcopy.c index 295e94b..82804d3 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 '"); @@ -186,7 +226,7 @@ visitDirEntry(struct dirent const *ent) perror("lstat()"); else { Operation op = checkDirEntry(&src_path, &f_stat); - PathInfo dst_path = global_info.src_list.root; + PathInfo dst_path = global_info.dst_list.root; char dst_path_buf[ENSC_PI_APPSZ(dst_path, src_path)]; PathInfo_append(&dst_path, &src_path, dst_path_buf);