extern int preserve_executability;
extern int preserve_perms;
extern int preserve_times;
-extern int uid_ndx;
-extern int gid_ndx;
extern int delete_mode;
extern int delete_before;
extern int delete_during;
rprintf(FINFO, " \r");
}
-int unchanged_attrs(const char *fname, struct file_struct *file, stat_x *sxp)
+static inline int time_differs(struct file_struct *file, stat_x *sxp)
{
-#ifndef CAN_SET_SYMLINK_TIMES
- if (S_ISLNK(file->mode)) {
- ;
- } else
-#endif
- if (preserve_times && cmp_time(sxp->st.st_mtime, file->modtime) != 0)
- return 0;
+ return cmp_time(sxp->st.st_mtime, file->modtime);
+}
- if (preserve_perms) {
- if (!BITS_EQUAL(sxp->st.st_mode, file->mode, CHMOD_BITS))
- return 0;
- } else if (preserve_executability
- && ((sxp->st.st_mode & 0111 ? 1 : 0) ^ (file->mode & 0111 ? 1 : 0)))
- return 0;
+static inline int perms_differ(struct file_struct *file, stat_x *sxp)
+{
+ if (preserve_perms)
+ return !BITS_EQUAL(sxp->st.st_mode, file->mode, CHMOD_BITS);
+ if (preserve_executability)
+ return (sxp->st.st_mode & 0111 ? 1 : 0) ^ (file->mode & 0111 ? 1 : 0);
+
+ return 0;
+}
+
+static inline int ownership_differs(struct file_struct *file, stat_x *sxp)
+{
if (am_root && uid_ndx && sxp->st.st_uid != (uid_t)F_OWNER(file))
- return 0;
+ return 1;
if (gid_ndx && !(file->flags & FLAG_SKIP_GROUP) && sxp->st.st_gid != (gid_t)F_GROUP(file))
- return 0;
+ return 1;
+
+ return 0;
+}
#ifdef SUPPORT_ACLS
- if (preserve_acls && !S_ISLNK(file->mode)) {
+static inline int acls_differ(const char *fname, struct file_struct *file, stat_x *sxp)
+{
+ if (preserve_acls) {
if (!ACL_READY(*sxp))
get_acl(fname, sxp);
if (set_acl(NULL, file, sxp, file->mode))
- return 0;
+ return 1;
}
+
+ return 0;
+}
#endif
+
#ifdef SUPPORT_XATTRS
+static inline int xattrs_differ(const char *fname, struct file_struct *file, stat_x *sxp)
+{
if (preserve_xattrs) {
if (!XATTR_READY(*sxp))
get_xattr(fname, sxp);
if (xattr_diff(file, sxp, 0))
- return 0;
+ return 1;
}
+
+ return 0;
+}
+#endif
+
+int unchanged_attrs(const char *fname, struct file_struct *file, stat_x *sxp)
+{
+ if (S_ISLNK(file->mode)) {
+#ifdef CAN_SET_SYMLINK_TIMES
+ if (preserve_times & PRESERVE_LINK_TIMES && time_differs(file, sxp))
+ return 0;
+#endif
+#ifdef CAN_CHMOD_SYMLINK
+ if (perms_differ(file, sxp))
+ return 0;
#endif
+#ifndef CAN_CHOWN_SYMLINK
+ if (ownership_differs(file, sxp))
+ return 0;
+#endif
+#if defined SUPPORT_ACLS && 0 /* no current symlink-ACL support */
+ if (acls_differ(fname, file, sxp))
+ return 0;
+#endif
+#if defined SUPPORT_XATTRS && !defined NO_SYMLINK_XATTRS
+ if (xattrs_differ(fname, file, sxp))
+ return 0;
+#endif
+ } else {
+ if (preserve_times && time_differs(file, sxp))
+ return 0;
+ if (perms_differ(file, sxp))
+ return 0;
+ if (ownership_differs(file, sxp))
+ return 0;
+#ifdef SUPPORT_ACLS
+ if (acls_differ(fname, file, sxp))
+ return 0;
+#endif
+#ifdef SUPPORT_XATTRS
+ if (xattrs_differ(fname, file, sxp))
+ return 0;
+#endif
+ }
return 1;
}
{
if (statret >= 0) { /* A from-dest-dir statret can == 1! */
int keep_time = !preserve_times ? 0
- : S_ISDIR(file->mode) ? preserve_times > 1 :
-#ifdef CAN_SET_SYMLINK_TIMES
- 1;
-#else
- !S_ISLNK(file->mode);
-#endif
+ : S_ISDIR(file->mode) ? preserve_times & PRESERVE_DIR_TIMES
+ : S_ISLNK(file->mode) ? preserve_times & PRESERVE_LINK_TIMES
+ : 1;
if (S_ISREG(file->mode) && F_LENGTH(file) != sxp->st.st_size)
iflags |= ITEM_REPORT_SIZE;
int s2length;
int64 l;
+ if (len < 0) {
+ /* The file length overflowed our int64 var, so we can't process this file. */
+ sum->count = -1; /* indicate overflow error */
+ return;
+ }
+
if (block_size)
blength = block_size;
else if (len <= BLOCK_SIZE * BLOCK_SIZE)
#ifdef SUPPORT_LINKS
if (preserve_links && S_ISLNK(f->mode)) {
rprintf(FINFO, "%s %*s %s %s -> %s\n",
- permbuf, colwidth, comma_num(len),
+ permbuf, colwidth, human_num(len),
timestring(f->modtime), f_name(f, NULL),
F_SYMLINK(f));
} else
f_name(f, NULL));
} else {
rprintf(FINFO, "%s %*s %s %s\n",
- permbuf, colwidth, comma_num(len),
+ permbuf, colwidth, human_num(len),
timestring(f->modtime), f_name(f, NULL));
}
}
skip_dir = NULL;
}
+ init_stat_x(&sx);
if (daemon_filter_list.head && (*fname != '.' || fname[1])) {
if (check_filter(&daemon_filter_list, FLOG, fname, is_dir) < 0) {
if (is_dir < 0)
}
}
- init_stat_x(&sx);
if (dry_run > 1 || (dry_missing_dir && is_below(file, dry_missing_dir))) {
parent_is_dry_missing:
if (fuzzy_dirlist) {
if (need_fuzzy_dirlist && S_ISREG(file->mode)) {
strlcpy(fnamecmpbuf, dn, sizeof fnamecmpbuf);
- fuzzy_dirlist = get_dirlist(fnamecmpbuf, -1, 1);
+ fuzzy_dirlist = get_dirlist(fnamecmpbuf, -1, GDL_IGNORE_FILTER_RULES);
need_fuzzy_dirlist = 0;
}
goto cleanup;
}
+ fnamecmp = fname;
+
if (is_dir) {
+ mode_t added_perms;
if (!implied_dirs && file->flags & FLAG_IMPLIED_DIR)
goto cleanup;
+ if (am_root < 0) {
+ /* For --fake-super, the dir must be useable by the copying
+ * user, just like it would be for root. */
+ added_perms = S_IRUSR|S_IWUSR|S_IXUSR;
+ } else
+ added_perms = 0;
if (is_dir < 0) {
/* In inc_recurse mode we want to make sure any missing
* directories get created while we're still processing
&& (S_ISDIR(sx.st.st_mode)
|| delete_item(fname, sx.st.st_mode, del_opts | DEL_FOR_DIR) != 0))
goto cleanup; /* Any errors get reported later. */
- if (do_mkdir(fname, file->mode & 0700) == 0)
+ if (do_mkdir(fname, (file->mode|added_perms) & 0700) == 0)
file->flags |= FLAG_DIR_CREATED;
goto cleanup;
}
itemizing = 0;
code = FNONE;
statret = 1;
- } else if (j >= 0)
+ } else if (j >= 0) {
statret = 1;
+ fnamecmp = fnamecmpbuf;
+ }
}
if (itemizing && f_out != -1) {
- itemize(fname, file, ndx, statret, &sx,
+ itemize(fnamecmp, file, ndx, statret, &sx,
statret ? ITEM_LOCAL_CHANGE : 0, 0, NULL);
}
- if (real_ret != 0 && do_mkdir(fname,file->mode) < 0 && errno != EEXIST) {
+ if (real_ret != 0 && do_mkdir(fname,file->mode|added_perms) < 0 && errno != EEXIST) {
if (!relative_paths || errno != ENOENT
|| make_path(fname, MKP_DROP_NAME | MKP_SKIP_SLASH) < 0
- || (do_mkdir(fname, file->mode) < 0 && errno != EEXIST)) {
+ || (do_mkdir(fname, file->mode|added_perms) < 0 && errno != EEXIST)) {
rsyserr(FERROR_XFER, errno,
"recv_generator: mkdir %s failed",
full_fname(fname));
const char *sl = F_SYMLINK(file);
if (safe_symlinks && unsafe_symlink(sl, fname)) {
if (INFO_GTE(NAME, 1)) {
- if (solo_file)
+ if (solo_file) {
/* fname contains the destination path, but we
* want to report the source path. */
fname = f_name(file, NULL);
+ }
rprintf(FINFO,
"ignoring unsafe symlink \"%s\" -> \"%s\"\n",
fname, sl);
goto cleanup;
}
- fnamecmp = fname;
fnamecmp_type = FNAMECMP_FNAME;
if (statret == 0 && !S_ISREG(sx.st.st_mode)) {
}
solo_file = local_name;
dir_tweaking = !(list_only || solo_file || dry_run);
- need_retouch_dir_times = preserve_times > 1;
+ need_retouch_dir_times = preserve_times & PRESERVE_DIR_TIMES;
loopchk_limit = allowed_lull ? allowed_lull * 5 : 200;
symlink_timeset_failed_flags = ITEM_REPORT_TIME
| (protocol_version >= 30 || !am_server ? ITEM_REPORT_TIMEFAIL : 0);