version 1.1.1.3, 2016/11/01 09:54:32
|
version 1.1.1.4, 2021/03/17 00:32:36
|
Line 4
|
Line 4
|
* Copyright (C) 1996-2000 Andrew Tridgell |
* Copyright (C) 1996-2000 Andrew Tridgell |
* Copyright (C) 1996 Paul Mackerras |
* Copyright (C) 1996 Paul Mackerras |
* Copyright (C) 2002 Martin Pool <mbp@samba.org> |
* Copyright (C) 2002 Martin Pool <mbp@samba.org> |
* Copyright (C) 2003-2015 Wayne Davison | * Copyright (C) 2003-2020 Wayne Davison |
* |
* |
* This program is free software; you can redistribute it and/or modify |
* This program is free software; you can redistribute it and/or modify |
* it under the terms of the GNU General Public License as published by |
* it under the terms of the GNU General Public License as published by |
Line 37 extern int implied_dirs;
|
Line 37 extern int implied_dirs;
|
extern int keep_dirlinks; |
extern int keep_dirlinks; |
extern int preserve_acls; |
extern int preserve_acls; |
extern int preserve_xattrs; |
extern int preserve_xattrs; |
|
extern int preserve_hfs_compression; |
extern int preserve_links; |
extern int preserve_links; |
extern int preserve_devices; |
extern int preserve_devices; |
|
extern int copy_devices; |
|
extern int write_devices; |
extern int preserve_specials; |
extern int preserve_specials; |
extern int preserve_hard_links; |
extern int preserve_hard_links; |
extern int preserve_executability; |
extern int preserve_executability; |
|
extern int preserve_fileflags; |
extern int preserve_perms; |
extern int preserve_perms; |
extern int preserve_times; |
extern int preserve_times; |
|
extern int force_change; |
extern int delete_mode; |
extern int delete_mode; |
extern int delete_before; |
extern int delete_before; |
extern int delete_during; |
extern int delete_during; |
Line 51 extern int delete_after;
|
Line 56 extern int delete_after;
|
extern int missing_args; |
extern int missing_args; |
extern int msgdone_cnt; |
extern int msgdone_cnt; |
extern int ignore_errors; |
extern int ignore_errors; |
|
extern int checksum_files; |
extern int remove_source_files; |
extern int remove_source_files; |
extern int delay_updates; |
extern int delay_updates; |
extern int update_only; |
extern int update_only; |
|
extern int downdate_only; |
extern int human_readable; |
extern int human_readable; |
extern int ignore_existing; |
extern int ignore_existing; |
extern int ignore_non_existing; |
extern int ignore_non_existing; |
extern int want_xattr_optim; |
extern int want_xattr_optim; |
|
extern int modify_window; |
extern int inplace; |
extern int inplace; |
|
extern int use_db; |
extern int append_mode; |
extern int append_mode; |
extern int make_backups; |
extern int make_backups; |
extern int csum_length; |
extern int csum_length; |
extern int ignore_times; |
extern int ignore_times; |
|
extern int date_only; |
extern int size_only; |
extern int size_only; |
extern OFF_T max_size; |
extern OFF_T max_size; |
extern OFF_T min_size; |
extern OFF_T min_size; |
Line 74 extern int protocol_version;
|
Line 84 extern int protocol_version;
|
extern int file_total; |
extern int file_total; |
extern int fuzzy_basis; |
extern int fuzzy_basis; |
extern int always_checksum; |
extern int always_checksum; |
extern int checksum_len; | extern int flist_csum_len; |
extern char *partial_dir; |
extern char *partial_dir; |
extern int compare_dest; | extern int alt_dest_type; |
extern int copy_dest; | extern int detect_renamed; |
extern int link_dest; | |
extern int whole_file; |
extern int whole_file; |
extern int list_only; |
extern int list_only; |
extern int read_batch; |
extern int read_batch; |
extern int write_batch; |
extern int write_batch; |
extern int safe_symlinks; |
extern int safe_symlinks; |
extern long block_size; /* "long" because popt can't set an int32. */ | extern int32 block_size; |
extern int unsort_ndx; |
extern int unsort_ndx; |
extern int max_delete; |
extern int max_delete; |
extern int force_delete; |
extern int force_delete; |
Line 97 extern char *tmpdir;
|
Line 106 extern char *tmpdir;
|
extern char *basis_dir[MAX_BASIS_DIRS+1]; |
extern char *basis_dir[MAX_BASIS_DIRS+1]; |
extern struct file_list *cur_flist, *first_flist, *dir_flist; |
extern struct file_list *cur_flist, *first_flist, *dir_flist; |
extern filter_rule_list filter_list, daemon_filter_list; |
extern filter_rule_list filter_list, daemon_filter_list; |
|
extern struct file_list the_fattr_list; |
|
|
int maybe_ATTRS_REPORT = 0; |
int maybe_ATTRS_REPORT = 0; |
|
int maybe_ATTRS_ACCURATE_TIME = 0; |
|
|
static dev_t dev_zero; |
static dev_t dev_zero; |
|
static int unexplored_dirs = 1; |
static int deldelay_size = 0, deldelay_cnt = 0; |
static int deldelay_size = 0, deldelay_cnt = 0; |
static char *deldelay_buf = NULL; |
static char *deldelay_buf = NULL; |
static int deldelay_fd = -1; |
static int deldelay_fd = -1; |
Line 109 static int dir_tweaking;
|
Line 121 static int dir_tweaking;
|
static int symlink_timeset_failed_flags; |
static int symlink_timeset_failed_flags; |
static int need_retouch_dir_times; |
static int need_retouch_dir_times; |
static int need_retouch_dir_perms; |
static int need_retouch_dir_perms; |
|
static int started_whole_dir, upcoming_whole_dir; |
static const char *solo_file = NULL; |
static const char *solo_file = NULL; |
|
|
enum nonregtype { |
enum nonregtype { |
TYPE_DIR, TYPE_SPECIAL, TYPE_DEVICE, TYPE_SYMLINK | TYPE_DIR, TYPE_SPECIAL, TYPE_DEVICE, TYPE_SYMLINK |
}; |
}; |
|
|
/* Forward declarations. */ |
/* Forward declarations. */ |
Line 170 static int remember_delete(struct file_struct *file, c
|
Line 183 static int remember_delete(struct file_struct *file, c
|
deldelay_buf[deldelay_cnt++] = '!'; |
deldelay_buf[deldelay_cnt++] = '!'; |
|
|
while (1) { |
while (1) { |
len = snprintf(deldelay_buf + deldelay_cnt, | len = snprintf(deldelay_buf + deldelay_cnt, deldelay_size - deldelay_cnt, |
deldelay_size - deldelay_cnt, | "%x %s%c", (int)file->mode, fname, '\0'); |
"%x %s%c", | |
(int)file->mode, fname, '\0'); | |
if ((deldelay_cnt += len) <= deldelay_size) |
if ((deldelay_cnt += len) <= deldelay_size) |
break; |
break; |
deldelay_cnt -= len; |
deldelay_cnt -= len; |
Line 210 static int read_delay_line(char *buf, int *flags_p)
|
Line 221 static int read_delay_line(char *buf, int *flags_p)
|
deldelay_size - deldelay_cnt); |
deldelay_size - deldelay_cnt); |
if (len == 0) { |
if (len == 0) { |
if (deldelay_cnt) { |
if (deldelay_cnt) { |
rprintf(FERROR, | rprintf(FERROR, "ERROR: unexpected EOF in delete-delay file.\n"); |
"ERROR: unexpected EOF in delete-delay file.\n"); | |
} |
} |
return -1; |
return -1; |
} |
} |
Line 271 static void do_delayed_deletions(char *delbuf)
|
Line 281 static void do_delayed_deletions(char *delbuf)
|
* all the --delete-WHEN options. Note that the fbuf pointer must point to a |
* all the --delete-WHEN options. Note that the fbuf pointer must point to a |
* MAXPATHLEN buffer with the name of the directory in it (the functions we |
* MAXPATHLEN buffer with the name of the directory in it (the functions we |
* call will append names onto the end, but the old dir value will be restored |
* call will append names onto the end, but the old dir value will be restored |
* on exit). */ | * on exit). |
static void delete_in_dir(char *fbuf, struct file_struct *file, dev_t *fs_dev) | * |
| * Note: --detect-rename may use this routine with DEL_NO_DELETIONS set! |
| */ |
| static void delete_in_dir(char *fbuf, struct file_struct *file, dev_t *fs_dev, |
| int del_flags) |
{ |
{ |
static int already_warned = 0; |
static int already_warned = 0; |
|
static struct hashtable *dev_tbl; |
struct file_list *dirlist; |
struct file_list *dirlist; |
char delbuf[MAXPATHLEN]; | char *p, delbuf[MAXPATHLEN]; |
int dlen, i; | unsigned remainder; |
| int dlen, i, restore_dot = 0; |
|
|
if (!fbuf) { |
if (!fbuf) { |
change_local_filter_dir(NULL, 0, 0); |
change_local_filter_dir(NULL, 0, 0); |
Line 291 static void delete_in_dir(char *fbuf, struct file_stru
|
Line 307 static void delete_in_dir(char *fbuf, struct file_stru
|
maybe_send_keepalive(time(NULL), MSK_ALLOW_FLUSH); |
maybe_send_keepalive(time(NULL), MSK_ALLOW_FLUSH); |
|
|
if (io_error & IOERR_GENERAL && !ignore_errors) { |
if (io_error & IOERR_GENERAL && !ignore_errors) { |
if (already_warned) | if (!already_warned) { |
| rprintf(FINFO, |
| "IO error encountered -- skipping file deletion\n"); |
| already_warned = 1; |
| } |
| if (!detect_renamed) |
return; |
return; |
rprintf(FINFO, | del_flags |= DEL_NO_DELETIONS; |
"IO error encountered -- skipping file deletion\n"); | |
already_warned = 1; | |
return; | |
} |
} |
|
|
dlen = strlen(fbuf); |
dlen = strlen(fbuf); |
change_local_filter_dir(fbuf, dlen, F_DEPTH(file)); |
change_local_filter_dir(fbuf, dlen, F_DEPTH(file)); |
|
|
|
if (detect_renamed) |
|
unexplored_dirs--; |
|
|
if (one_file_system) { |
if (one_file_system) { |
if (file->flags & FLAG_TOP_DIR) | if (!dev_tbl) |
| dev_tbl = hashtable_create(16, HT_KEY64); |
| if (file->flags & FLAG_TOP_DIR) { |
| hashtable_find(dev_tbl, *fs_dev+1, ""); |
filesystem_dev = *fs_dev; |
filesystem_dev = *fs_dev; |
else if (filesystem_dev != *fs_dev) | } else if (filesystem_dev != *fs_dev) { |
return; | if (!hashtable_find(dev_tbl, *fs_dev+1, NULL)) |
| return; |
| filesystem_dev = *fs_dev; /* it's a prior top-dir dev */ |
| } |
} |
} |
|
|
dirlist = get_dirlist(fbuf, dlen, 0); |
dirlist = get_dirlist(fbuf, dlen, 0); |
|
|
|
p = fbuf + dlen; |
|
if (dlen == 1 && *fbuf == '.') { |
|
restore_dot = 1; |
|
p = fbuf; |
|
} else if (dlen != 1 || *fbuf != '/') |
|
*p++ = '/'; |
|
remainder = MAXPATHLEN - (p - fbuf); |
|
|
/* If an item in dirlist is not found in flist, delete it |
/* If an item in dirlist is not found in flist, delete it |
* from the filesystem. */ |
* from the filesystem. */ |
for (i = dirlist->used; i--; ) { |
for (i = dirlist->used; i--; ) { |
Line 323 static void delete_in_dir(char *fbuf, struct file_stru
|
Line 358 static void delete_in_dir(char *fbuf, struct file_stru
|
f_name(fp, NULL)); |
f_name(fp, NULL)); |
continue; |
continue; |
} |
} |
|
if (detect_renamed && S_ISREG(fp->mode)) { |
|
strlcpy(p, fp->basename, remainder); |
|
look_for_rename(fp, fbuf); |
|
} |
/* Here we want to match regardless of file type. Replacement |
/* Here we want to match regardless of file type. Replacement |
* of a file with one of another type is handled separately by |
* of a file with one of another type is handled separately by |
* a delete_item call with a DEL_MAKE_ROOM flag. */ |
* a delete_item call with a DEL_MAKE_ROOM flag. */ |
Line 331 static void delete_in_dir(char *fbuf, struct file_stru
|
Line 370 static void delete_in_dir(char *fbuf, struct file_stru
|
if (!(fp->mode & S_IWUSR) && !am_root && fp->flags & FLAG_OWNED_BY_US) |
if (!(fp->mode & S_IWUSR) && !am_root && fp->flags & FLAG_OWNED_BY_US) |
flags |= DEL_NO_UID_WRITE; |
flags |= DEL_NO_UID_WRITE; |
f_name(fp, delbuf); |
f_name(fp, delbuf); |
if (delete_during == 2) { | if (delete_during == 2 && !(del_flags & DEL_NO_DELETIONS)) { |
if (!remember_delete(fp, delbuf, flags)) | if (!remember_delete(fp, delbuf, del_flags | flags)) |
break; |
break; |
} else |
} else |
delete_item(delbuf, fp->mode, flags); | delete_item(delbuf, fp->mode, del_flags | flags); |
} | } else if (detect_renamed && S_ISDIR(fp->mode)) |
| unexplored_dirs++; |
} |
} |
|
|
|
if (restore_dot) |
|
fbuf[0] = '.'; |
|
fbuf[dlen] = '\0'; |
|
|
flist_free(dirlist); |
flist_free(dirlist); |
} |
} |
|
|
Line 374 static void do_delete_pass(void)
|
Line 418 static void do_delete_pass(void)
|
|| !S_ISDIR(st.st_mode)) |
|| !S_ISDIR(st.st_mode)) |
continue; |
continue; |
|
|
delete_in_dir(fbuf, file, &st.st_dev); | delete_in_dir(fbuf, file, &st.st_dev, 0); |
} |
} |
delete_in_dir(NULL, NULL, &dev_zero); | delete_in_dir(NULL, NULL, &dev_zero, 0); |
|
|
if (INFO_GTE(FLIST, 2) && !am_server) |
if (INFO_GTE(FLIST, 2) && !am_server) |
rprintf(FINFO, " \r"); |
rprintf(FINFO, " \r"); |
} |
} |
|
|
static inline int time_differs(struct file_struct *file, stat_x *sxp) | /* Search for a regular file that matches either (1) the size & modified |
| * time (plus the basename, if possible) or (2) the size & checksum. If |
| * we find an exact match down to the dirname, return -1 because we found |
| * an up-to-date file in the transfer, not a renamed file. */ |
| static int fattr_find(struct file_struct *f, char *fname) |
{ |
{ |
return cmp_time(sxp->st.st_mtime, file->modtime); | int low = the_fattr_list.low, high = the_fattr_list.high; |
| int mid, ok_match = -1, good_match = -1; |
| struct file_struct *fmid; |
| int diff; |
| |
| while (low <= high) { |
| mid = (low + high) / 2; |
| fmid = the_fattr_list.files[mid]; |
| if (F_LENGTH(fmid) != F_LENGTH(f)) { |
| if (F_LENGTH(fmid) < F_LENGTH(f)) |
| low = mid + 1; |
| else |
| high = mid - 1; |
| continue; |
| } |
| if (always_checksum) { |
| /* We use the FLAG_FILE_SENT flag to indicate when we |
| * have computed the checksum for an entry. */ |
| if (!(f->flags & FLAG_FILE_SENT)) { |
| STRUCT_STAT st; |
| if (fmid->modtime == f->modtime |
| && f_name_cmp(fmid, f) == 0) |
| return -1; /* assume we can't help */ |
| st.st_size = F_LENGTH(f); |
| st.st_mtime = f->modtime; |
| file_checksum(fname, &st, F_SUM(f)); |
| f->flags |= FLAG_FILE_SENT; |
| } |
| diff = u_memcmp(F_SUM(fmid), F_SUM(f), flist_csum_len); |
| if (diff) { |
| if (diff < 0) |
| low = mid + 1; |
| else |
| high = mid - 1; |
| continue; |
| } |
| } else { |
| if (fmid->modtime != f->modtime) { |
| if (fmid->modtime < f->modtime) |
| low = mid + 1; |
| else |
| high = mid - 1; |
| continue; |
| } |
| } |
| ok_match = mid; |
| diff = u_strcmp(fmid->basename, f->basename); |
| if (diff == 0) { |
| good_match = mid; |
| if (fmid->dirname == f->dirname) |
| return -1; /* file is up-to-date */ |
| if (!fmid->dirname) { |
| low = mid + 1; |
| continue; |
| } |
| if (!f->dirname) { |
| high = mid - 1; |
| continue; |
| } |
| diff = u_strcmp(fmid->dirname, f->dirname); |
| if (diff == 0) |
| return -1; /* file is up-to-date */ |
| } |
| if (diff < 0) |
| low = mid + 1; |
| else |
| high = mid - 1; |
| } |
| |
| return good_match >= 0 ? good_match : ok_match; |
} |
} |
|
|
|
void look_for_rename(struct file_struct *file, char *fname) |
|
{ |
|
struct file_struct *fp; |
|
char *partialptr, *fn; |
|
STRUCT_STAT st; |
|
int ndx; |
|
|
|
if (!partial_dir || (ndx = fattr_find(file, fname)) < 0) |
|
return; |
|
|
|
fp = the_fattr_list.files[ndx]; |
|
fn = f_name(fp, NULL); |
|
/* We don't provide an alternate-basis file if there is a basis file. */ |
|
if (link_stat(fn, &st, 0) == 0) |
|
return; |
|
|
|
if (!dry_run) { |
|
if ((partialptr = partial_dir_fname(fn)) == NULL |
|
|| !handle_partial_dir(partialptr, PDIR_CREATE)) |
|
return; |
|
/* We only use the file if we can hard-link it into our tmp dir. */ |
|
if (link(fname, partialptr) != 0) { |
|
if (errno != EEXIST) |
|
handle_partial_dir(partialptr, PDIR_DELETE); |
|
return; |
|
} |
|
} |
|
|
|
/* I think this falls into the -vv category with "%s is uptodate", etc. */ |
|
if (INFO_GTE(MISC, 2)) |
|
rprintf(FINFO, "found renamed: %s => %s\n", fname, fn); |
|
} |
|
|
|
static inline int mtime_differs(STRUCT_STAT *stp, struct file_struct *file) |
|
{ |
|
#ifdef ST_MTIME_NSEC |
|
return !same_time(stp->st_mtime, stp->ST_MTIME_NSEC, file->modtime, F_MOD_NSEC_or_0(file)); |
|
#else |
|
return !same_time(stp->st_mtime, 0, file->modtime, 0); |
|
#endif |
|
} |
|
|
|
static inline int any_time_differs(stat_x *sxp, struct file_struct *file, UNUSED(const char *fname)) |
|
{ |
|
int differs = mtime_differs(&sxp->st, file); |
|
#ifdef SUPPORT_CRTIMES |
|
if (!differs && crtimes_ndx) { |
|
if (sxp->crtime == 0) |
|
sxp->crtime = get_create_time(fname); |
|
differs = !same_time(sxp->crtime, 0, F_CRTIME(file), 0); |
|
} |
|
#endif |
|
return differs; |
|
} |
|
|
static inline int perms_differ(struct file_struct *file, stat_x *sxp) |
static inline int perms_differ(struct file_struct *file, stat_x *sxp) |
{ |
{ |
if (preserve_perms) |
if (preserve_perms) |
Line 441 int unchanged_attrs(const char *fname, struct file_str
|
Line 613 int unchanged_attrs(const char *fname, struct file_str
|
{ |
{ |
if (S_ISLNK(file->mode)) { |
if (S_ISLNK(file->mode)) { |
#ifdef CAN_SET_SYMLINK_TIMES |
#ifdef CAN_SET_SYMLINK_TIMES |
if (preserve_times & PRESERVE_LINK_TIMES && time_differs(file, sxp)) | if (preserve_times & PRESERVE_LINK_TIMES && any_time_differs(sxp, file, fname)) |
return 0; |
return 0; |
#endif |
#endif |
#ifdef CAN_CHMOD_SYMLINK |
#ifdef CAN_CHMOD_SYMLINK |
Line 461 int unchanged_attrs(const char *fname, struct file_str
|
Line 633 int unchanged_attrs(const char *fname, struct file_str
|
return 0; |
return 0; |
#endif |
#endif |
} else { |
} else { |
if (preserve_times && time_differs(file, sxp)) | if (preserve_times && any_time_differs(sxp, file, fname)) |
return 0; |
return 0; |
if (perms_differ(file, sxp)) |
if (perms_differ(file, sxp)) |
return 0; |
return 0; |
|
#ifdef SUPPORT_FILEFLAGS |
|
if (preserve_fileflags && sxp->st.st_flags != F_FFLAGS(file)) |
|
return 0; |
|
#endif |
if (ownership_differs(file, sxp)) |
if (ownership_differs(file, sxp)) |
return 0; |
return 0; |
#ifdef SUPPORT_ACLS |
#ifdef SUPPORT_ACLS |
Line 485 void itemize(const char *fnamecmp, struct file_struct
|
Line 661 void itemize(const char *fnamecmp, struct file_struct
|
const char *xname) |
const char *xname) |
{ |
{ |
if (statret >= 0) { /* A from-dest-dir statret can == 1! */ |
if (statret >= 0) { /* A from-dest-dir statret can == 1! */ |
|
int omit_changes = omit_dir_changes && S_ISDIR(sxp->st.st_mode); |
int keep_time = !preserve_times ? 0 |
int keep_time = !preserve_times ? 0 |
: S_ISDIR(file->mode) ? preserve_times & PRESERVE_DIR_TIMES |
: S_ISDIR(file->mode) ? preserve_times & PRESERVE_DIR_TIMES |
: S_ISLNK(file->mode) ? preserve_times & PRESERVE_LINK_TIMES |
: S_ISLNK(file->mode) ? preserve_times & PRESERVE_LINK_TIMES |
Line 496 void itemize(const char *fnamecmp, struct file_struct
|
Line 673 void itemize(const char *fnamecmp, struct file_struct
|
if (iflags & ITEM_LOCAL_CHANGE) |
if (iflags & ITEM_LOCAL_CHANGE) |
iflags |= symlink_timeset_failed_flags; |
iflags |= symlink_timeset_failed_flags; |
} else if (keep_time |
} else if (keep_time |
? cmp_time(file->modtime, sxp->st.st_mtime) != 0 | ? mtime_differs(&sxp->st, file) |
: iflags & (ITEM_TRANSFER|ITEM_LOCAL_CHANGE) && !(iflags & ITEM_MATCHED) |
: iflags & (ITEM_TRANSFER|ITEM_LOCAL_CHANGE) && !(iflags & ITEM_MATCHED) |
&& (!(iflags & ITEM_XNAME_FOLLOWS) || *xname)) |
&& (!(iflags & ITEM_XNAME_FOLLOWS) || *xname)) |
iflags |= ITEM_REPORT_TIME; |
iflags |= ITEM_REPORT_TIME; |
|
if (atimes_ndx && !S_ISDIR(file->mode) && !S_ISLNK(file->mode) |
|
&& !same_time(F_ATIME(file), 0, sxp->st.st_atime, 0)) |
|
iflags |= ITEM_REPORT_ATIME; |
|
#ifdef SUPPORT_CRTIMES |
|
if (crtimes_ndx) { |
|
if (sxp->crtime == 0) |
|
sxp->crtime = get_create_time(fnamecmp); |
|
if (!same_time(sxp->crtime, 0, F_CRTIME(file), 0)) |
|
iflags |= ITEM_REPORT_CRTIME; |
|
} |
|
#endif |
#if !defined HAVE_LCHMOD && !defined HAVE_SETATTRLIST |
#if !defined HAVE_LCHMOD && !defined HAVE_SETATTRLIST |
if (S_ISLNK(file->mode)) { |
if (S_ISLNK(file->mode)) { |
; |
; |
Line 511 void itemize(const char *fnamecmp, struct file_struct
|
Line 699 void itemize(const char *fnamecmp, struct file_struct
|
} else if (preserve_executability |
} else if (preserve_executability |
&& ((sxp->st.st_mode & 0111 ? 1 : 0) ^ (file->mode & 0111 ? 1 : 0))) |
&& ((sxp->st.st_mode & 0111 ? 1 : 0) ^ (file->mode & 0111 ? 1 : 0))) |
iflags |= ITEM_REPORT_PERMS; |
iflags |= ITEM_REPORT_PERMS; |
if (uid_ndx && am_root && (uid_t)F_OWNER(file) != sxp->st.st_uid) | if (uid_ndx && am_root && !omit_changes && (uid_t)F_OWNER(file) != sxp->st.st_uid) |
iflags |= ITEM_REPORT_OWNER; |
iflags |= ITEM_REPORT_OWNER; |
if (gid_ndx && !(file->flags & FLAG_SKIP_GROUP) | if (gid_ndx && !omit_changes && !(file->flags & FLAG_SKIP_GROUP) && sxp->st.st_gid != (gid_t)F_GROUP(file)) |
&& sxp->st.st_gid != (gid_t)F_GROUP(file)) | |
iflags |= ITEM_REPORT_GROUP; |
iflags |= ITEM_REPORT_GROUP; |
|
#ifdef SUPPORT_FILEFLAGS |
|
if (preserve_fileflags && !S_ISLNK(file->mode) |
|
&& sxp->st.st_flags != F_FFLAGS(file)) |
|
iflags |= ITEM_REPORT_FFLAGS; |
|
#endif |
#ifdef SUPPORT_ACLS |
#ifdef SUPPORT_ACLS |
if (preserve_acls && !S_ISLNK(file->mode)) { |
if (preserve_acls && !S_ISLNK(file->mode)) { |
if (!ACL_READY(*sxp)) |
if (!ACL_READY(*sxp)) |
Line 569 void itemize(const char *fnamecmp, struct file_struct
|
Line 761 void itemize(const char *fnamecmp, struct file_struct
|
|
|
|
|
/* Perform our quick-check heuristic for determining if a file is unchanged. */ |
/* Perform our quick-check heuristic for determining if a file is unchanged. */ |
int unchanged_file(char *fn, struct file_struct *file, STRUCT_STAT *st) | int unchanged_file(char *fn, struct file_struct *file, STRUCT_STAT *st, int slot) |
{ |
{ |
|
if (date_only) |
|
return !mtime_differs(st, file); |
|
|
if (st->st_size != F_LENGTH(file)) |
if (st->st_size != F_LENGTH(file)) |
return 0; |
return 0; |
|
|
Line 578 int unchanged_file(char *fn, struct file_struct *file,
|
Line 773 int unchanged_file(char *fn, struct file_struct *file,
|
of the file time to determine whether to sync */ |
of the file time to determine whether to sync */ |
if (always_checksum > 0 && S_ISREG(st->st_mode)) { |
if (always_checksum > 0 && S_ISREG(st->st_mode)) { |
char sum[MAX_DIGEST_LEN]; |
char sum[MAX_DIGEST_LEN]; |
file_checksum(fn, st, sum); | if (checksum_files && slot >= 0) |
return memcmp(sum, F_SUM(file), checksum_len) == 0; | get_cached_checksum(slot, fn, file, -1, st, sum); |
| else |
| file_checksum(fn, st, sum); |
| return memcmp(sum, F_SUM(file), flist_csum_len) == 0; |
} |
} |
|
|
if (size_only > 0) |
if (size_only > 0) |
Line 588 int unchanged_file(char *fn, struct file_struct *file,
|
Line 786 int unchanged_file(char *fn, struct file_struct *file,
|
if (ignore_times) |
if (ignore_times) |
return 0; |
return 0; |
|
|
return cmp_time(st->st_mtime, file->modtime) == 0; | return !mtime_differs(st, file); |
} |
} |
|
|
|
|
Line 633 static void sum_sizes_sqroot(struct sum_struct *sum, i
|
Line 831 static void sum_sizes_sqroot(struct sum_struct *sum, i
|
if (c < 0 || c >= max_blength) |
if (c < 0 || c >= max_blength) |
blength = max_blength; |
blength = max_blength; |
else { |
else { |
blength = 0; | blength = 0; |
do { | do { |
blength |= c; | blength |= c; |
if (len < (int64)blength * blength) | if (len < (int64)blength * blength) |
blength &= ~c; | blength &= ~c; |
c >>= 1; | c >>= 1; |
} while (c >= 8); /* round to multiple of 8 */ | } while (c >= 8); /* round to multiple of 8 */ |
blength = MAX(blength, BLOCK_SIZE); | blength = MAX(blength, BLOCK_SIZE); |
} |
} |
} |
} |
|
|
Line 697 static int generate_and_send_sums(int fd, OFF_T len, i
|
Line 895 static int generate_and_send_sums(int fd, OFF_T len, i
|
if (append_mode > 0 && f_copy < 0) |
if (append_mode > 0 && f_copy < 0) |
return 0; |
return 0; |
|
|
if (len > 0) | if (len > 0) { |
mapbuf = map_file(fd, len, MAX_MAP_SIZE, sum.blength); |
mapbuf = map_file(fd, len, MAX_MAP_SIZE, sum.blength); |
else | checksum2_enable_prefetch(mapbuf, len, sum.blength); |
| } else { |
mapbuf = NULL; |
mapbuf = NULL; |
|
} |
|
|
for (i = 0; i < sum.count; i++) { |
for (i = 0; i < sum.count; i++) { |
int32 n1 = (int32)MIN(len, (OFF_T)sum.blength); |
int32 n1 = (int32)MIN(len, (OFF_T)sum.blength); |
Line 718 static int generate_and_send_sums(int fd, OFF_T len, i
|
Line 918 static int generate_and_send_sums(int fd, OFF_T len, i
|
} |
} |
|
|
sum1 = get_checksum1(map, n1); |
sum1 = get_checksum1(map, n1); |
get_checksum2(map, n1, sum2); | get_checksum2(map, n1, sum2, offset - n1); |
|
|
if (DEBUG_GTE(DELTASUM, 3)) { |
if (DEBUG_GTE(DELTASUM, 3)) { |
rprintf(FINFO, |
rprintf(FINFO, |
Line 730 static int generate_and_send_sums(int fd, OFF_T len, i
|
Line 930 static int generate_and_send_sums(int fd, OFF_T len, i
|
write_buf(f_out, sum2, sum.s2length); |
write_buf(f_out, sum2, sum.s2length); |
} |
} |
|
|
if (mapbuf) | if (mapbuf) { |
unmap_file(mapbuf); |
unmap_file(mapbuf); |
|
checksum2_disable_prefetch(); |
|
} |
|
|
return 0; |
return 0; |
} |
} |
Line 765 static struct file_struct *find_fuzzy(struct file_stru
|
Line 967 static struct file_struct *find_fuzzy(struct file_stru
|
if (!S_ISREG(fp->mode) || !F_LENGTH(fp) || fp->flags & FLAG_FILE_SENT) |
if (!S_ISREG(fp->mode) || !F_LENGTH(fp) || fp->flags & FLAG_FILE_SENT) |
continue; |
continue; |
|
|
if (F_LENGTH(fp) == F_LENGTH(file) && cmp_time(fp->modtime, file->modtime) == 0) { | if (F_LENGTH(fp) == F_LENGTH(file) && same_time(fp->modtime, 0, file->modtime, 0)) { |
if (DEBUG_GTE(FUZZY, 2)) |
if (DEBUG_GTE(FUZZY, 2)) |
rprintf(FINFO, "fuzzy size/modtime match for %s\n", f_name(fp, NULL)); |
rprintf(FINFO, "fuzzy size/modtime match for %s\n", f_name(fp, NULL)); |
*fnamecmp_type_ptr = FNAMECMP_FUZZY + i; |
*fnamecmp_type_ptr = FNAMECMP_FUZZY + i; |
Line 871 static int try_dests_reg(struct file_struct *file, cha
|
Line 1073 static int try_dests_reg(struct file_struct *file, cha
|
pathjoin(cmpbuf, MAXPATHLEN, basis_dir[j], fname); |
pathjoin(cmpbuf, MAXPATHLEN, basis_dir[j], fname); |
if (link_stat(cmpbuf, &sxp->st, 0) < 0 || !S_ISREG(sxp->st.st_mode)) |
if (link_stat(cmpbuf, &sxp->st, 0) < 0 || !S_ISREG(sxp->st.st_mode)) |
continue; |
continue; |
switch (match_level) { | if (match_level == 0) { |
case 0: | |
best_match = j; |
best_match = j; |
match_level = 1; |
match_level = 1; |
/* FALL THROUGH */ | } |
case 1: | if (!unchanged_file(cmpbuf, file, &sxp->st, j+1)) |
if (!unchanged_file(cmpbuf, file, &sxp->st)) | continue; |
continue; | if (match_level == 1) { |
best_match = j; |
best_match = j; |
match_level = 2; |
match_level = 2; |
/* FALL THROUGH */ | } |
case 2: | if (alt_dest_type == CLONE_DEST || unchanged_attrs(cmpbuf, file, sxp)) { |
if (!unchanged_attrs(cmpbuf, file, sxp)) { | |
free_stat_x(sxp); | |
continue; | |
} | |
best_match = j; |
best_match = j; |
match_level = 3; |
match_level = 3; |
break; |
break; |
} |
} |
break; | free_stat_x(sxp); |
} while (basis_dir[++j] != NULL); |
} while (basis_dir[++j] != NULL); |
|
|
if (!match_level) |
if (!match_level) |
Line 904 static int try_dests_reg(struct file_struct *file, cha
|
Line 1101 static int try_dests_reg(struct file_struct *file, cha
|
goto got_nothing_for_ya; |
goto got_nothing_for_ya; |
} |
} |
|
|
if (match_level == 3 && !copy_dest) { | if (match_level == 3 && alt_dest_type != COPY_DEST) { |
if (find_exact_for_existing) { |
if (find_exact_for_existing) { |
if (link_dest && real_st.st_dev == sxp->st.st_dev && real_st.st_ino == sxp->st.st_ino) | if (alt_dest_type == LINK_DEST && real_st.st_dev == sxp->st.st_dev && real_st.st_ino == sxp->st.st_ino) |
return -1; |
return -1; |
if (do_unlink(fname) < 0 && errno != ENOENT) |
if (do_unlink(fname) < 0 && errno != ENOENT) |
goto got_nothing_for_ya; |
goto got_nothing_for_ya; |
} |
} |
#ifdef SUPPORT_HARD_LINKS |
#ifdef SUPPORT_HARD_LINKS |
if (link_dest) { | if (alt_dest_type == LINK_DEST) { |
if (!hard_link_one(file, fname, cmpbuf, 1)) |
if (!hard_link_one(file, fname, cmpbuf, 1)) |
goto try_a_copy; |
goto try_a_copy; |
|
if (atimes_ndx) |
|
set_file_attrs(fname, file, sxp, NULL, 0); |
if (preserve_hard_links && F_IS_HLINKED(file)) |
if (preserve_hard_links && F_IS_HLINKED(file)) |
finish_hard_link(file, fname, ndx, &sxp->st, itemizing, code, j); |
finish_hard_link(file, fname, ndx, &sxp->st, itemizing, code, j); |
if (!maybe_ATTRS_REPORT && (INFO_GTE(NAME, 2) || stdout_format_has_i > 1)) { |
if (!maybe_ATTRS_REPORT && (INFO_GTE(NAME, 2) || stdout_format_has_i > 1)) { |
Line 924 static int try_dests_reg(struct file_struct *file, cha
|
Line 1123 static int try_dests_reg(struct file_struct *file, cha
|
} |
} |
} else |
} else |
#endif |
#endif |
{ | if (alt_dest_type == CLONE_DEST) { |
| if (do_clone(cmpbuf, fname, file->mode) < 0) { |
| rsyserr(FERROR_XFER, errno, "failed to clone %s to %s", cmpbuf, fname); |
| exit_cleanup(RERR_UNSUPPORTED); |
| } |
| } else { |
if (itemizing) |
if (itemizing) |
itemize(cmpbuf, file, ndx, 0, sxp, 0, 0, NULL); |
itemize(cmpbuf, file, ndx, 0, sxp, 0, 0, NULL); |
} |
} |
Line 1080 static int try_dests_non(struct file_struct *file, cha
|
Line 1284 static int try_dests_non(struct file_struct *file, cha
|
|
|
if (match_level == 3) { |
if (match_level == 3) { |
#ifdef SUPPORT_HARD_LINKS |
#ifdef SUPPORT_HARD_LINKS |
if (link_dest | if ((alt_dest_type == LINK_DEST || alt_dest_type == CLONE_DEST) |
#ifndef CAN_HARDLINK_SYMLINK |
#ifndef CAN_HARDLINK_SYMLINK |
&& !S_ISLNK(file->mode) |
&& !S_ISLNK(file->mode) |
#endif |
#endif |
Line 1101 static int try_dests_non(struct file_struct *file, cha
|
Line 1305 static int try_dests_non(struct file_struct *file, cha
|
match_level = 2; |
match_level = 2; |
if (itemizing && stdout_format_has_i |
if (itemizing && stdout_format_has_i |
&& (INFO_GTE(NAME, 2) || stdout_format_has_i > 1)) { |
&& (INFO_GTE(NAME, 2) || stdout_format_has_i > 1)) { |
int chg = compare_dest && type != TYPE_DIR ? 0 | int chg = alt_dest_type == COMPARE_DEST && type != TYPE_DIR ? 0 |
: ITEM_LOCAL_CHANGE + (match_level == 3 ? ITEM_XNAME_FOLLOWS : 0); |
: ITEM_LOCAL_CHANGE + (match_level == 3 ? ITEM_XNAME_FOLLOWS : 0); |
char *lp = match_level == 3 ? "" : NULL; |
char *lp = match_level == 3 ? "" : NULL; |
itemize(cmpbuf, file, ndx, 0, sxp, chg + ITEM_MATCHED, 0, lp); |
itemize(cmpbuf, file, ndx, 0, sxp, chg + ITEM_MATCHED, 0, lp); |
Line 1119 static int try_dests_non(struct file_struct *file, cha
|
Line 1323 static int try_dests_non(struct file_struct *file, cha
|
static void list_file_entry(struct file_struct *f) |
static void list_file_entry(struct file_struct *f) |
{ |
{ |
char permbuf[PERMSTRING_SIZE]; |
char permbuf[PERMSTRING_SIZE]; |
int64 len; | const char *mtime_str = timestring(f->modtime); |
int colwidth = human_readable ? 14 : 11; | int size_width = human_readable ? 14 : 11; |
| int mtime_width = 1 + strlen(mtime_str); |
| int atime_width = atimes_ndx ? mtime_width : 0; |
| int crtime_width = crtimes_ndx ? mtime_width : 0; |
|
|
if (!F_IS_ACTIVE(f)) { |
if (!F_IS_ACTIVE(f)) { |
/* this can happen if duplicate names were removed */ |
/* this can happen if duplicate names were removed */ |
return; |
return; |
} |
} |
|
|
permstring(permbuf, f->mode); |
|
len = F_LENGTH(f); |
|
|
|
/* TODO: indicate '+' if the entry has an ACL. */ |
/* TODO: indicate '+' if the entry has an ACL. */ |
|
|
#ifdef SUPPORT_LINKS |
|
if (preserve_links && S_ISLNK(f->mode)) { |
|
rprintf(FINFO, "%s %*s %s %s -> %s\n", |
|
permbuf, colwidth, human_num(len), |
|
timestring(f->modtime), f_name(f, NULL), |
|
F_SYMLINK(f)); |
|
} else |
|
#endif |
|
if (missing_args == 2 && f->mode == 0) { |
if (missing_args == 2 && f->mode == 0) { |
rprintf(FINFO, "%-*s %s\n", |
rprintf(FINFO, "%-*s %s\n", |
colwidth + 31, "*missing", | 10 + 1 + size_width + mtime_width + atime_width + crtime_width, "*missing", |
f_name(f, NULL)); |
f_name(f, NULL)); |
} else { |
} else { |
rprintf(FINFO, "%s %*s %s %s\n", | const char *atime_str = atimes_ndx && !S_ISDIR(f->mode) ? timestring(F_ATIME(f)) : ""; |
permbuf, colwidth, human_num(len), | const char *crtime_str = crtimes_ndx ? timestring(F_CRTIME(f)) : ""; |
timestring(f->modtime), f_name(f, NULL)); | const char *arrow, *lnk; |
| |
| permstring(permbuf, f->mode); |
| |
| #ifdef SUPPORT_LINKS |
| if (preserve_links && S_ISLNK(f->mode)) { |
| arrow = " -> "; |
| lnk = F_SYMLINK(f); |
| } else |
| #endif |
| arrow = lnk = ""; |
| |
| rprintf(FINFO, "%s %*s %s%*s%*s %s%s%s\n", |
| permbuf, size_width, human_num(F_LENGTH(f)), |
| timestring(f->modtime), atime_width, atime_str, crtime_width, crtime_str, |
| f_name(f, NULL), arrow, lnk); |
} |
} |
} |
} |
|
|
|
static struct bitbag *delayed_bits = NULL; |
static int phase = 0; |
static int phase = 0; |
static int dflt_perms; |
static int dflt_perms; |
|
|
Line 1184 static void recv_generator(char *fname, struct file_st
|
Line 1396 static void recv_generator(char *fname, struct file_st
|
* --ignore-non-existing, daemon exclude, or mkdir failure. */ |
* --ignore-non-existing, daemon exclude, or mkdir failure. */ |
static struct file_struct *skip_dir = NULL; |
static struct file_struct *skip_dir = NULL; |
static struct file_list *fuzzy_dirlist[MAX_BASIS_DIRS+1]; |
static struct file_list *fuzzy_dirlist[MAX_BASIS_DIRS+1]; |
static int need_fuzzy_dirlist = 0; | static int need_new_dirscan = 0; |
struct file_struct *fuzzy_file = NULL; |
struct file_struct *fuzzy_file = NULL; |
int fd = -1, f_copy = -1; |
int fd = -1, f_copy = -1; |
stat_x sx, real_sx; |
stat_x sx, real_sx; |
Line 1210 static void recv_generator(char *fname, struct file_st
|
Line 1422 static void recv_generator(char *fname, struct file_st
|
return; |
return; |
} |
} |
|
|
|
maybe_ATTRS_ACCURATE_TIME = always_checksum ? ATTRS_ACCURATE_TIME : 0; |
|
|
if (skip_dir) { |
if (skip_dir) { |
if (is_below(file, skip_dir)) { |
if (is_below(file, skip_dir)) { |
if (is_dir) |
if (is_dir) |
Line 1240 static void recv_generator(char *fname, struct file_st
|
Line 1454 static void recv_generator(char *fname, struct file_st
|
return; |
return; |
} |
} |
} |
} |
|
sx.crtime = 0; |
|
|
if (dry_run > 1 || (dry_missing_dir && is_below(file, dry_missing_dir))) { |
if (dry_run > 1 || (dry_missing_dir && is_below(file, dry_missing_dir))) { |
int i; |
int i; |
Line 1262 static void recv_generator(char *fname, struct file_st
|
Line 1477 static void recv_generator(char *fname, struct file_st
|
* this function was asked to process in the file list. */ |
* this function was asked to process in the file list. */ |
if (!inc_recurse |
if (!inc_recurse |
&& (*dn != '.' || dn[1]) /* Avoid an issue with --relative and the "." dir. */ |
&& (*dn != '.' || dn[1]) /* Avoid an issue with --relative and the "." dir. */ |
&& (prior_dir_file && strcmp(dn, f_name(prior_dir_file, NULL)) != 0) | && (!prior_dir_file || strcmp(dn, f_name(prior_dir_file, NULL)) != 0)) { |
&& flist_find_name(cur_flist, dn, 1) < 0) { | int ok = 0, j = flist_find_name(cur_flist, dn, -1); |
rprintf(FERROR, | if (j >= 0) { |
"ABORTING due to invalid path from sender: %s/%s\n", | struct file_struct *f = cur_flist->sorted[j]; |
dn, file->basename); | if (S_ISDIR(f->mode) || (missing_args == 2 && !file->mode && !f->mode)) |
exit_cleanup(RERR_PROTOCOL); | ok = 1; |
| } |
| /* The --delete-missing-args option can actually put invalid entries into |
| * the file list, so if that option was specified, we'll just complain about |
| * it and allow it. */ |
| if (!ok && missing_args == 2 && file->mode == 0 && j < 0) |
| rprintf(FERROR, "WARNING: parent dir is absent in the file list: %s\n", dn); |
| else if (!ok) { |
| rprintf(FERROR, "ABORTING due to invalid path from sender: %s/%s\n", |
| dn, file->basename); |
| exit_cleanup(RERR_PROTOCOL); |
| } |
} |
} |
if (relative_paths && !implied_dirs | if (relative_paths && !implied_dirs && file->mode != 0 |
&& do_stat(dn, &sx.st) < 0) { |
&& do_stat(dn, &sx.st) < 0) { |
if (dry_run) |
if (dry_run) |
goto parent_is_dry_missing; |
goto parent_is_dry_missing; |
if (make_path(fname, MKP_DROP_NAME | MKP_SKIP_SLASH) < 0) { | if (make_path(fname, ACCESSPERMS, MKP_DROP_NAME | MKP_SKIP_SLASH) < 0) { |
rsyserr(FERROR_XFER, errno, |
rsyserr(FERROR_XFER, errno, |
"recv_generator: mkdir %s failed", |
"recv_generator: mkdir %s failed", |
full_fname(dn)); |
full_fname(dn)); |
Line 1287 static void recv_generator(char *fname, struct file_st
|
Line 1513 static void recv_generator(char *fname, struct file_st
|
fuzzy_dirlist[i] = NULL; |
fuzzy_dirlist[i] = NULL; |
} |
} |
} |
} |
need_fuzzy_dirlist = 1; | need_new_dirscan = 1; |
} | } else if (checksum_files) |
| need_new_dirscan = 1; |
#ifdef SUPPORT_ACLS |
#ifdef SUPPORT_ACLS |
if (!preserve_perms) |
if (!preserve_perms) |
dflt_perms = default_perms_for_dir(dn); |
dflt_perms = default_perms_for_dir(dn); |
Line 1296 static void recv_generator(char *fname, struct file_st
|
Line 1523 static void recv_generator(char *fname, struct file_st
|
} |
} |
parent_dirname = dn; |
parent_dirname = dn; |
|
|
if (need_fuzzy_dirlist && S_ISREG(file->mode)) { | if (need_new_dirscan && S_ISREG(file->mode)) { |
int i; |
int i; |
strlcpy(fnamecmpbuf, dn, sizeof fnamecmpbuf); |
strlcpy(fnamecmpbuf, dn, sizeof fnamecmpbuf); |
for (i = 0; i < fuzzy_basis; i++) { |
for (i = 0; i < fuzzy_basis; i++) { |
if (i && pathjoin(fnamecmpbuf, MAXPATHLEN, basis_dir[i-1], dn) >= MAXPATHLEN) |
if (i && pathjoin(fnamecmpbuf, MAXPATHLEN, basis_dir[i-1], dn) >= MAXPATHLEN) |
continue; |
continue; |
fuzzy_dirlist[i] = get_dirlist(fnamecmpbuf, -1, GDL_IGNORE_FILTER_RULES); | fuzzy_dirlist[i] = get_dirlist(fnamecmpbuf, -1, GDL_IGNORE_FILTER_RULES | GDL_PERHAPS_DIR); |
if (fuzzy_dirlist[i] && fuzzy_dirlist[i]->used == 0) { |
if (fuzzy_dirlist[i] && fuzzy_dirlist[i]->used == 0) { |
flist_free(fuzzy_dirlist[i]); |
flist_free(fuzzy_dirlist[i]); |
fuzzy_dirlist[i] = NULL; |
fuzzy_dirlist[i] = NULL; |
} |
} |
} |
} |
need_fuzzy_dirlist = 0; | if (checksum_files) { |
| reset_checksum_cache(started_whole_dir); |
| started_whole_dir = upcoming_whole_dir; |
| } |
| need_new_dirscan = 0; |
} |
} |
|
|
statret = link_stat(fname, &sx.st, keep_dirlinks && is_dir); |
statret = link_stat(fname, &sx.st, keep_dirlinks && is_dir); |
Line 1370 static void recv_generator(char *fname, struct file_st
|
Line 1601 static void recv_generator(char *fname, struct file_st
|
added_perms = 0; |
added_perms = 0; |
if (is_dir < 0) { |
if (is_dir < 0) { |
if (!(preserve_times & PRESERVE_DIR_TIMES)) |
if (!(preserve_times & PRESERVE_DIR_TIMES)) |
return; | goto cleanup; |
/* In inc_recurse mode we want to make sure any missing |
/* In inc_recurse mode we want to make sure any missing |
* directories get created while we're still processing |
* directories get created while we're still processing |
* the parent dir (which allows us to touch the parent |
* the parent dir (which allows us to touch the parent |
Line 1404 static void recv_generator(char *fname, struct file_st
|
Line 1635 static void recv_generator(char *fname, struct file_st
|
real_ret = statret; |
real_ret = statret; |
if (file->flags & FLAG_DIR_CREATED) |
if (file->flags & FLAG_DIR_CREATED) |
statret = -1; |
statret = -1; |
if (!preserve_perms) { /* See comment in non-dir code below. */ | if (!preserve_perms || omit_dir_changes) { /* See comment in non-dir code below. */ |
file->mode = dest_mode(file->mode, sx.st.st_mode, | file->mode = dest_mode(file->mode, sx.st.st_mode, dflt_perms, statret == 0); |
dflt_perms, statret == 0); | |
} |
} |
|
#ifdef SUPPORT_FORCE_CHANGE |
|
if (force_change && !preserve_fileflags) |
|
F_FFLAGS(file) = sx.st.st_flags; |
|
#endif |
if (statret != 0 && basis_dir[0] != NULL) { |
if (statret != 0 && basis_dir[0] != NULL) { |
int j = try_dests_non(file, fname, ndx, fnamecmpbuf, &sx, | int j = try_dests_non(file, fname, ndx, fnamecmpbuf, &sx, itemizing, code); |
itemizing, code); | |
if (j == -2) { |
if (j == -2) { |
itemizing = 0; |
itemizing = 0; |
code = FNONE; |
code = FNONE; |
Line 1426 static void recv_generator(char *fname, struct file_st
|
Line 1659 static void recv_generator(char *fname, struct file_st
|
} |
} |
if (real_ret != 0 && do_mkdir(fname,file->mode|added_perms) < 0 && errno != EEXIST) { |
if (real_ret != 0 && do_mkdir(fname,file->mode|added_perms) < 0 && errno != EEXIST) { |
if (!relative_paths || errno != ENOENT |
if (!relative_paths || errno != ENOENT |
|| make_path(fname, MKP_DROP_NAME | MKP_SKIP_SLASH) < 0 | || make_path(fname, ACCESSPERMS, MKP_DROP_NAME | MKP_SKIP_SLASH) < 0 |
|| (do_mkdir(fname, file->mode|added_perms) < 0 && errno != EEXIST)) { |
|| (do_mkdir(fname, file->mode|added_perms) < 0 && errno != EEXIST)) { |
rsyserr(FERROR_XFER, errno, |
rsyserr(FERROR_XFER, errno, |
"recv_generator: mkdir %s failed", |
"recv_generator: mkdir %s failed", |
full_fname(fname)); |
full_fname(fname)); |
skipping_dir_contents: |
skipping_dir_contents: |
rprintf(FERROR, | rprintf(FERROR, "*** Skipping any contents from this failed directory ***\n"); |
"*** Skipping any contents from this failed directory ***\n"); | |
skip_dir = file; |
skip_dir = file; |
file->flags |= FLAG_MISSING_DIR; |
file->flags |= FLAG_MISSING_DIR; |
goto cleanup; |
goto cleanup; |
Line 1445 static void recv_generator(char *fname, struct file_st
|
Line 1677 static void recv_generator(char *fname, struct file_st
|
copy_xattrs(fnamecmpbuf, fname); |
copy_xattrs(fnamecmpbuf, fname); |
#endif |
#endif |
if (set_file_attrs(fname, file, real_ret ? NULL : &real_sx, NULL, 0) |
if (set_file_attrs(fname, file, real_ret ? NULL : &real_sx, NULL, 0) |
&& INFO_GTE(NAME, 1) && code != FNONE && f_out != -1) | && INFO_GTE(NAME, 1) && code != FNONE && f_out != -1) |
rprintf(code, "%s/\n", fname); |
rprintf(code, "%s/\n", fname); |
|
|
/* We need to ensure that the dirs in the transfer have both |
/* We need to ensure that the dirs in the transfer have both |
* readable and writable permissions during the time we are |
* readable and writable permissions during the time we are |
* putting files within them. This is then restored to the |
* putting files within them. This is then restored to the |
* former permissions after the transfer is done. */ |
* former permissions after the transfer is done. */ |
|
#ifdef SUPPORT_FORCE_CHANGE |
|
if (force_change && F_FFLAGS(file) & force_change |
|
&& make_mutable(fname, file->mode, F_FFLAGS(file), force_change)) |
|
need_retouch_dir_perms = 1; |
|
#endif |
#ifdef HAVE_CHMOD |
#ifdef HAVE_CHMOD |
if (!am_root && (file->mode & S_IRWXU) != S_IRWXU && dir_tweaking) { |
if (!am_root && (file->mode & S_IRWXU) != S_IRWXU && dir_tweaking) { |
mode_t mode = file->mode | S_IRWXU; |
mode_t mode = file->mode | S_IRWXU; |
if (do_chmod(fname, mode) < 0) { | if (do_chmod(fname, mode, 0) < 0) { |
rsyserr(FERROR_XFER, errno, |
rsyserr(FERROR_XFER, errno, |
"failed to modify permissions on %s", |
"failed to modify permissions on %s", |
full_fname(fname)); |
full_fname(fname)); |
Line 1475 static void recv_generator(char *fname, struct file_st
|
Line 1712 static void recv_generator(char *fname, struct file_st
|
} |
} |
else if (delete_during && f_out != -1 && !phase |
else if (delete_during && f_out != -1 && !phase |
&& !(file->flags & FLAG_MISSING_DIR)) { |
&& !(file->flags & FLAG_MISSING_DIR)) { |
if (file->flags & FLAG_CONTENT_DIR) | if (file->flags & FLAG_CONTENT_DIR) { |
delete_in_dir(fname, file, &real_sx.st.st_dev); | if (detect_renamed && real_ret != 0) |
else | unexplored_dirs++; |
| delete_in_dir(fname, file, &real_sx.st.st_dev, |
| delete_during < 0 ? DEL_NO_DELETIONS : 0); |
| } else |
change_local_filter_dir(fname, strlen(fname), F_DEPTH(file)); |
change_local_filter_dir(fname, strlen(fname), F_DEPTH(file)); |
} |
} |
|
upcoming_whole_dir = file->flags & FLAG_CONTENT_DIR && f_out != -1 ? 1 : 0; |
prior_dir_file = file; |
prior_dir_file = file; |
goto cleanup; |
goto cleanup; |
} |
} |
Line 1488 static void recv_generator(char *fname, struct file_st
|
Line 1729 static void recv_generator(char *fname, struct file_st
|
* mode based on the local permissions and some heuristics. */ |
* mode based on the local permissions and some heuristics. */ |
if (!preserve_perms) { |
if (!preserve_perms) { |
int exists = statret == 0 && !S_ISDIR(sx.st.st_mode); |
int exists = statret == 0 && !S_ISDIR(sx.st.st_mode); |
file->mode = dest_mode(file->mode, sx.st.st_mode, dflt_perms, | file->mode = dest_mode(file->mode, sx.st.st_mode, dflt_perms, exists); |
exists); | |
} |
} |
|
#ifdef SUPPORT_FORCE_CHANGE |
|
if (force_change && !preserve_fileflags) |
|
F_FFLAGS(file) = sx.st.st_flags; |
|
#endif |
|
|
#ifdef SUPPORT_HARD_LINKS |
#ifdef SUPPORT_HARD_LINKS |
if (preserve_hard_links && F_HLINK_NOT_FIRST(file) |
if (preserve_hard_links && F_HLINK_NOT_FIRST(file) |
Line 1512 static void recv_generator(char *fname, struct file_st
|
Line 1756 static void recv_generator(char *fname, struct file_st
|
"ignoring unsafe symlink \"%s\" -> \"%s\"\n", |
"ignoring unsafe symlink \"%s\" -> \"%s\"\n", |
fname, sl); |
fname, sl); |
} |
} |
return; | goto cleanup; |
} |
} |
if (statret == 0) { |
if (statret == 0) { |
char lnk[MAXPATHLEN]; |
char lnk[MAXPATHLEN]; |
Line 1534 static void recv_generator(char *fname, struct file_st
|
Line 1778 static void recv_generator(char *fname, struct file_st
|
goto cleanup; |
goto cleanup; |
} |
} |
} else if (basis_dir[0] != NULL) { |
} else if (basis_dir[0] != NULL) { |
int j = try_dests_non(file, fname, ndx, fnamecmpbuf, &sx, | int j = try_dests_non(file, fname, ndx, fnamecmpbuf, &sx, itemizing, code); |
itemizing, code); | |
if (j == -2) { |
if (j == -2) { |
#ifndef CAN_HARDLINK_SYMLINK |
#ifndef CAN_HARDLINK_SYMLINK |
if (link_dest) { | if (alt_dest_type == LINK_DEST) { |
/* Resort to --copy-dest behavior. */ |
/* Resort to --copy-dest behavior. */ |
} else |
} else |
#endif |
#endif |
if (!copy_dest) | if (alt_dest_type != COPY_DEST) |
goto cleanup; |
goto cleanup; |
itemizing = 0; |
itemizing = 0; |
code = FNONE; |
code = FNONE; |
Line 1610 static void recv_generator(char *fname, struct file_st
|
Line 1853 static void recv_generator(char *fname, struct file_st
|
goto cleanup; |
goto cleanup; |
} |
} |
} else if (basis_dir[0] != NULL) { |
} else if (basis_dir[0] != NULL) { |
int j = try_dests_non(file, fname, ndx, fnamecmpbuf, &sx, | int j = try_dests_non(file, fname, ndx, fnamecmpbuf, &sx, itemizing, code); |
itemizing, code); | |
if (j == -2) { |
if (j == -2) { |
#ifndef CAN_HARDLINK_SPECIAL |
#ifndef CAN_HARDLINK_SPECIAL |
if (link_dest) { | if (alt_dest_type == LINK_DEST) { |
/* Resort to --copy-dest behavior. */ |
/* Resort to --copy-dest behavior. */ |
} else |
} else |
#endif |
#endif |
if (!copy_dest) | if (alt_dest_type != COPY_DEST) |
goto cleanup; |
goto cleanup; |
itemizing = 0; |
itemizing = 0; |
code = FNONE; |
code = FNONE; |
Line 1650 static void recv_generator(char *fname, struct file_st
|
Line 1892 static void recv_generator(char *fname, struct file_st
|
goto cleanup; |
goto cleanup; |
} |
} |
|
|
if (!S_ISREG(file->mode)) { | if (!(S_ISREG(file->mode) || (copy_devices && IS_DEVICE(file->mode)))) { |
if (solo_file) |
if (solo_file) |
fname = f_name(file, NULL); |
fname = f_name(file, NULL); |
rprintf(FINFO, "skipping non-regular file \"%s\"\n", fname); |
rprintf(FINFO, "skipping non-regular file \"%s\"\n", fname); |
Line 1674 static void recv_generator(char *fname, struct file_st
|
Line 1916 static void recv_generator(char *fname, struct file_st
|
goto cleanup; |
goto cleanup; |
} |
} |
|
|
if (update_only > 0 && statret == 0 | if (update_only > 0 && statret == 0 && file->modtime - sx.st.st_mtime <= modify_window) { |
&& cmp_time(sx.st.st_mtime, file->modtime) > 0) { | |
if (INFO_GTE(SKIP, 1)) |
if (INFO_GTE(SKIP, 1)) |
rprintf(FINFO, "%s is newer\n", fname); |
rprintf(FINFO, "%s is newer\n", fname); |
#ifdef SUPPORT_HARD_LINKS |
#ifdef SUPPORT_HARD_LINKS |
Line 1685 static void recv_generator(char *fname, struct file_st
|
Line 1926 static void recv_generator(char *fname, struct file_st
|
goto cleanup; |
goto cleanup; |
} |
} |
|
|
|
if (downdate_only > 0 && statret == 0 && file->modtime - sx.st.st_mtime >= modify_window) { |
|
if (INFO_GTE(SKIP, 1)) |
|
rprintf(FINFO, "%s is older\n", fname); |
|
return; |
|
} |
|
|
fnamecmp_type = FNAMECMP_FNAME; |
fnamecmp_type = FNAMECMP_FNAME; |
|
|
if (statret == 0 && !S_ISREG(sx.st.st_mode)) { | if (statret == 0 && !(S_ISREG(sx.st.st_mode) || (write_devices && IS_DEVICE(sx.st.st_mode)))) { |
if (delete_item(fname, sx.st.st_mode, del_opts | DEL_FOR_FILE) != 0) |
if (delete_item(fname, sx.st.st_mode, del_opts | DEL_FOR_FILE) != 0) |
goto cleanup; |
goto cleanup; |
statret = -1; |
statret = -1; |
stat_errno = ENOENT; |
stat_errno = ENOENT; |
} |
} |
|
|
if (basis_dir[0] != NULL && (statret != 0 || !copy_dest)) { | if (basis_dir[0] != NULL && (statret != 0 || alt_dest_type != COPY_DEST)) { |
int j = try_dests_reg(file, fname, ndx, fnamecmpbuf, &sx, | int j = try_dests_reg(file, fname, ndx, fnamecmpbuf, &sx, statret == 0, itemizing, code); |
statret == 0, itemizing, code); | |
if (j == -2) { |
if (j == -2) { |
if (remove_source_files == 1) |
if (remove_source_files == 1) |
goto return_with_success; |
goto return_with_success; |
Line 1714 static void recv_generator(char *fname, struct file_st
|
Line 1960 static void recv_generator(char *fname, struct file_st
|
real_ret = statret; |
real_ret = statret; |
|
|
if (partial_dir && (partialptr = partial_dir_fname(fname)) != NULL |
if (partial_dir && (partialptr = partial_dir_fname(fname)) != NULL |
&& link_stat(partialptr, &partial_st, 0) == 0 | && link_stat(partialptr, &partial_st, 0) == 0 |
&& S_ISREG(partial_st.st_mode)) { | && S_ISREG(partial_st.st_mode)) { |
if (statret != 0) |
if (statret != 0) |
goto prepare_to_open; |
goto prepare_to_open; |
} else |
} else |
Line 1731 static void recv_generator(char *fname, struct file_st
|
Line 1977 static void recv_generator(char *fname, struct file_st
|
fname, fnamecmpbuf); |
fname, fnamecmpbuf); |
} |
} |
sx.st.st_size = F_LENGTH(fuzzy_file); |
sx.st.st_size = F_LENGTH(fuzzy_file); |
|
#ifdef SUPPORT_HFS_COMPRESSION |
|
if (sx.st.st_flags & UF_COMPRESSED) { |
|
if (preserve_hfs_compression) |
|
sx.st.st_size = 0; |
|
else |
|
sx.st.st_flags &= ~UF_COMPRESSED; |
|
} |
|
#endif |
statret = 0; |
statret = 0; |
fnamecmp = fnamecmpbuf; |
fnamecmp = fnamecmpbuf; |
} |
} |
Line 1743 static void recv_generator(char *fname, struct file_st
|
Line 1997 static void recv_generator(char *fname, struct file_st
|
goto cleanup; |
goto cleanup; |
} |
} |
#endif |
#endif |
if (stat_errno == ENOENT) | if (stat_errno == ENOENT) { |
| if (detect_renamed && unexplored_dirs > 0 |
| && F_LENGTH(file)) { |
| bitbag_set_bit(delayed_bits, ndx); |
| return; |
| } |
goto notify_others; |
goto notify_others; |
|
} |
rsyserr(FERROR_XFER, stat_errno, "recv_generator: failed to stat %s", |
rsyserr(FERROR_XFER, stat_errno, "recv_generator: failed to stat %s", |
full_fname(fname)); |
full_fname(fname)); |
goto cleanup; |
goto cleanup; |
Line 1752 static void recv_generator(char *fname, struct file_st
|
Line 2012 static void recv_generator(char *fname, struct file_st
|
|
|
if (fnamecmp_type <= FNAMECMP_BASIS_DIR_HIGH) |
if (fnamecmp_type <= FNAMECMP_BASIS_DIR_HIGH) |
; |
; |
else if (fnamecmp_type == FNAMECMP_FUZZY) | else if (fnamecmp_type >= FNAMECMP_FUZZY) |
; |
; |
else if (unchanged_file(fnamecmp, file, &sx.st)) { | else if (unchanged_file(fnamecmp, file, &sx.st, fnamecmp_type == FNAMECMP_FNAME ? 0 : -1)) { |
if (partialptr) { |
if (partialptr) { |
do_unlink(partialptr); |
do_unlink(partialptr); |
handle_partial_dir(partialptr, PDIR_DELETE); |
handle_partial_dir(partialptr, PDIR_DELETE); |
} |
} |
set_file_attrs(fname, file, &sx, NULL, maybe_ATTRS_REPORT); | set_file_attrs(fname, file, &sx, NULL, maybe_ATTRS_REPORT | maybe_ATTRS_ACCURATE_TIME); |
| if (checksum_files & CSF_UPDATE) |
| set_cached_checksum(cur_flist, file); |
if (itemizing) |
if (itemizing) |
itemize(fnamecmp, file, ndx, statret, &sx, 0, 0, NULL); |
itemize(fnamecmp, file, ndx, statret, &sx, 0, 0, NULL); |
#ifdef SUPPORT_HARD_LINKS |
#ifdef SUPPORT_HARD_LINKS |
Line 1788 static void recv_generator(char *fname, struct file_st
|
Line 2050 static void recv_generator(char *fname, struct file_st
|
fnamecmp = partialptr; |
fnamecmp = partialptr; |
fnamecmp_type = FNAMECMP_PARTIAL_DIR; |
fnamecmp_type = FNAMECMP_PARTIAL_DIR; |
statret = 0; |
statret = 0; |
|
if (detect_renamed > 1 && unchanged_file(fnamecmp, file, &sx.st)) { |
|
/* Adopt the partial file. */ |
|
finish_transfer(fname, fnamecmp, NULL, NULL, file, 1, 1); |
|
handle_partial_dir(partialptr, PDIR_DELETE); |
|
if (itemizing) |
|
itemize(fnamecmp, file, ndx, -1, &sx, |
|
ITEM_LOCAL_CHANGE, fnamecmp_type, NULL); |
|
#ifdef SUPPORT_HARD_LINKS |
|
if (preserve_hard_links && F_IS_HLINKED(file)) |
|
finish_hard_link(file, fname, ndx, &sx.st, itemizing, code, -1); |
|
#endif |
|
if (remove_source_files == 1) |
|
goto return_with_success; |
|
goto cleanup; |
|
} |
} |
} |
|
|
if (!do_xfers) |
if (!do_xfers) |
goto notify_others; |
goto notify_others; |
|
|
if (read_batch || whole_file) { |
if (read_batch || whole_file) { |
if (inplace && make_backups > 0 && fnamecmp_type == FNAMECMP_FNAME) { | if (inplace && make_backups > 1 && fnamecmp_type == FNAMECMP_FNAME) { |
if (!(backupptr = get_backup_name(fname))) |
if (!(backupptr = get_backup_name(fname))) |
goto cleanup; |
goto cleanup; |
if (!(back_file = make_file(fname, NULL, NULL, 0, NO_FILTERS))) |
if (!(back_file = make_file(fname, NULL, NULL, 0, NO_FILTERS))) |
Line 1830 static void recv_generator(char *fname, struct file_st
|
Line 2107 static void recv_generator(char *fname, struct file_st
|
goto notify_others; |
goto notify_others; |
} |
} |
|
|
if (inplace && make_backups > 0 && fnamecmp_type == FNAMECMP_FNAME) { | if (inplace && make_backups > 1 && fnamecmp_type == FNAMECMP_FNAME) { |
if (!(backupptr = get_backup_name(fname))) { |
if (!(backupptr = get_backup_name(fname))) { |
close(fd); |
close(fd); |
goto cleanup; |
goto cleanup; |
Line 1857 static void recv_generator(char *fname, struct file_st
|
Line 2134 static void recv_generator(char *fname, struct file_st
|
fnamecmp_type = FNAMECMP_BACKUP; |
fnamecmp_type = FNAMECMP_BACKUP; |
} |
} |
|
|
|
if (IS_DEVICE(sx.st.st_mode) && sx.st.st_size == 0) |
|
sx.st.st_size = get_device_size(fd, fnamecmp); |
|
|
if (DEBUG_GTE(DELTASUM, 3)) { |
if (DEBUG_GTE(DELTASUM, 3)) { |
rprintf(FINFO, "gen mapped %s of size %s\n", |
rprintf(FINFO, "gen mapped %s of size %s\n", |
fnamecmp, big_num(sx.st.st_size)); |
fnamecmp, big_num(sx.st.st_size)); |
Line 1898 static void recv_generator(char *fname, struct file_st
|
Line 2178 static void recv_generator(char *fname, struct file_st
|
if (read_batch) |
if (read_batch) |
goto cleanup; |
goto cleanup; |
|
|
|
#ifdef SUPPORT_HFS_COMPRESSION |
|
if (F_FFLAGS(file) & UF_COMPRESSED) { |
|
/* At this point the attrs have already been copied, we don't need to transfer a data fork |
|
* If my filesystem doesn't support HFS compression, the existing file's content |
|
* will not be automatically truncated, so we'll do that manually here */ |
|
if (preserve_hfs_compression && sx.st.st_size > 0) { |
|
if (ftruncate(fd, 0) == 0) |
|
sx.st.st_size = 0; |
|
} |
|
} |
|
#endif |
|
|
if (statret != 0 || whole_file) |
if (statret != 0 || whole_file) |
write_sum_head(f_out, NULL); |
write_sum_head(f_out, NULL); |
else if (sx.st.st_size <= 0) { |
else if (sx.st.st_size <= 0) { |
Line 1906 static void recv_generator(char *fname, struct file_st
|
Line 2198 static void recv_generator(char *fname, struct file_st
|
} else { |
} else { |
if (generate_and_send_sums(fd, sx.st.st_size, f_out, f_copy) < 0) { |
if (generate_and_send_sums(fd, sx.st.st_size, f_out, f_copy) < 0) { |
rprintf(FWARNING, |
rprintf(FWARNING, |
"WARNING: file is too large for checksum sending: %s\n", | "WARNING: file is too large for checksum sending: %s\n", |
fnamecmp); | fnamecmp); |
write_sum_head(f_out, NULL); |
write_sum_head(f_out, NULL); |
} |
} |
close(fd); |
close(fd); |
Line 1954 int atomic_create(struct file_struct *file, char *fnam
|
Line 2246 int atomic_create(struct file_struct *file, char *fnam
|
skip_atomic = 0; |
skip_atomic = 0; |
|
|
if (del_for_flag) { |
if (del_for_flag) { |
if (make_backups > 0 && !dir_in_the_way) { | if (make_backups > 1 && !dir_in_the_way) { |
if (!make_backup(fname, skip_atomic)) |
if (!make_backup(fname, skip_atomic)) |
return 0; |
return 0; |
} else if (skip_atomic) { |
} else if (skip_atomic) { |
Line 2059 static void touch_up_dirs(struct file_list *flist, int
|
Line 2351 static void touch_up_dirs(struct file_list *flist, int
|
continue; |
continue; |
fname = f_name(file, NULL); |
fname = f_name(file, NULL); |
if (fix_dir_perms) |
if (fix_dir_perms) |
do_chmod(fname, file->mode); | do_chmod(fname, file->mode, 0); |
if (need_retouch_dir_times) { |
if (need_retouch_dir_times) { |
STRUCT_STAT st; |
STRUCT_STAT st; |
if (link_stat(fname, &st, 0) == 0 | if (link_stat(fname, &st, 0) == 0 && mtime_differs(&st, file)) { |
&& cmp_time(st.st_mtime, file->modtime) != 0) | st.st_mtime = file->modtime; |
set_modtime(fname, file->modtime, F_MOD_NSEC(file), file->mode); | #ifdef ST_MTIME_NSEC |
| st.ST_MTIME_NSEC = F_MOD_NSEC_or_0(file); |
| #endif |
| #ifdef SUPPORT_FORCE_CHANGE |
| st.st_mode = file->mode; |
| st.st_flags = 0; |
| #endif |
| set_times(fname, &st); |
| } |
} |
} |
|
#ifdef SUPPORT_FORCE_CHANGE |
|
if (force_change && F_FFLAGS(file) & force_change) |
|
undo_make_mutable(fname, F_FFLAGS(file)); |
|
#endif |
if (counter >= loopchk_limit) { |
if (counter >= loopchk_limit) { |
if (allowed_lull) |
if (allowed_lull) |
maybe_send_keepalive(time(NULL), MSK_ALLOW_FLUSH); |
maybe_send_keepalive(time(NULL), MSK_ALLOW_FLUSH); |
Line 2110 void check_for_finished_files(int itemizing, enum logc
|
Line 2414 void check_for_finished_files(int itemizing, enum logc
|
ignore_existing = -ignore_existing; |
ignore_existing = -ignore_existing; |
ignore_non_existing = -ignore_non_existing; |
ignore_non_existing = -ignore_non_existing; |
update_only = -update_only; |
update_only = -update_only; |
|
downdate_only = -downdate_only; |
|
downdate_only = -downdate_only; |
always_checksum = -always_checksum; |
always_checksum = -always_checksum; |
size_only = -size_only; |
size_only = -size_only; |
append_mode = -append_mode; |
append_mode = -append_mode; |
Line 2204 void generate_files(int f_out, const char *local_name)
|
Line 2510 void generate_files(int f_out, const char *local_name)
|
if (DEBUG_GTE(GENR, 1)) |
if (DEBUG_GTE(GENR, 1)) |
rprintf(FINFO, "generator starting pid=%d\n", (int)getpid()); |
rprintf(FINFO, "generator starting pid=%d\n", (int)getpid()); |
|
|
|
if (detect_renamed) { |
|
delayed_bits = bitbag_create(cur_flist->used); |
|
if (!delete_before && !delete_during) |
|
delete_during = -1; |
|
} |
|
|
if (delete_before && !solo_file && cur_flist->used > 0) |
if (delete_before && !solo_file && cur_flist->used > 0) |
do_delete_pass(); |
do_delete_pass(); |
if (delete_during == 2) { |
if (delete_during == 2) { |
deldelay_size = BIGPATHBUFLEN * 4; |
deldelay_size = BIGPATHBUFLEN * 4; |
deldelay_buf = new_array(char, deldelay_size); |
deldelay_buf = new_array(char, deldelay_size); |
if (!deldelay_buf) |
|
out_of_memory("delete-delay"); |
|
} |
} |
info_levels[INFO_FLIST] = info_levels[INFO_PROGRESS] = 0; |
info_levels[INFO_FLIST] = info_levels[INFO_PROGRESS] = 0; |
|
|
if (append_mode > 0 || whole_file < 0) | if (append_mode > 0 || detect_renamed || whole_file < 0) |
whole_file = 0; |
whole_file = 0; |
if (DEBUG_GTE(FLIST, 1)) { |
if (DEBUG_GTE(FLIST, 1)) { |
rprintf(FINFO, "delta-transmission %s\n", |
rprintf(FINFO, "delta-transmission %s\n", |
Line 2223 void generate_files(int f_out, const char *local_name)
|
Line 2533 void generate_files(int f_out, const char *local_name)
|
: "enabled"); |
: "enabled"); |
} |
} |
|
|
|
if (use_db) { |
|
if (always_checksum || (append_mode != 1 && protocol_version >= 30)) |
|
db_connect(0); /* Will reset use_db on error. */ |
|
else |
|
use_db = 0; |
|
} |
|
|
dflt_perms = (ACCESSPERMS & ~orig_umask); |
dflt_perms = (ACCESSPERMS & ~orig_umask); |
|
|
do { |
do { |
Line 2250 void generate_files(int f_out, const char *local_name)
|
Line 2567 void generate_files(int f_out, const char *local_name)
|
dirdev = MAKEDEV(DEV_MAJOR(devp), DEV_MINOR(devp)); |
dirdev = MAKEDEV(DEV_MAJOR(devp), DEV_MINOR(devp)); |
} else |
} else |
dirdev = MAKEDEV(0, 0); |
dirdev = MAKEDEV(0, 0); |
delete_in_dir(fbuf, fp, &dirdev); | delete_in_dir(fbuf, fp, &dirdev, 0); |
} else |
} else |
change_local_filter_dir(fbuf, strlen(fbuf), F_DEPTH(fp)); |
change_local_filter_dir(fbuf, strlen(fbuf), F_DEPTH(fp)); |
} |
} |
|
upcoming_whole_dir = fp->flags & FLAG_CONTENT_DIR ? 1 : 0; |
} |
} |
for (i = cur_flist->low; i <= cur_flist->high; i++) { |
for (i = cur_flist->low; i <= cur_flist->high; i++) { |
struct file_struct *file = cur_flist->sorted[i]; |
struct file_struct *file = cur_flist->sorted[i]; |
Line 2297 void generate_files(int f_out, const char *local_name)
|
Line 2615 void generate_files(int f_out, const char *local_name)
|
} while ((cur_flist = cur_flist->next) != NULL); |
} while ((cur_flist = cur_flist->next) != NULL); |
|
|
if (delete_during) |
if (delete_during) |
delete_in_dir(NULL, NULL, &dev_zero); | delete_in_dir(NULL, NULL, &dev_zero, 0); |
| if (detect_renamed) { |
| if (delete_during < 0) |
| delete_during = 0; |
| detect_renamed = 0; |
| |
| for (i = -1; (i = bitbag_next_bit(delayed_bits, i)) >= 0; ) { |
| struct file_struct *file = cur_flist->files[i]; |
| if (local_name) |
| strlcpy(fbuf, local_name, sizeof fbuf); |
| else |
| f_name(file, fbuf); |
| recv_generator(fbuf, file, i, itemizing, code, f_out); |
| } |
| } |
phase++; |
phase++; |
if (DEBUG_GTE(GENR, 1)) |
if (DEBUG_GTE(GENR, 1)) |
rprintf(FINFO, "generate_files phase=%d\n", phase); |
rprintf(FINFO, "generate_files phase=%d\n", phase); |
Line 2347 void generate_files(int f_out, const char *local_name)
|
Line 2679 void generate_files(int f_out, const char *local_name)
|
while (msgdone_cnt == 2) |
while (msgdone_cnt == 2) |
wait_for_receiver(); |
wait_for_receiver(); |
} |
} |
|
|
|
if (checksum_files) |
|
reset_checksum_cache(started_whole_dir); |
|
|
|
if (use_db) |
|
db_disconnect(True); |
|
|
info_levels[INFO_FLIST] = save_info_flist; |
info_levels[INFO_FLIST] = save_info_flist; |
info_levels[INFO_PROGRESS] = save_info_progress; |
info_levels[INFO_PROGRESS] = save_info_progress; |