関数 | |
static int | is_backup_file (char *fn) |
static int | delete_item (char *fname, int mode, int flags) |
static void | delete_in_dir (struct file_list *flist, char *fbuf, struct file_struct *file, STRUCT_STAT *stp) |
static void | do_delete_pass (struct file_list *flist) |
int | unchanged_attrs (struct file_struct *file, STRUCT_STAT *st) |
void | itemize (struct file_struct *file, int ndx, int statret, STRUCT_STAT *st, int32 iflags, uchar fnamecmp_type, char *xname) |
int | unchanged_file (char *fn, struct file_struct *file, STRUCT_STAT *st) |
static void | sum_sizes_sqroot (struct sum_struct *sum, int64 len) |
static void | generate_and_send_sums (int fd, OFF_T len, int f_out, int f_copy) |
static int | find_fuzzy (struct file_struct *file, struct file_list *dirlist) |
void | check_for_finished_hlinks (int itemizing, enum logcode code) |
static int | try_dests_reg (struct file_struct *file, char *fname, int ndx, char *cmpbuf, STRUCT_STAT *stp, int itemizing, int maybe_ATTRS_REPORT, enum logcode code) |
static int | try_dests_non (struct file_struct *file, char *fname, int ndx, int itemizing, int maybe_ATTRS_REPORT, enum logcode code) |
static void | recv_generator (char *fname, struct file_struct *file, int ndx, int itemizing, int maybe_ATTRS_REPORT, enum logcode code, int f_out) |
void | generate_files (int f_out, struct file_list *flist, char *local_name) |
変数 | |
int | verbose |
int | dry_run |
int | do_xfers |
int | log_format_has_i |
int | daemon_log_format_has_i |
int | am_root |
int | am_server |
int | am_daemon |
int | do_progress |
int | recurse |
int | relative_paths |
int | implied_dirs |
int | keep_dirlinks |
int | preserve_links |
int | preserve_devices |
int | preserve_specials |
int | preserve_hard_links |
int | preserve_perms |
int | preserve_uid |
int | preserve_gid |
int | preserve_times |
int | omit_dir_times |
int | delete_mode |
int | delete_before |
int | delete_during |
int | delete_after |
int | module_id |
int | ignore_errors |
int | remove_sent_files |
int | delay_updates |
int | update_only |
int | ignore_existing |
int | ignore_non_existing |
int | inplace |
int | append_mode |
int | make_backups |
int | csum_length |
int | ignore_times |
int | size_only |
OFF_T | max_size |
OFF_T | min_size |
int | io_error |
int | allowed_lull |
int | sock_f_out |
int | ignore_timeout |
int | protocol_version |
int | fuzzy_basis |
int | always_checksum |
int | checksum_len |
char * | partial_dir |
char * | basis_dir [] |
int | compare_dest |
int | copy_dest |
int | link_dest |
int | whole_file |
If 1, send the whole file as literal data rather than trying to create an incremental diff. | |
int | list_only |
int | read_batch |
int | safe_symlinks |
long | block_size |
int | max_delete |
int | force_delete |
int | one_file_system |
mode_t | orig_umask |
stats | stats |
dev_t | filesystem_dev |
char * | backup_dir |
char * | backup_suffix |
int | backup_suffix_len |
file_list * | the_file_list |
filter_list_struct | server_filter_list |
static int | deletion_count = 0 |
static int | phase = 0 |
static int | dflt_perms |
static int is_backup_file | ( | char * | fn | ) | [static] |
generator.c の 104 行で定義されています。
参照先 backup_suffix・backup_suffix_len.
参照元 delete_item().
00105 { 00106 int k = strlen(fn) - backup_suffix_len; 00107 return k > 0 && strcmp(fn+k, backup_suffix) == 0; 00108 }
static int delete_item | ( | char * | fname, | |
int | mode, | |||
int | flags | |||
) | [static] |
generator.c の 117 行で定義されています。
参照先 backup_dir・file_struct::basename・file_list::count・deletion_count・do_rmdir()・dry_run・errno・FERROR・file_list::files・file_struct::flags・flist_free()・force_delete・full_fname()・get_dirlist()・is_backup_file()・log_delete()・make_backup()・make_backups・max_delete・file_struct::mode・pop_local_filters()・push_local_filters()・robust_unlink()・rsyserr()・strlcpy().
参照元 delete_in_dir()・recv_generator().
00118 { 00119 struct file_list *dirlist; 00120 int j, dlen, zap_dir, ok; 00121 unsigned remainder; 00122 void *save_filters; 00123 char *p; 00124 00125 if (!S_ISDIR(mode)) { 00126 if (max_delete && ++deletion_count > max_delete) 00127 return 0; 00128 if (make_backups && (backup_dir || !is_backup_file(fname))) 00129 ok = make_backup(fname); 00130 else 00131 ok = robust_unlink(fname) == 0; 00132 if (ok) { 00133 if (!(flags & DEL_TERSE)) 00134 log_delete(fname, mode); 00135 return 0; 00136 } 00137 if (errno == ENOENT) { 00138 deletion_count--; 00139 return 0; 00140 } 00141 rsyserr(FERROR, errno, "delete_file: unlink %s failed", 00142 full_fname(fname)); 00143 return -1; 00144 } 00145 00146 zap_dir = flags & DEL_FORCE_RECURSE || force_delete; 00147 if ((max_delete && ++deletion_count > max_delete) 00148 || (dry_run && zap_dir)) { 00149 ok = 0; 00150 errno = ENOTEMPTY; 00151 } else if (make_backups && !backup_dir && !is_backup_file(fname) 00152 && !(flags & DEL_FORCE_RECURSE)) 00153 ok = make_backup(fname); 00154 else 00155 ok = do_rmdir(fname) == 0; 00156 if (ok) { 00157 if (!(flags & DEL_TERSE)) 00158 log_delete(fname, mode); 00159 return 0; 00160 } 00161 if (errno == ENOENT) { 00162 deletion_count--; 00163 return 0; 00164 } 00165 if (!zap_dir) { 00166 rsyserr(FERROR, errno, "delete_file: rmdir %s failed", 00167 full_fname(fname)); 00168 return -1; 00169 } 00170 flags |= DEL_FORCE_RECURSE; /* mark subdir dels as not "in the way" */ 00171 deletion_count--; 00172 00173 dlen = strlen(fname); 00174 save_filters = push_local_filters(fname, dlen); 00175 00176 dirlist = get_dirlist(fname, dlen, 0); 00177 00178 p = fname + dlen; 00179 if (dlen != 1 || *fname != '/') 00180 *p++ = '/'; 00181 remainder = MAXPATHLEN - (p - fname); 00182 00183 for (j = dirlist->count; j--; ) { 00184 struct file_struct *fp = dirlist->files[j]; 00185 00186 if (fp->flags & FLAG_MOUNT_POINT) 00187 continue; 00188 00189 strlcpy(p, fp->basename, remainder); 00190 delete_item(fname, fp->mode, flags & ~DEL_TERSE); 00191 } 00192 flist_free(dirlist); 00193 00194 fname[dlen] = '\0'; 00195 00196 pop_local_filters(save_filters); 00197 00198 if (max_delete && ++deletion_count > max_delete) 00199 return 0; 00200 00201 if (do_rmdir(fname) == 0) { 00202 if (!(flags & DEL_TERSE)) 00203 log_delete(fname, mode); 00204 } else if (errno != ENOTEMPTY && errno != EEXIST && errno != ENOENT) { 00205 rsyserr(FERROR, errno, "delete_file: rmdir %s failed", 00206 full_fname(fname)); 00207 return -1; 00208 } 00209 00210 return 0; 00211 }
static void delete_in_dir | ( | struct file_list * | flist, | |
char * | fbuf, | |||
struct file_struct * | file, | |||
STRUCT_STAT * | stp | |||
) | [static] |
generator.c の 219 行で定義されています。
参照先 allowed_lull・file_struct::basename・file_list::count・delete_item()・file_struct::depth・file_struct::dir・f_name()・file_list::files・filesystem_dev・FINFO・file_struct::flags・flist_find()・flist_free()・get_dirlist()・ignore_errors・io_error・maybe_send_keepalive()・file_struct::mode・module_id・one_file_system・pop_local_filters()・push_local_filters()・rprintf()・verbose.
参照元 do_delete_pass()・generate_files()・recv_generator().
00221 { 00222 static int min_depth = MAXPATHLEN, cur_depth = -1; 00223 static void *filt_array[MAXPATHLEN/2+1]; 00224 static int already_warned = 0; 00225 struct file_list *dirlist; 00226 char delbuf[MAXPATHLEN]; 00227 int dlen, i; 00228 00229 if (!flist) { 00230 while (cur_depth >= min_depth) 00231 pop_local_filters(filt_array[cur_depth--]); 00232 min_depth = MAXPATHLEN; 00233 cur_depth = -1; 00234 return; 00235 } 00236 00237 if (verbose > 2) 00238 rprintf(FINFO, "delete_in_dir(%s)\n", fbuf); 00239 00240 if (allowed_lull) 00241 maybe_send_keepalive(); 00242 00243 if (file->dir.depth >= MAXPATHLEN/2+1) 00244 return; /* Impossible... */ 00245 00246 if (io_error && !(lp_ignore_errors(module_id) || ignore_errors)) { 00247 if (already_warned) 00248 return; 00249 rprintf(FINFO, 00250 "IO error encountered -- skipping file deletion\n"); 00251 already_warned = 1; 00252 return; 00253 } 00254 00255 while (cur_depth >= file->dir.depth && cur_depth >= min_depth) 00256 pop_local_filters(filt_array[cur_depth--]); 00257 cur_depth = file->dir.depth; 00258 if (min_depth > cur_depth) 00259 min_depth = cur_depth; 00260 dlen = strlen(fbuf); 00261 filt_array[cur_depth] = push_local_filters(fbuf, dlen); 00262 00263 if (one_file_system) { 00264 if (file->flags & FLAG_TOP_DIR) 00265 filesystem_dev = stp->st_dev; 00266 else if (filesystem_dev != stp->st_dev) 00267 return; 00268 } 00269 00270 dirlist = get_dirlist(fbuf, dlen, 0); 00271 00272 /* If an item in dirlist is not found in flist, delete it 00273 * from the filesystem. */ 00274 for (i = dirlist->count; i--; ) { 00275 struct file_struct *fp = dirlist->files[i]; 00276 if (!fp->basename || fp->flags & FLAG_MOUNT_POINT) 00277 continue; 00278 if (flist_find(flist, fp) < 0) { 00279 f_name(fp, delbuf); 00280 delete_item(delbuf, fp->mode, DEL_FORCE_RECURSE); 00281 } 00282 } 00283 00284 flist_free(dirlist); 00285 }
static void do_delete_pass | ( | struct file_list * | flist | ) | [static] |
generator.c の 289 行で定義されています。
参照先 am_server・file_list::count・delete_in_dir()・do_progress・dry_run・f_name()・file_list::files・FINFO・keep_dirlinks・link_stat()・list_only・rprintf()・verbose.
参照元 generate_files().
00290 { 00291 char fbuf[MAXPATHLEN]; 00292 STRUCT_STAT st; 00293 int j; 00294 00295 if (dry_run > 1 /* destination doesn't exist yet */ 00296 || list_only) 00297 return; 00298 00299 for (j = 0; j < flist->count; j++) { 00300 struct file_struct *file = flist->files[j]; 00301 00302 if (!(file->flags & FLAG_DEL_HERE)) 00303 continue; 00304 00305 f_name(file, fbuf); 00306 if (verbose > 1 && file->flags & FLAG_TOP_DIR) 00307 rprintf(FINFO, "deleting in %s\n", fbuf); 00308 00309 if (link_stat(fbuf, &st, keep_dirlinks) < 0 00310 || !S_ISDIR(st.st_mode)) 00311 continue; 00312 00313 delete_in_dir(flist, fbuf, file, &st); 00314 } 00315 delete_in_dir(NULL, NULL, NULL, NULL); 00316 00317 if (do_progress && !am_server) 00318 rprintf(FINFO, " \r"); 00319 }
int unchanged_attrs | ( | struct file_struct * | file, | |
STRUCT_STAT * | st | |||
) |
generator.c の 321 行で定義されています。
参照先 am_root・file_struct::gid・file_struct::mode・preserve_gid・preserve_perms・preserve_uid・file_struct::uid.
参照元 hard_link_check()・try_dests_non()・try_dests_reg().
00322 { 00323 /* FIXME: Flag ACL changes. */ 00324 00325 if (preserve_perms 00326 && (st->st_mode & CHMOD_BITS) != (file->mode & CHMOD_BITS)) 00327 return 0; 00328 00329 if (am_root && preserve_uid && st->st_uid != file->uid) 00330 return 0; 00331 00332 if (preserve_gid && file->gid != GID_NONE && st->st_gid != file->gid) 00333 return 0; 00334 00335 return 1; 00336 }
void itemize | ( | struct file_struct * | file, | |
int | ndx, | |||
int | statret, | |||
STRUCT_STAT * | st, | |||
int32 | iflags, | |||
uchar | fnamecmp_type, | |||
char * | xname | |||
) |
generator.c の 338 行で定義されています。
参照先 am_root・cmp_time()・file_struct::gid・file_struct::length・log_format_has_i・log_item()・file_struct::mode・file_struct::modtime・omit_dir_times・preserve_gid・preserve_times・preserve_uid・protocol_version・read_batch・sock_f_out・stats・file_struct::uid・verbose・write_byte()・write_int()・write_shortint()・write_vstring().
参照元 hard_link_one()・maybe_hard_link()・recv_generator()・try_dests_non()・try_dests_reg().
00340 { 00341 if (statret >= 0) { /* A from-dest-dir statret can == 1! */ 00342 int keep_time = !preserve_times ? 0 00343 : S_ISDIR(file->mode) ? !omit_dir_times 00344 : !S_ISLNK(file->mode); 00345 00346 if (S_ISREG(file->mode) && file->length != st->st_size) 00347 iflags |= ITEM_REPORT_SIZE; 00348 if ((iflags & (ITEM_TRANSFER|ITEM_LOCAL_CHANGE) && !keep_time 00349 && (!(iflags & ITEM_XNAME_FOLLOWS) || *xname)) 00350 || (keep_time && cmp_time(file->modtime, st->st_mtime) != 0)) 00351 iflags |= ITEM_REPORT_TIME; 00352 if ((file->mode & CHMOD_BITS) != (st->st_mode & CHMOD_BITS)) 00353 iflags |= ITEM_REPORT_PERMS; 00354 if (preserve_uid && am_root && file->uid != st->st_uid) 00355 iflags |= ITEM_REPORT_OWNER; 00356 if (preserve_gid && file->gid != GID_NONE 00357 && st->st_gid != file->gid) 00358 iflags |= ITEM_REPORT_GROUP; 00359 /* FIXME: Itemize ACL changes. ITEM_REPORT_XATTR? */ 00360 } else 00361 iflags |= ITEM_IS_NEW; 00362 00363 iflags &= 0xffff; 00364 if ((iflags & SIGNIFICANT_ITEM_FLAGS || verbose > 1 00365 || log_format_has_i > 1 || (xname && *xname)) && !read_batch) { 00366 if (protocol_version >= 29) { 00367 if (ndx >= 0) 00368 write_int(sock_f_out, ndx); 00369 write_shortint(sock_f_out, iflags); 00370 if (iflags & ITEM_BASIS_TYPE_FOLLOWS) 00371 write_byte(sock_f_out, fnamecmp_type); 00372 if (iflags & ITEM_XNAME_FOLLOWS) 00373 write_vstring(sock_f_out, xname, strlen(xname)); 00374 } else if (ndx >= 0) 00375 log_item(file, &stats, iflags, xname); 00376 } 00377 }
int unchanged_file | ( | char * | fn, | |
struct file_struct * | file, | |||
STRUCT_STAT * | st | |||
) |
generator.c の 381 行で定義されています。
参照先 always_checksum・checksum_len・cmp_time()・file_checksum()・ignore_times・file_struct::length・file_struct::modtime・size_only・file_struct::sum・file_struct::u.
参照元 hard_link_check()・recv_generator()・try_dests_reg().
00382 { 00383 if (st->st_size != file->length) 00384 return 0; 00385 00386 /* if always checksum is set then we use the checksum instead 00387 of the file time to determine whether to sync */ 00388 if (always_checksum && S_ISREG(st->st_mode)) { 00389 char sum[MD4_SUM_LENGTH]; 00390 file_checksum(fn, sum, st->st_size); 00391 return memcmp(sum, file->u.sum, checksum_len) == 0; 00392 } 00393 00394 if (size_only) 00395 return 1; 00396 00397 if (ignore_times) 00398 return 0; 00399 00400 return cmp_time(st->st_mtime, file->modtime) == 0; 00401 }
static void sum_sizes_sqroot | ( | struct sum_struct * | sum, | |
int64 | len | |||
) | [static] |
generator.c の 421 行で定義されています。
参照先 block_size・csum_length・FINFO・protocol_version・rprintf()・file_struct::sum・verbose.
00422 { 00423 int32 blength; 00424 int s2length; 00425 00426 if (block_size) 00427 blength = block_size; 00428 else if (len <= BLOCK_SIZE * BLOCK_SIZE) 00429 blength = BLOCK_SIZE; 00430 else { 00431 int32 c; 00432 int64 l; 00433 int cnt; 00434 for (c = 1, l = len, cnt = 0; l >>= 2; c <<= 1, cnt++) {} 00435 if (cnt >= 31 || c >= MAX_BLOCK_SIZE) 00436 blength = MAX_BLOCK_SIZE; 00437 else { 00438 blength = 0; 00439 do { 00440 blength |= c; 00441 if (len < (int64)blength * blength) 00442 blength &= ~c; 00443 c >>= 1; 00444 } while (c >= 8); /* round to multiple of 8 */ 00445 blength = MAX(blength, BLOCK_SIZE); 00446 } 00447 } 00448 00449 if (protocol_version < 27) { 00450 s2length = csum_length; 00451 } else if (csum_length == SUM_LENGTH) { 00452 s2length = SUM_LENGTH; 00453 } else { 00454 int32 c; 00455 int64 l; 00456 int b = BLOCKSUM_BIAS; 00457 for (l = len; l >>= 1; b += 2) {} 00458 for (c = blength; c >>= 1 && b; b--) {} 00459 /* add a bit, subtract rollsum, round up. */ 00460 s2length = (b + 1 - 32 + 7) / 8; /* --optimize in compiler-- */ 00461 s2length = MAX(s2length, csum_length); 00462 s2length = MIN(s2length, SUM_LENGTH); 00463 } 00464 00465 sum->flength = len; 00466 sum->blength = blength; 00467 sum->s2length = s2length; 00468 sum->remainder = len % blength; 00469 sum->count = len / blength + (sum->remainder != 0); 00470 00471 if (sum->count && verbose > 2) { 00472 rprintf(FINFO, 00473 "count=%.0f rem=%ld blength=%ld s2length=%d flength=%.0f\n", 00474 (double)sum->count, (long)sum->remainder, (long)sum->blength, 00475 sum->s2length, (double)sum->flength); 00476 } 00477 }
static void generate_and_send_sums | ( | int | fd, | |
OFF_T | len, | |||
int | f_out, | |||
int | f_copy | |||
) | [static] |
generator.c の 485 行で定義されています。
参照先 append_mode・sum_struct::blength・sum_struct::count・FINFO・full_write()・get_checksum1()・get_checksum2()・map_file()・map_ptr()・rprintf()・sum_struct::s2length・sum_sizes_sqroot()・unmap_file()・verbose・write_buf()・write_int()・write_sum_head().
参照元 recv_generator().
00486 { 00487 int32 i; 00488 struct map_struct *mapbuf; 00489 struct sum_struct sum; 00490 OFF_T offset = 0; 00491 00492 sum_sizes_sqroot(&sum, len); 00493 write_sum_head(f_out, &sum); 00494 00495 if (append_mode > 0 && f_copy < 0) 00496 return; 00497 00498 if (len > 0) 00499 mapbuf = map_file(fd, len, MAX_MAP_SIZE, sum.blength); 00500 else 00501 mapbuf = NULL; 00502 00503 for (i = 0; i < sum.count; i++) { 00504 int32 n1 = (int32)MIN(len, (OFF_T)sum.blength); 00505 char *map = map_ptr(mapbuf, offset, n1); 00506 char sum2[SUM_LENGTH]; 00507 uint32 sum1; 00508 00509 len -= n1; 00510 offset += n1; 00511 00512 if (f_copy >= 0) { 00513 full_write(f_copy, map, n1); 00514 if (append_mode > 0) 00515 continue; 00516 } 00517 00518 sum1 = get_checksum1(map, n1); 00519 get_checksum2(map, n1, sum2); 00520 00521 if (verbose > 3) { 00522 rprintf(FINFO, 00523 "chunk[%.0f] offset=%.0f len=%ld sum1=%08lx\n", 00524 (double)i, (double)offset - n1, (long)n1, 00525 (unsigned long)sum1); 00526 } 00527 write_int(f_out, sum1); 00528 write_buf(f_out, sum2, sum.s2length); 00529 } 00530 00531 if (mapbuf) 00532 unmap_file(mapbuf); 00533 }
static int find_fuzzy | ( | struct file_struct * | file, | |
struct file_list * | dirlist | |||
) | [static] |
generator.c の 537 行で定義されています。
参照先 file_struct::basename・cmp_time()・file_list::count・file_list::files・find_filename_suffix()・FINFO・fuzzy_distance()・file_struct::length・file_struct::modtime・name・rprintf()・verbose.
参照元 recv_generator().
00538 { 00539 int fname_len, fname_suf_len; 00540 const char *fname_suf, *fname = file->basename; 00541 uint32 lowest_dist = 25 << 16; /* ignore a distance greater than 25 */ 00542 int j, lowest_j = -1; 00543 00544 fname_len = strlen(fname); 00545 fname_suf = find_filename_suffix(fname, fname_len, &fname_suf_len); 00546 00547 for (j = 0; j < dirlist->count; j++) { 00548 struct file_struct *fp = dirlist->files[j]; 00549 const char *suf, *name; 00550 int len, suf_len; 00551 uint32 dist; 00552 00553 if (!S_ISREG(fp->mode) || !fp->length 00554 || fp->flags & FLAG_NO_FUZZY) 00555 continue; 00556 00557 name = fp->basename; 00558 00559 if (fp->length == file->length 00560 && cmp_time(fp->modtime, file->modtime) == 0) { 00561 if (verbose > 4) { 00562 rprintf(FINFO, 00563 "fuzzy size/modtime match for %s\n", 00564 name); 00565 } 00566 return j; 00567 } 00568 00569 len = strlen(name); 00570 suf = find_filename_suffix(name, len, &suf_len); 00571 00572 dist = fuzzy_distance(name, len, fname, fname_len); 00573 /* Add some extra weight to how well the suffixes match. */ 00574 dist += fuzzy_distance(suf, suf_len, fname_suf, fname_suf_len) 00575 * 10; 00576 if (verbose > 4) { 00577 rprintf(FINFO, "fuzzy distance for %s = %d.%05d\n", 00578 name, (int)(dist>>16), (int)(dist&0xFFFF)); 00579 } 00580 if (dist <= lowest_dist) { 00581 lowest_dist = dist; 00582 lowest_j = j; 00583 } 00584 } 00585 00586 return lowest_j; 00587 }
void check_for_finished_hlinks | ( | int | itemizing, | |
enum logcode | code | |||
) |
generator.c の 589 行で定義されています。
参照先 file_list::count・file_list::files・get_hlink_num()・hard_link_cluster()・file_struct::link_u・file_struct::links・the_file_list.
参照元 generate_files()・get_redo_num()・increment_active_files().
00590 { 00591 struct file_struct *file; 00592 int ndx; 00593 00594 while ((ndx = get_hlink_num()) != -1) { 00595 if (ndx < 0 || ndx >= the_file_list->count) 00596 continue; 00597 00598 file = the_file_list->files[ndx]; 00599 if (!file->link_u.links) 00600 continue; 00601 00602 hard_link_cluster(file, ndx, itemizing, code); 00603 } 00604 }
static int try_dests_reg | ( | struct file_struct * | file, | |
char * | fname, | |||
int | ndx, | |||
char * | cmpbuf, | |||
STRUCT_STAT * | stp, | |||
int | itemizing, | |||
int | maybe_ATTRS_REPORT, | |||
enum logcode | code | |||
) | [static] |
generator.c の 609 行で定義されています。
参照先 always_checksum・basis_dir・cmp_time()・copy_dest・copy_file()・daemon_log_format_has_i・dry_run・errno・FCLIENT・FINFO・full_fname()・hard_link_cluster()・hard_link_one()・ignore_times・itemize()・link_dest・link_stat()・file_struct::mode・file_struct::modtime・pathjoin()・preserve_hard_links・rprintf()・rsyserr()・set_file_attrs()・unchanged_attrs()・unchanged_file()・verbose.
参照元 recv_generator().
00612 { 00613 int best_match = -1; 00614 int match_level = 0; 00615 int j = 0; 00616 00617 do { 00618 pathjoin(cmpbuf, MAXPATHLEN, basis_dir[j], fname); 00619 if (link_stat(cmpbuf, stp, 0) < 0 || !S_ISREG(stp->st_mode)) 00620 continue; 00621 switch (match_level) { 00622 case 0: 00623 best_match = j; 00624 match_level = 1; 00625 /* FALL THROUGH */ 00626 case 1: 00627 if (!unchanged_file(cmpbuf, file, stp)) 00628 continue; 00629 best_match = j; 00630 match_level = 2; 00631 /* FALL THROUGH */ 00632 case 2: 00633 if (!unchanged_attrs(file, stp)) 00634 continue; 00635 if ((always_checksum || ignore_times) 00636 && cmp_time(stp->st_mtime, file->modtime)) 00637 continue; 00638 best_match = j; 00639 match_level = 3; 00640 break; 00641 } 00642 break; 00643 } while (basis_dir[++j] != NULL); 00644 00645 if (!match_level) 00646 return -1; 00647 00648 if (j != best_match) { 00649 j = best_match; 00650 pathjoin(cmpbuf, MAXPATHLEN, basis_dir[j], fname); 00651 if (link_stat(cmpbuf, stp, 0) < 0) 00652 match_level = 0; 00653 } 00654 00655 #ifdef HAVE_LINK 00656 if (match_level == 3 && !copy_dest) { 00657 if (link_dest) { 00658 if (hard_link_one(file, ndx, fname, 0, stp, 00659 cmpbuf, 1, 00660 itemizing && verbose > 1, 00661 code) < 0) 00662 goto try_a_copy; 00663 if (preserve_hard_links && file->link_u.links) 00664 hard_link_cluster(file, ndx, itemizing, code); 00665 } else if (itemizing) 00666 itemize(file, ndx, 0, stp, 0, 0, NULL); 00667 if (verbose > 1 && maybe_ATTRS_REPORT) { 00668 code = daemon_log_format_has_i || dry_run 00669 ? FCLIENT : FINFO; 00670 rprintf(code, "%s is uptodate\n", fname); 00671 } 00672 return -2; 00673 } 00674 #endif 00675 00676 if (match_level >= 2) { 00677 try_a_copy: /* Copy the file locally. */ 00678 if (copy_file(cmpbuf, fname, file->mode) < 0) { 00679 if (verbose) { 00680 rsyserr(FINFO, errno, "copy_file %s => %s", 00681 full_fname(cmpbuf), fname); 00682 } 00683 return -1; 00684 } 00685 if (itemizing) 00686 itemize(file, ndx, 0, stp, ITEM_LOCAL_CHANGE, 0, NULL); 00687 set_file_attrs(fname, file, NULL, 0); 00688 if (maybe_ATTRS_REPORT 00689 && ((!itemizing && verbose && match_level == 2) 00690 || (verbose > 1 && match_level == 3))) { 00691 code = daemon_log_format_has_i || dry_run 00692 ? FCLIENT : FINFO; 00693 rprintf(code, "%s%s\n", fname, 00694 match_level == 3 ? " is uptodate" : ""); 00695 } 00696 if (preserve_hard_links && file->link_u.links) 00697 hard_link_cluster(file, ndx, itemizing, code); 00698 return -2; 00699 } 00700 00701 return FNAMECMP_BASIS_DIR_LOW + j; 00702 }
static int try_dests_non | ( | struct file_struct * | file, | |
char * | fname, | |||
int | ndx, | |||
int | itemizing, | |||
int | maybe_ATTRS_REPORT, | |||
enum logcode | code | |||
) | [static] |
generator.c の 706 行で定義されています。
参照先 basis_dir・compare_dest・daemon_log_format_has_i・do_link()・dry_run・errno・FCLIENT・FERROR・FINFO・hard_link_cluster()・itemize()・file_struct::link・link_dest・link_stat()・file_struct::link_u・file_struct::links・log_format_has_i・file_struct::mode・pathjoin()・preserve_hard_links・file_struct::rdev・rprintf()・rsyserr()・file_struct::u・unchanged_attrs()・verbose.
参照元 recv_generator().
00709 { 00710 char fnamebuf[MAXPATHLEN]; 00711 STRUCT_STAT st; 00712 int i = 0; 00713 00714 do { 00715 pathjoin(fnamebuf, MAXPATHLEN, basis_dir[i], fname); 00716 if (link_stat(fnamebuf, &st, 0) < 0 || S_ISDIR(st.st_mode) 00717 || !unchanged_attrs(file, &st)) 00718 continue; 00719 if (S_ISLNK(file->mode)) { 00720 #ifdef SUPPORT_LINKS 00721 char lnk[MAXPATHLEN]; 00722 int len; 00723 if ((len = readlink(fnamebuf, lnk, MAXPATHLEN-1)) <= 0) 00724 continue; 00725 lnk[len] = '\0'; 00726 if (strcmp(lnk, file->u.link) != 0) 00727 #endif 00728 continue; 00729 } else if (IS_SPECIAL(file->mode)) { 00730 if (!IS_SPECIAL(st.st_mode) || st.st_rdev != file->u.rdev) 00731 continue; 00732 } else if (IS_DEVICE(file->mode)) { 00733 if (!IS_DEVICE(st.st_mode) || st.st_rdev != file->u.rdev) 00734 continue; 00735 } else { 00736 rprintf(FERROR, 00737 "internal: try_dests_non() called with invalid mode (%o)\n", 00738 file->mode); 00739 exit_cleanup(RERR_UNSUPPORTED); 00740 } 00741 if (link_dest 00742 #ifndef CAN_HARDLINK_SYMLINK 00743 && !S_ISLNK(file->mode) 00744 #endif 00745 #ifndef CAN_HARDLINK_SPECIAL 00746 && !IS_SPECIAL(file->mode) && !IS_DEVICE(file->mode) 00747 #endif 00748 ) { 00749 if (do_link(fnamebuf, fname) < 0) { 00750 rsyserr(FERROR, errno, 00751 "failed to hard-link %s with %s", 00752 fnamebuf, fname); 00753 break; 00754 } 00755 if (preserve_hard_links && file->link_u.links) 00756 hard_link_cluster(file, ndx, itemizing, code); 00757 } 00758 if (itemizing && log_format_has_i && verbose > 1) { 00759 int changes = compare_dest ? 0 : ITEM_LOCAL_CHANGE 00760 + (link_dest ? ITEM_XNAME_FOLLOWS : 0); 00761 char *lp = link_dest ? "" : NULL; 00762 itemize(file, ndx, 0, &st, changes, 0, lp); 00763 } 00764 if (verbose > 1 && maybe_ATTRS_REPORT) { 00765 code = daemon_log_format_has_i || dry_run 00766 ? FCLIENT : FINFO; 00767 rprintf(code, "%s is uptodate\n", fname); 00768 } 00769 return -2; 00770 } while (basis_dir[++i] != NULL); 00771 00772 return -1; 00773 }
static void recv_generator | ( | char * | fname, | |
struct file_struct * | file, | |||
int | ndx, | |||
int | itemizing, | |||
int | maybe_ATTRS_REPORT, | |||
enum logcode | code, | |||
int | f_out | |||
) | [static] |
generator.c の 788 行で定義されています。
参照先 always_checksum・am_root・append_mode・file_struct::basename・basis_dir・check_filter()・cmp_time()・copy_dest・file_list::count・create_directory_path()・default_perms_for_dir()・delay_updates・delete_during・delete_in_dir()・delete_item()・delete_mode・file_struct::depth・dest_mode()・file_struct::dir・file_struct::dirname・do_mkdir()・do_mknod()・do_open()・do_stat()・do_symlink()・do_unlink()・do_xfers・dry_run・errno・f_name()・FERROR・file_list::files・find_fuzzy()・FINFO・file_struct::flags・flist_find()・flist_free()・full_fname()・fuzzy_basis・generate_and_send_sums()・get_backup_name()・get_dirlist()・handle_partial_dir()・hard_link_check()・hard_link_cluster()・filter_list_struct::head・ignore_existing・ignore_non_existing・implied_dirs・increment_active_files()・inplace・itemize()・keep_dirlinks・file_struct::length・file_struct::link・link_dest・link_stat()・file_struct::link_u・file_struct::links・list_only・make_backups・make_file()・max_size・min_size・file_struct::mode・file_struct::modtime・MSG_SUCCESS・partial_dir・partial_dir_fname()・preserve_devices・preserve_hard_links・preserve_links・preserve_perms・preserve_specials・file_struct::rdev・read_batch・relative_paths・remove_sent_files・robust_unlink()・rprintf()・rsyserr()・safe_symlinks・send_msg()・server_filter_list・set_file_attrs()・the_file_list・try_dests_non()・try_dests_reg()・file_struct::u・unchanged_file()・unsafe_symlink()・update_only・verbose・whole_file・write_int()・write_sum_head().
参照元 generate_files().
00791 { 00792 static int missing_below = -1, excluded_below = -1; 00793 static char *parent_dirname = ""; 00794 static struct file_list *fuzzy_dirlist = NULL; 00795 static int need_fuzzy_dirlist = 0; 00796 struct file_struct *fuzzy_file = NULL; 00797 int fd = -1, f_copy = -1; 00798 STRUCT_STAT st, real_st, partial_st; 00799 struct file_struct *back_file = NULL; 00800 int statret, real_ret, stat_errno; 00801 char *fnamecmp, *partialptr, *backupptr = NULL; 00802 char fnamecmpbuf[MAXPATHLEN]; 00803 uchar fnamecmp_type; 00804 int del_opts = DEL_TERSE | (delete_mode ? DEL_FORCE_RECURSE : 0); 00805 00806 if (list_only) 00807 return; 00808 00809 if (!fname) { 00810 if (fuzzy_dirlist) { 00811 flist_free(fuzzy_dirlist); 00812 fuzzy_dirlist = NULL; 00813 } 00814 if (missing_below >= 0) { 00815 dry_run--; 00816 missing_below = -1; 00817 } 00818 parent_dirname = ""; 00819 return; 00820 } 00821 00822 if (verbose > 2) 00823 rprintf(FINFO, "recv_generator(%s,%d)\n", fname, ndx); 00824 00825 if (server_filter_list.head) { 00826 if (excluded_below >= 0) { 00827 if (file->dir.depth > excluded_below) 00828 goto skipping; 00829 excluded_below = -1; 00830 } 00831 if (check_filter(&server_filter_list, fname, 00832 S_ISDIR(file->mode)) < 0) { 00833 if (S_ISDIR(file->mode)) 00834 excluded_below = file->dir.depth; 00835 skipping: 00836 if (verbose) { 00837 rprintf(FINFO, 00838 "skipping server-excluded file \"%s\"\n", 00839 fname); 00840 } 00841 return; 00842 } 00843 } 00844 00845 if (missing_below >= 0 && file->dir.depth <= missing_below) { 00846 dry_run--; 00847 missing_below = -1; 00848 } 00849 if (dry_run > 1) { 00850 statret = -1; 00851 stat_errno = ENOENT; 00852 } else { 00853 char *dn = file->dirname ? file->dirname : "."; 00854 if (parent_dirname != dn && strcmp(parent_dirname, dn) != 0) { 00855 if (relative_paths && !implied_dirs 00856 && do_stat(dn, &st) < 0 00857 && create_directory_path(fname) < 0) { 00858 rsyserr(FERROR, errno, 00859 "recv_generator: mkdir %s failed", 00860 full_fname(dn)); 00861 } 00862 if (fuzzy_dirlist) { 00863 flist_free(fuzzy_dirlist); 00864 fuzzy_dirlist = NULL; 00865 } 00866 if (fuzzy_basis) 00867 need_fuzzy_dirlist = 1; 00868 #ifdef SUPPORT_ACLS 00869 if (!preserve_perms) 00870 dflt_perms = default_perms_for_dir(dn); 00871 #endif 00872 } 00873 parent_dirname = dn; 00874 00875 if (need_fuzzy_dirlist && S_ISREG(file->mode)) { 00876 fuzzy_dirlist = get_dirlist(dn, -1, 1); 00877 need_fuzzy_dirlist = 0; 00878 } 00879 00880 statret = link_stat(fname, &st, 00881 keep_dirlinks && S_ISDIR(file->mode)); 00882 stat_errno = errno; 00883 } 00884 00885 if (ignore_non_existing && statret == -1 && stat_errno == ENOENT) { 00886 if (verbose > 1) { 00887 rprintf(FINFO, "not creating new %s \"%s\"\n", 00888 S_ISDIR(file->mode) ? "directory" : "file", 00889 fname); 00890 } 00891 return; 00892 } 00893 00894 /* If we're not preserving permissions, change the file-list's 00895 * mode based on the local permissions and some heuristics. */ 00896 if (!preserve_perms) { 00897 int exists = statret == 0 00898 && S_ISDIR(st.st_mode) == S_ISDIR(file->mode); 00899 file->mode = dest_mode(file->mode, st.st_mode, dflt_perms, 00900 exists); 00901 } 00902 00903 if (S_ISDIR(file->mode)) { 00904 /* The file to be received is a directory, so we need 00905 * to prepare appropriately. If there is already a 00906 * file of that name and it is *not* a directory, then 00907 * we need to delete it. If it doesn't exist, then 00908 * (perhaps recursively) create it. */ 00909 if (statret == 0 && !S_ISDIR(st.st_mode)) { 00910 if (delete_item(fname, st.st_mode, del_opts) < 0) 00911 return; 00912 statret = -1; 00913 } 00914 if (dry_run && statret != 0 && missing_below < 0) { 00915 missing_below = file->dir.depth; 00916 dry_run++; 00917 } 00918 if (itemizing && f_out != -1) { 00919 itemize(file, ndx, statret, &st, 00920 statret ? ITEM_LOCAL_CHANGE : 0, 0, NULL); 00921 } 00922 if (statret != 0 && do_mkdir(fname,file->mode) < 0 && errno != EEXIST) { 00923 if (!relative_paths || errno != ENOENT 00924 || create_directory_path(fname) < 0 00925 || (do_mkdir(fname, file->mode) < 0 && errno != EEXIST)) { 00926 rsyserr(FERROR, errno, 00927 "recv_generator: mkdir %s failed", 00928 full_fname(fname)); 00929 } 00930 } 00931 if (set_file_attrs(fname, file, statret ? NULL : &st, 0) 00932 && verbose && code && f_out != -1) 00933 rprintf(code, "%s/\n", fname); 00934 if (delete_during && f_out != -1 && !phase && dry_run < 2 00935 && (file->flags & FLAG_DEL_HERE)) 00936 delete_in_dir(the_file_list, fname, file, &st); 00937 return; 00938 } 00939 00940 if (preserve_hard_links && file->link_u.links 00941 && hard_link_check(file, ndx, fname, statret, &st, 00942 itemizing, code, HL_CHECK_MASTER)) 00943 return; 00944 00945 if (preserve_links && S_ISLNK(file->mode)) { 00946 #ifdef SUPPORT_LINKS 00947 if (safe_symlinks && unsafe_symlink(file->u.link, fname)) { 00948 if (verbose) { 00949 if (the_file_list->count == 1) 00950 fname = f_name(file, NULL); 00951 rprintf(FINFO, 00952 "ignoring unsafe symlink %s -> \"%s\"\n", 00953 full_fname(fname), file->u.link); 00954 } 00955 return; 00956 } 00957 if (statret == 0) { 00958 char lnk[MAXPATHLEN]; 00959 int len; 00960 00961 if (!S_ISDIR(st.st_mode) 00962 && (len = readlink(fname, lnk, MAXPATHLEN-1)) > 0) { 00963 lnk[len] = 0; 00964 /* A link already pointing to the 00965 * right place -- no further action 00966 * required. */ 00967 if (strcmp(lnk, file->u.link) == 0) { 00968 if (itemizing) { 00969 itemize(file, ndx, 0, &st, 0, 00970 0, NULL); 00971 } 00972 set_file_attrs(fname, file, &st, 00973 maybe_ATTRS_REPORT); 00974 if (preserve_hard_links 00975 && file->link_u.links) { 00976 hard_link_cluster(file, ndx, 00977 itemizing, 00978 code); 00979 } 00980 return; 00981 } 00982 } 00983 /* Not the right symlink (or not a symlink), so 00984 * delete it. */ 00985 if (delete_item(fname, st.st_mode, del_opts) < 0) 00986 return; 00987 if (!S_ISLNK(st.st_mode)) 00988 statret = -1; 00989 } else if (basis_dir[0] != NULL) { 00990 if (try_dests_non(file, fname, ndx, itemizing, 00991 maybe_ATTRS_REPORT, code) == -2) { 00992 #ifndef CAN_HARDLINK_SYMLINK 00993 if (link_dest) { 00994 /* Resort to --copy-dest behavior. */ 00995 } else 00996 #endif 00997 if (!copy_dest) 00998 return; 00999 itemizing = code = 0; 01000 } 01001 } 01002 if (preserve_hard_links && file->link_u.links 01003 && hard_link_check(file, ndx, fname, -1, &st, 01004 itemizing, code, HL_SKIP)) 01005 return; 01006 if (do_symlink(file->u.link,fname) != 0) { 01007 rsyserr(FERROR, errno, "symlink %s -> \"%s\" failed", 01008 full_fname(fname), file->u.link); 01009 } else { 01010 set_file_attrs(fname, file, NULL, 0); 01011 if (itemizing) { 01012 itemize(file, ndx, statret, &st, 01013 ITEM_LOCAL_CHANGE, 0, NULL); 01014 } 01015 if (code && verbose) { 01016 rprintf(code, "%s -> %s\n", fname, 01017 file->u.link); 01018 } 01019 if (remove_sent_files && !dry_run) { 01020 char numbuf[4]; 01021 SIVAL(numbuf, 0, ndx); 01022 send_msg(MSG_SUCCESS, numbuf, 4); 01023 } 01024 if (preserve_hard_links && file->link_u.links) 01025 hard_link_cluster(file, ndx, itemizing, code); 01026 } 01027 #endif 01028 return; 01029 } 01030 01031 if ((am_root && preserve_devices && IS_DEVICE(file->mode)) 01032 || (preserve_specials && IS_SPECIAL(file->mode))) { 01033 if (statret != 0 && basis_dir[0] != NULL) { 01034 if (try_dests_non(file, fname, ndx, itemizing, 01035 maybe_ATTRS_REPORT, code) == -2) { 01036 #ifndef CAN_HARDLINK_SPECIAL 01037 if (link_dest) { 01038 /* Resort to --copy-dest behavior. */ 01039 } else 01040 #endif 01041 if (!copy_dest) 01042 return; 01043 itemizing = code = 0; 01044 } 01045 } 01046 if (statret != 0 01047 || (st.st_mode & ~CHMOD_BITS) != (file->mode & ~CHMOD_BITS) 01048 || st.st_rdev != file->u.rdev) { 01049 if (statret == 0 01050 && delete_item(fname, st.st_mode, del_opts) < 0) 01051 return; 01052 if (preserve_hard_links && file->link_u.links 01053 && hard_link_check(file, ndx, fname, -1, &st, 01054 itemizing, code, HL_SKIP)) 01055 return; 01056 if ((IS_DEVICE(file->mode) && !IS_DEVICE(st.st_mode)) 01057 || (IS_SPECIAL(file->mode) && !IS_SPECIAL(st.st_mode))) 01058 statret = -1; 01059 if (verbose > 2) { 01060 rprintf(FINFO,"mknod(%s,0%o,0x%x)\n", 01061 fname, 01062 (int)file->mode, (int)file->u.rdev); 01063 } 01064 if (do_mknod(fname,file->mode,file->u.rdev) < 0) { 01065 rsyserr(FERROR, errno, "mknod %s failed", 01066 full_fname(fname)); 01067 } else { 01068 set_file_attrs(fname, file, NULL, 0); 01069 if (itemizing) { 01070 itemize(file, ndx, statret, &st, 01071 ITEM_LOCAL_CHANGE, 0, NULL); 01072 } 01073 if (code && verbose) 01074 rprintf(code, "%s\n", fname); 01075 if (preserve_hard_links && file->link_u.links) { 01076 hard_link_cluster(file, ndx, 01077 itemizing, code); 01078 } 01079 } 01080 } else { 01081 if (itemizing) 01082 itemize(file, ndx, statret, &st, 0, 0, NULL); 01083 set_file_attrs(fname, file, &st, maybe_ATTRS_REPORT); 01084 if (preserve_hard_links && file->link_u.links) 01085 hard_link_cluster(file, ndx, itemizing, code); 01086 } 01087 return; 01088 } 01089 01090 if (!S_ISREG(file->mode)) { 01091 if (the_file_list->count == 1) 01092 fname = f_name(file, NULL); 01093 rprintf(FINFO, "skipping non-regular file \"%s\"\n", fname); 01094 return; 01095 } 01096 01097 if (max_size && file->length > max_size) { 01098 if (verbose > 1) { 01099 if (the_file_list->count == 1) 01100 fname = f_name(file, NULL); 01101 rprintf(FINFO, "%s is over max-size\n", fname); 01102 } 01103 return; 01104 } 01105 if (min_size && file->length < min_size) { 01106 if (verbose > 1) { 01107 if (the_file_list->count == 1) 01108 fname = f_name(file, NULL); 01109 rprintf(FINFO, "%s is under min-size\n", fname); 01110 } 01111 return; 01112 } 01113 01114 if (ignore_existing && statret == 0) { 01115 if (verbose > 1) 01116 rprintf(FINFO, "%s exists\n", fname); 01117 return; 01118 } 01119 01120 if (update_only && statret == 0 01121 && cmp_time(st.st_mtime, file->modtime) > 0) { 01122 if (verbose > 1) 01123 rprintf(FINFO, "%s is newer\n", fname); 01124 return; 01125 } 01126 01127 fnamecmp = fname; 01128 fnamecmp_type = FNAMECMP_FNAME; 01129 01130 if (statret == 0 && !S_ISREG(st.st_mode)) { 01131 if (delete_item(fname, st.st_mode, del_opts) != 0) 01132 return; 01133 statret = -1; 01134 stat_errno = ENOENT; 01135 } 01136 01137 if (statret != 0 && basis_dir[0] != NULL) { 01138 int j = try_dests_reg(file, fname, ndx, fnamecmpbuf, &st, 01139 itemizing, maybe_ATTRS_REPORT, code); 01140 if (j == -2) 01141 return; 01142 if (j != -1) { 01143 fnamecmp = fnamecmpbuf; 01144 fnamecmp_type = j; 01145 statret = 0; 01146 } 01147 } 01148 01149 real_ret = statret; 01150 real_st = st; 01151 01152 if (partial_dir && (partialptr = partial_dir_fname(fname)) != NULL 01153 && link_stat(partialptr, &partial_st, 0) == 0 01154 && S_ISREG(partial_st.st_mode)) { 01155 if (statret != 0) 01156 goto prepare_to_open; 01157 } else 01158 partialptr = NULL; 01159 01160 if (statret != 0 && fuzzy_dirlist && dry_run <= 1) { 01161 int j = find_fuzzy(file, fuzzy_dirlist); 01162 if (j >= 0) { 01163 fuzzy_file = fuzzy_dirlist->files[j]; 01164 f_name(fuzzy_file, fnamecmpbuf); 01165 if (verbose > 2) { 01166 rprintf(FINFO, "fuzzy basis selected for %s: %s\n", 01167 fname, fnamecmpbuf); 01168 } 01169 st.st_size = fuzzy_file->length; 01170 statret = 0; 01171 fnamecmp = fnamecmpbuf; 01172 fnamecmp_type = FNAMECMP_FUZZY; 01173 } 01174 } 01175 01176 if (statret != 0) { 01177 if (preserve_hard_links && file->link_u.links 01178 && hard_link_check(file, ndx, fname, statret, &st, 01179 itemizing, code, HL_SKIP)) 01180 return; 01181 if (stat_errno == ENOENT) 01182 goto notify_others; 01183 rsyserr(FERROR, stat_errno, "recv_generator: failed to stat %s", 01184 full_fname(fname)); 01185 return; 01186 } 01187 01188 if (append_mode && st.st_size > file->length) 01189 return; 01190 01191 if (fnamecmp_type <= FNAMECMP_BASIS_DIR_HIGH) 01192 ; 01193 else if (fnamecmp_type == FNAMECMP_FUZZY) 01194 ; 01195 else if (unchanged_file(fnamecmp, file, &st)) { 01196 if (partialptr) { 01197 do_unlink(partialptr); 01198 handle_partial_dir(partialptr, PDIR_DELETE); 01199 } 01200 if (itemizing) { 01201 itemize(file, ndx, real_ret, &real_st, 01202 0, 0, NULL); 01203 } 01204 set_file_attrs(fname, file, &st, maybe_ATTRS_REPORT); 01205 if (preserve_hard_links && file->link_u.links) 01206 hard_link_cluster(file, ndx, itemizing, code); 01207 return; 01208 } 01209 01210 prepare_to_open: 01211 if (partialptr) { 01212 st = partial_st; 01213 fnamecmp = partialptr; 01214 fnamecmp_type = FNAMECMP_PARTIAL_DIR; 01215 statret = 0; 01216 } 01217 01218 if (!do_xfers || read_batch || whole_file) 01219 goto notify_others; 01220 01221 if (fuzzy_dirlist) { 01222 int j = flist_find(fuzzy_dirlist, file); 01223 if (j >= 0) /* don't use changing file as future fuzzy basis */ 01224 fuzzy_dirlist->files[j]->flags |= FLAG_NO_FUZZY; 01225 } 01226 01227 /* open the file */ 01228 fd = do_open(fnamecmp, O_RDONLY, 0); 01229 01230 if (fd == -1) { 01231 rsyserr(FERROR, errno, "failed to open %s, continuing", 01232 full_fname(fnamecmp)); 01233 pretend_missing: 01234 /* pretend the file didn't exist */ 01235 if (preserve_hard_links && file->link_u.links 01236 && hard_link_check(file, ndx, fname, statret, &st, 01237 itemizing, code, HL_SKIP)) 01238 return; 01239 statret = real_ret = -1; 01240 goto notify_others; 01241 } 01242 01243 if (inplace && make_backups && fnamecmp_type == FNAMECMP_FNAME) { 01244 if (!(backupptr = get_backup_name(fname))) { 01245 close(fd); 01246 return; 01247 } 01248 if (!(back_file = make_file(fname, NULL, NULL, 0, NO_FILTERS))) { 01249 close(fd); 01250 goto pretend_missing; 01251 } 01252 if (robust_unlink(backupptr) && errno != ENOENT) { 01253 rsyserr(FERROR, errno, "unlink %s", 01254 full_fname(backupptr)); 01255 free(back_file); 01256 close(fd); 01257 return; 01258 } 01259 if ((f_copy = do_open(backupptr, 01260 O_WRONLY | O_CREAT | O_TRUNC | O_EXCL, 0600)) < 0) { 01261 rsyserr(FERROR, errno, "open %s", 01262 full_fname(backupptr)); 01263 free(back_file); 01264 close(fd); 01265 return; 01266 } 01267 fnamecmp_type = FNAMECMP_BACKUP; 01268 } 01269 01270 if (verbose > 3) { 01271 rprintf(FINFO, "gen mapped %s of size %.0f\n", 01272 fnamecmp, (double)st.st_size); 01273 } 01274 01275 if (verbose > 2) 01276 rprintf(FINFO, "generating and sending sums for %d\n", ndx); 01277 01278 notify_others: 01279 if (remove_sent_files && !delay_updates && !phase) 01280 increment_active_files(ndx, itemizing, code); 01281 write_int(f_out, ndx); 01282 if (itemizing) { 01283 int iflags = ITEM_TRANSFER; 01284 if (always_checksum) 01285 iflags |= ITEM_REPORT_CHECKSUM; 01286 if (fnamecmp_type != FNAMECMP_FNAME) 01287 iflags |= ITEM_BASIS_TYPE_FOLLOWS; 01288 if (fnamecmp_type == FNAMECMP_FUZZY) 01289 iflags |= ITEM_XNAME_FOLLOWS; 01290 itemize(file, -1, real_ret, &real_st, iflags, fnamecmp_type, 01291 fuzzy_file ? fuzzy_file->basename : NULL); 01292 } 01293 01294 if (!do_xfers) { 01295 if (preserve_hard_links && file->link_u.links) 01296 hard_link_cluster(file, ndx, itemizing, code); 01297 return; 01298 } 01299 if (read_batch) 01300 return; 01301 01302 if (statret != 0 || whole_file) { 01303 write_sum_head(f_out, NULL); 01304 return; 01305 } 01306 01307 generate_and_send_sums(fd, st.st_size, f_out, f_copy); 01308 01309 if (f_copy >= 0) { 01310 close(f_copy); 01311 set_file_attrs(backupptr, back_file, NULL, 0); 01312 if (verbose > 1) { 01313 rprintf(FINFO, "backed up %s to %s\n", 01314 fname, backupptr); 01315 } 01316 free(back_file); 01317 } 01318 01319 close(fd); 01320 }
void generate_files | ( | int | f_out, | |
struct file_list * | flist, | |||
char * | local_name | |||
) |
generator.c の 1322 行で定義されています。
参照先 allowed_lull・always_checksum・am_daemon・am_root・am_server・append_mode・check_for_finished_hlinks()・code・file_list::count・csum_length・daemon_log_format_has_i・delay_updates・delete_after・delete_before・delete_during・delete_in_dir()・deletion_count・do_chmod()・do_delete_pass()・do_progress・do_xfers・dry_run・errno・f_name()・FCLIENT・FERROR・file_list::files・FINFO・FLOG・full_fname()・get_redo_num()・ignore_existing・ignore_non_existing・ignore_timeout・ignore_times・io_error・list_only・log_format_has_i・make_backups・max_delete・max_size・maybe_flush_socket()・maybe_send_keepalive()・min_size・file_struct::mode・omit_dir_times・orig_umask・preserve_hard_links・preserve_times・protocol_version・recv_generator()・rprintf()・rsyserr()・size_only・strlcpy()・update_only・verbose・whole_file・write_int().
参照元 do_recv().
01323 { 01324 int i; 01325 char fbuf[MAXPATHLEN]; 01326 int itemizing, maybe_ATTRS_REPORT; 01327 enum logcode code; 01328 int lull_mod = allowed_lull * 5; 01329 int need_retouch_dir_times = preserve_times && !omit_dir_times; 01330 int need_retouch_dir_perms = 0; 01331 int save_ignore_existing = ignore_existing; 01332 int save_ignore_non_existing = ignore_non_existing; 01333 int save_do_progress = do_progress; 01334 int save_make_backups = make_backups; 01335 int dir_tweaking = !(list_only || local_name || dry_run); 01336 01337 if (protocol_version >= 29) { 01338 itemizing = 1; 01339 maybe_ATTRS_REPORT = log_format_has_i ? 0 : ATTRS_REPORT; 01340 code = daemon_log_format_has_i ? 0 : FLOG; 01341 } else if (am_daemon) { 01342 itemizing = daemon_log_format_has_i && do_xfers; 01343 maybe_ATTRS_REPORT = ATTRS_REPORT; 01344 code = itemizing || !do_xfers ? FCLIENT : FINFO; 01345 } else if (!am_server) { 01346 itemizing = log_format_has_i; 01347 maybe_ATTRS_REPORT = log_format_has_i ? 0 : ATTRS_REPORT; 01348 code = itemizing ? 0 : FINFO; 01349 } else { 01350 itemizing = 0; 01351 maybe_ATTRS_REPORT = ATTRS_REPORT; 01352 code = FINFO; 01353 } 01354 01355 if (verbose > 2) { 01356 rprintf(FINFO, "generator starting pid=%ld count=%d\n", 01357 (long)getpid(), flist->count); 01358 } 01359 01360 if (delete_before && !local_name && flist->count > 0) 01361 do_delete_pass(flist); 01362 do_progress = 0; 01363 01364 if (append_mode || whole_file < 0) 01365 whole_file = 0; 01366 if (verbose >= 2) { 01367 rprintf(FINFO, "delta-transmission %s\n", 01368 whole_file 01369 ? "disabled for local transfer or --whole-file" 01370 : "enabled"); 01371 } 01372 01373 /* Since we often fill up the outgoing socket and then just sit around 01374 * waiting for the other 2 processes to do their thing, we don't want 01375 * to exit on a timeout. If the data stops flowing, the receiver will 01376 * notice that and let us know via the redo pipe (or its closing). */ 01377 ignore_timeout = 1; 01378 01379 dflt_perms = (ACCESSPERMS & ~orig_umask); 01380 01381 for (i = 0; i < flist->count; i++) { 01382 struct file_struct *file = flist->files[i]; 01383 01384 if (!file->basename) 01385 continue; 01386 01387 if (local_name) 01388 strlcpy(fbuf, local_name, sizeof fbuf); 01389 else 01390 f_name(file, fbuf); 01391 recv_generator(fbuf, file, i, itemizing, maybe_ATTRS_REPORT, 01392 code, f_out); 01393 01394 /* We need to ensure that any dirs we create have writeable 01395 * permissions during the time we are putting files within 01396 * them. This is then fixed after the transfer is done. */ 01397 #ifdef HAVE_CHMOD 01398 if (!am_root && S_ISDIR(file->mode) && !(file->mode & S_IWUSR) 01399 && dir_tweaking) { 01400 mode_t mode = file->mode | S_IWUSR; /* user write */ 01401 char *fname = local_name ? local_name : fbuf; 01402 if (do_chmod(fname, mode) < 0) { 01403 rsyserr(FERROR, errno, 01404 "failed to modify permissions on %s", 01405 full_fname(fname)); 01406 } 01407 need_retouch_dir_perms = 1; 01408 } 01409 #endif 01410 01411 if (preserve_hard_links) 01412 check_for_finished_hlinks(itemizing, code); 01413 01414 if (allowed_lull && !(i % lull_mod)) 01415 maybe_send_keepalive(); 01416 else if (!(i % 200)) 01417 maybe_flush_socket(); 01418 } 01419 recv_generator(NULL, NULL, 0, 0, 0, code, -1); 01420 if (delete_during) 01421 delete_in_dir(NULL, NULL, NULL, NULL); 01422 01423 phase++; 01424 csum_length = SUM_LENGTH; 01425 max_size = min_size = ignore_existing = ignore_non_existing = 0; 01426 update_only = always_checksum = size_only = 0; 01427 ignore_times = 1; 01428 if (append_mode) /* resend w/o append mode */ 01429 append_mode = -1; /* ... but only longer files */ 01430 make_backups = 0; /* avoid a duplicate backup for inplace processing */ 01431 01432 if (verbose > 2) 01433 rprintf(FINFO,"generate_files phase=%d\n",phase); 01434 01435 write_int(f_out, -1); 01436 01437 /* files can cycle through the system more than once 01438 * to catch initial checksum errors */ 01439 while ((i = get_redo_num(itemizing, code)) != -1) { 01440 struct file_struct *file = flist->files[i]; 01441 if (local_name) 01442 strlcpy(fbuf, local_name, sizeof fbuf); 01443 else 01444 f_name(file, fbuf); 01445 recv_generator(fbuf, file, i, itemizing, maybe_ATTRS_REPORT, 01446 code, f_out); 01447 } 01448 01449 phase++; 01450 ignore_non_existing = save_ignore_non_existing; 01451 ignore_existing = save_ignore_existing; 01452 make_backups = save_make_backups; 01453 01454 if (verbose > 2) 01455 rprintf(FINFO,"generate_files phase=%d\n",phase); 01456 01457 write_int(f_out, -1); 01458 /* Reduce round-trip lag-time for a useless delay-updates phase. */ 01459 if (protocol_version >= 29 && !delay_updates) 01460 write_int(f_out, -1); 01461 01462 /* Read MSG_DONE for the redo phase (and any prior messages). */ 01463 get_redo_num(itemizing, code); 01464 01465 if (protocol_version >= 29) { 01466 phase++; 01467 if (verbose > 2) 01468 rprintf(FINFO, "generate_files phase=%d\n", phase); 01469 if (delay_updates) 01470 write_int(f_out, -1); 01471 /* Read MSG_DONE for delay-updates phase & prior messages. */ 01472 get_redo_num(itemizing, code); 01473 } 01474 01475 do_progress = save_do_progress; 01476 if (delete_after && !local_name && flist->count > 0) 01477 do_delete_pass(flist); 01478 01479 if ((need_retouch_dir_perms || need_retouch_dir_times) && dir_tweaking) { 01480 int j = 0; 01481 /* Now we need to fix any directory permissions that were 01482 * modified during the transfer and/or re-set any tweaked 01483 * modified-time values. */ 01484 for (i = 0; i < flist->count; i++) { 01485 struct file_struct *file = flist->files[i]; 01486 01487 if (!file->basename || !S_ISDIR(file->mode)) 01488 continue; 01489 if (!need_retouch_dir_times && file->mode & S_IWUSR) 01490 continue; 01491 recv_generator(f_name(file, NULL), file, i, itemizing, 01492 maybe_ATTRS_REPORT, code, -1); 01493 if (allowed_lull && !(++j % lull_mod)) 01494 maybe_send_keepalive(); 01495 else if (!(j % 200)) 01496 maybe_flush_socket(); 01497 } 01498 } 01499 recv_generator(NULL, NULL, 0, 0, 0, code, -1); 01500 01501 if (max_delete > 0 && deletion_count > max_delete) { 01502 rprintf(FINFO, 01503 "Deletions stopped due to --max-delete limit (%d skipped)\n", 01504 deletion_count - max_delete); 01505 io_error |= IOERR_DEL_LIMIT; 01506 } 01507 01508 if (verbose > 2) 01509 rprintf(FINFO,"generate_files finished\n"); 01510 }
int log_format_has_i |
clientserver.c の 58 行で定義されています。
int do_progress |
int relative_paths |
int implied_dirs |
int keep_dirlinks |
int preserve_links |
int preserve_devices |
int preserve_perms |
int preserve_uid |
int preserve_gid |
int preserve_times |
int omit_dir_times |
int delete_mode |
int delete_before |
int delete_after |
int module_id |
clientserver.c の 60 行で定義されています。
int ignore_errors |
int delay_updates |
int update_only |
int ignore_existing |
int append_mode |
int make_backups |
int csum_length |
checksum.c の 22 行で定義されています。
int ignore_times |
int size_only |
int allowed_lull |
int sock_f_out |
int ignore_timeout |
int protocol_version |
int fuzzy_basis |
int always_checksum |
int checksum_len |
char* partial_dir |
char* basis_dir[] |
int compare_dest |
int copy_dest |
int link_dest |
int whole_file |
If 1, send the whole file as literal data rather than trying to create an incremental diff.
If -1, then look at whether we're local or remote and go by that.
参照元 do_cmd()・generate_files()・recv_generator()・server_options().
int read_batch |
int safe_symlinks |
long block_size |
int max_delete |
int force_delete |
int one_file_system |
mode_t orig_umask |
dev_t filesystem_dev |
char* backup_dir |
char* backup_suffix |
struct file_list* the_file_list |
int deletion_count = 0 [static] |
int phase = 0 [static] |
int dflt_perms [static] |