Changeset 2569
- Timestamp:
- 07/22/07 19:24:29 (1 year ago)
- Files:
-
- trunk/lib_internal/Makefile-files (modified) (1 diff)
- trunk/lib_internal/matchlist-compare.c (modified) (1 diff)
- trunk/lib_internal/mkdir.c (added)
- trunk/lib_internal/testsuite (modified) (1 prop)
- trunk/lib_internal/testsuite/Makefile-files (modified) (3 diffs)
- trunk/lib_internal/testsuite/matchlist.c (added)
- trunk/lib_internal/util.h (modified) (1 diff)
- trunk/src/vclone.c (modified) (12 diffs)
- trunk/src/vhashify.c (modified) (3 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
trunk/lib_internal/Makefile-files
r2255 r2569 102 102 lib_internal/util-lockfile.c \ 103 103 lib_internal/util-safechdir.c \ 104 lib_internal/mkdir.c \ 104 105 $(command_SRCS) \ 105 106 $(filecfg_SRCS) trunk/lib_internal/matchlist-compare.c
r1423 r2569 38 38 } 39 39 40 return stINCLUDE;40 return list->skip_depth > 0 ? stEXCLUDE : stINCLUDE; 41 41 } trunk/lib_internal/testsuite
- Property svn:ignore changed from
.deps
.dirstamp
.libs
.libs
.nfs0*
command
copy
filecfg-ml
isnumber
isnumber-gnu
sigbus
sigbus-gnu to
.deps
.dirstamp
.libs
.libs
.nfs0*
command
copy
filecfg-ml
isnumber
isnumber-gnu
sigbus
sigbus-gnu
matchlist
matchlist-gnu
- Property svn:ignore changed from
trunk/lib_internal/testsuite/Makefile-files
r2545 r2569 24 24 lib_internal/testsuite/isnumber-gnu \ 25 25 lib_internal/testsuite/sigbus \ 26 lib_internal/testsuite/sigbus-gnu 26 lib_internal/testsuite/sigbus-gnu \ 27 lib_internal/testsuite/matchlist \ 28 lib_internal/testsuite/matchlist-gnu 27 29 TESTS += lib_internal/testsuite/filecfg-ml \ 28 30 lib_internal/testsuite/copy-check \ … … 30 32 lib_internal/testsuite/isnumber-gnu \ 31 33 lib_internal/testsuite/sigbus \ 32 lib_internal/testsuite/sigbus-gnu 34 lib_internal/testsuite/sigbus-gnu \ 35 lib_internal/testsuite/matchlist \ 36 lib_internal/testsuite/matchlist-gnu 33 37 endif 34 38 35 39 DIETPROGS += lib_internal/testsuite/isnumber \ 36 lib_internal/testsuite/sigbus 40 lib_internal/testsuite/sigbus \ 41 lib_internal/testsuite/matchlist 37 42 38 43 EXTRA_DIST += lib_internal/testsuite/copy-check … … 67 72 lib_internal_testsuite_sigbus_gnu_SOURCES = lib_internal/testsuite/sigbus.c 68 73 lib_internal_testsuite_sigbus_gnu_CPPFLAGS = $(AM_CPPFLAGS) # see note above 74 75 lib_internal_testsuite_matchlist_SOURCES = lib_internal/testsuite/matchlist.c 76 lib_internal_testsuite_matchlist_LDADD = $(LIBINTERNAL) 77 lib_internal_testsuite_matchlist_CPPFLAGS = $(AM_CPPFLAGS) # see note above 78 79 lib_internal_testsuite_matchlist_gnu_SOURCES = lib_internal/testsuite/matchlist.c 80 lib_internal_testsuite_matchlist_gnu_LDADD = $(LIBINTERNAL_GLIBC) 81 lib_internal_testsuite_matchlist_gnu_CPPFLAGS = $(AM_CPPFLAGS) # see note above trunk/lib_internal/util.h
r2255 r2569 38 38 bool isNumber(char const *, signed long *result, bool is_strict); 39 39 bool isNumberUnsigned(char const *, unsigned long *result, bool is_strict); 40 bool mkdirRecursive(char const *); 40 41 41 42 #endif // H_UTILVSERVER_LIB_INTERNAL_UTIL_H trunk/src/vclone.c
r2559 r2569 26 26 #include "lib_internal/pathinfo.h" 27 27 #include "lib_internal/unify.h" 28 #include "lib_internal/matchlist.h" 28 29 29 30 #include <unistd.h> … … 50 51 struct WalkdownInfo 51 52 { 52 PathInfo state; 53 PathInfo src; 54 PathInfo dst; 53 PathInfo state; 54 PathInfo src; 55 PathInfo dst; 56 struct MatchList excludes; 55 57 }; 56 58 … … 58 60 unsigned int verbosity; 59 61 xid_t xid; 62 const char * exclude_list; 60 63 }; 61 64 … … 67 70 struct option const 68 71 CMDLINE_OPTIONS[] = { 69 { "help", no_argument, 0, CMD_HELP }, 70 { "version", no_argument, 0, CMD_VERSION }, 71 { "xid", required_argument, 0, CMD_XID }, 72 { "help", no_argument, 0, CMD_HELP }, 73 { "version", no_argument, 0, CMD_VERSION }, 74 { "xid", required_argument, 0, CMD_XID }, 75 { "exclude-from", required_argument, 0, 'X' }, 72 76 { 0,0,0,0 } 73 77 }; … … 82 86 WRITE_STR(fd, cmd); 83 87 WRITE_MSG(fd, 84 " [--xid <xid>] <source> <absolute path to destination>\n\n" 88 " [--xid <xid>] [--exclude-from <exclude-list>]\n" 89 " <source> <absolute path to destination>\n\n" 85 90 "Please report bugs to " PACKAGE_BUGREPORT "\n"); 86 91 exit(res); … … 108 113 #include "vserver-visitdir.hc" 109 114 115 static bool 116 handleDirEntry(const PathInfo *src_path, const PathInfo *basename, 117 bool *is_dir, struct stat *st) 118 { 119 bool res = false; 120 121 *is_dir = false; 122 123 if (lstat(basename->d, st)==-1) 124 PERROR_Q(ENSC_WRAPPERS_PREFIX "lstat", src_path->d); 125 else { 126 PathInfo dst_path = global_info.dst; 127 char dst_path_buf[ENSC_PI_APPSZ(dst_path, *src_path)]; 128 129 if (S_ISDIR(st->st_mode)) 130 *is_dir = true; 131 132 if (MatchList_compare(&global_info.excludes, src_path->d) != stINCLUDE) { 133 if (Global_getVerbosity() > 1) { 134 WRITE_MSG(1, " skipping '"); 135 Vwrite(1, src_path->d, src_path->l); 136 WRITE_MSG(1, "' (excluded)\n"); 137 } 138 return false; 139 } 140 141 PathInfo_append(&dst_path, src_path, dst_path_buf); 142 143 /* skip files that already exist */ 144 if (access(dst_path.d, F_OK)!=-1) { 145 if (Global_getVerbosity() > 1) { 146 WRITE_MSG(1, " skipping '"); 147 Vwrite(1, src_path->d, src_path->l); 148 WRITE_MSG(1, "' (exists in destination)\n"); 149 } 150 res = true; 151 } 152 else { 153 /* create directory that might have been skipped */ 154 if (global_info.excludes.skip_depth > 0) { 155 if (Global_getVerbosity() > 4) { 156 WRITE_MSG(1, " creating directories for '"); 157 Vwrite(1, dst_path.d, dst_path.l); 158 WRITE_MSG(1, "'\n"); 159 } 160 if (mkdirRecursive(dst_path.d) == -1) 161 PERROR_Q(ENSC_WRAPPERS_PREFIX "mkdirRecursive", dst_path.d); 162 } 163 164 /* already unified file */ 165 if (S_ISREG(st->st_mode) && Unify_isIUnlinkable(basename->d) == unifyBUSY) { 166 if (Global_getVerbosity() > 2) { 167 WRITE_MSG(1, " linking unified file '"); 168 Vwrite(1, src_path->d, src_path->l); 169 WRITE_MSG(1, "'\n"); 170 } 171 Elink(basename->d, dst_path.d); 172 res = true; 173 } 174 /* something we have to copy */ 175 else { 176 if (Global_getVerbosity() > 2) { 177 WRITE_MSG(1, " copying non-unified file '"); 178 Vwrite(1, src_path->d, src_path->l); 179 WRITE_MSG(1, "'\n"); 180 } 181 if (!Unify_copy(basename->d, st, dst_path.d)) 182 PERROR_Q(ENSC_WRAPPERS_PREFIX "Unify_copy", dst_path.d); 183 else if (global_args->xid != VC_NOCTX && 184 vc_set_iattr(dst_path.d, global_args->xid, 0, VC_IATTR_XID) == -1) 185 PERROR_Q(ENSC_WRAPPERS_PREFIX "vc_set_iattr", dst_path.d); 186 else 187 res = true; 188 } 189 } 190 } 191 192 return res; 193 } 194 195 /* returns 1 on error, 0 on success */ 110 196 static uint64_t 111 197 visitDirEntry(struct dirent const *ent) … … 122 208 char path_buf[ENSC_PI_APPSZ(src_path, src_d_path)]; 123 209 struct stat f_stat = { .st_dev = 0 }; 210 bool is_dir; 124 211 125 212 PathInfo_append(&src_path, &src_d_path, path_buf); 126 213 127 128 if (lstat(dirname, &f_stat)==-1) 129 perror(ENSC_WRAPPERS_PREFIX "lstat()"); 130 else { 131 PathInfo dst_path = global_info.dst; 132 char dst_path_buf[ENSC_PI_APPSZ(dst_path, src_path)]; 133 134 PathInfo_append(&dst_path, &src_path, dst_path_buf); 135 136 /* skip files that already exist */ 137 if (access(dst_path.d, F_OK)!=-1) 138 res = 0; 139 else if (S_ISREG(f_stat.st_mode) && Unify_isIUnlinkable(src_d_path.d) == unifyBUSY) { 140 Elink(src_d_path.d, dst_path.d); 141 res = 0; 142 } 143 else { 144 if (!Unify_copy(src_d_path.d, &f_stat, dst_path.d)) 145 perror(ENSC_WRAPPERS_PREFIX "Unify_copy()"); 146 else if (vc_set_iattr(dst_path.d, global_args->xid, 0, VC_IATTR_XID) == -1) 147 perror(ENSC_WRAPPERS_PREFIX "vc_set_iattr()"); 148 else 149 res = 0; 150 } 151 if (S_ISDIR(f_stat.st_mode)) 152 res = visitDir(dirname, &f_stat); 214 if (handleDirEntry(&src_path, &src_d_path, &is_dir, &f_stat)) 215 res = 0; 216 217 if (is_dir) { 218 if (res || global_info.excludes.skip_depth > 0) 219 global_info.excludes.skip_depth++; 220 res = res + visitDir(dirname, &f_stat); 221 if (global_info.excludes.skip_depth > 0) 222 global_info.excludes.skip_depth--; 153 223 } 154 224 … … 161 231 .verbosity = 0, 162 232 .xid = VC_NOCTX, 233 .exclude_list = NULL, 163 234 }; 164 235 uint64_t res; … … 167 238 global_args = &args; 168 239 while (1) { 169 int c = getopt_long(argc, argv, "+v ",240 int c = getopt_long(argc, argv, "+vX:", 170 241 CMDLINE_OPTIONS, 0); 171 242 if (c==-1) break; … … 175 246 case CMD_VERSION : showVersion(); 176 247 case 'v' : args.verbosity++; break; 248 case 'X' : args.exclude_list = optarg; break; 177 249 case CMD_XID : args.xid = Evc_xidopt2xid(optarg,true); break; 178 250 default : … … 213 285 ENSC_PI_SETSTR(global_info.dst, argv[optind+1]); 214 286 287 if (global_args->exclude_list) 288 MatchList_initManually(&global_info.excludes, 0, strdup(argv[optind]), 289 global_args->exclude_list); 290 else 291 MatchList_init(&global_info.excludes, argv[optind], 0); 292 215 293 if (global_args->verbosity>3) 216 294 WRITE_MSG(1, "Starting to traverse directories...\n"); … … 218 296 Echdir(global_info.src.d); 219 297 res = visitDir("/", 0); 298 299 MatchList_destroy(&global_info.excludes); 220 300 221 301 return res>0 ? 1 : 0; trunk/src/vhashify.c
r2475 r2569 394 394 } 395 395 396 static enum { mkdirFAIL, mkdirSUCCESS, mkdirSKIP }397 mkdirSingle(char const *path, char *end_ptr, int good_err)398 {399 *end_ptr = '\0';400 if (mkdir(path, 0700)!=-1 || errno==EEXIST) {401 *end_ptr = '/';402 return mkdirSUCCESS;403 }404 else if (errno==good_err) {405 *end_ptr = '/';406 return mkdirSKIP;407 }408 else {409 int old_errno = errno;410 WRITE_MSG(2, "mkdir('");411 WRITE_STR(2, path);412 errno = old_errno;413 perror("')");414 return mkdirFAIL;415 }416 }417 418 static char *419 rstrchr(char *str, char c)420 {421 while (*str!=c) --str;422 return str;423 }424 425 static bool426 mkdirRecursive(char const *path)427 {428 if (path[0]!='/') return false; // only absolute paths429 430 char buf[strlen(path)+1];431 char * ptr = buf + sizeof(buf) - 2;432 433 strcpy(buf, path);434 435 while (ptr>buf && (ptr = rstrchr(ptr, '/'))!=0) {436 switch (mkdirSingle(buf, ptr, ENOENT)) {437 case mkdirSUCCESS : break;438 case mkdirSKIP : --ptr; continue;439 case mkdirFAIL : return false;440 }441 442 break; // implied by mkdirSUCCESS443 }444 445 assert(ptr!=0);446 ++ptr;447 448 while ((ptr=strchr(ptr, '/'))!=0) {449 switch (mkdirSingle(buf, ptr, 0)) {450 case mkdirSKIP :451 case mkdirFAIL : return false;452 case mkdirSUCCESS : ++ptr; continue;453 }454 }455 456 return true;457 }458 459 396 static bool 460 397 resolveCollisions(char *result, PathInfo const *root, HashPath d_path, … … 498 435 if (!global_args->dry_run) { 499 436 *ptr = '\0'; 500 if (!mkdirRecursive(result)) 437 if (!mkdirRecursive(result)) { 438 PERROR_Q("mkdir", result); 501 439 return false; 440 } 502 441 *ptr = '-'; 503 442 … … 505 444 506 445 if (fd==-1) { 507 int old_errno = errno; 508 WRITE_MSG(2, "open('"); 509 WRITE_STR(2, buf); 510 errno = old_errno; 511 perror("')"); 446 PERROR_Q("open", buf); 512 447 return false; 513 448 }
