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;
struct file_list *dirlist;
char delbuf[MAXPATHLEN];
int dlen, i;
- int save_uid_ndx = uid_ndx;
if (!fbuf) {
change_local_filter_dir(NULL, 0, 0);
if (allowed_lull)
maybe_send_keepalive(time(NULL), MSK_ALLOW_FLUSH);
- if (io_error && !ignore_errors) {
+ if (io_error & IOERR_GENERAL && !ignore_errors) {
if (already_warned)
return;
rprintf(FINFO,
return;
}
- if (!uid_ndx)
- uid_ndx = ++file_extra_cnt;
-
dirlist = get_dirlist(fbuf, dlen, 0);
/* If an item in dirlist is not found in flist, delete it
* a delete_item call with a DEL_MAKE_ROOM flag. */
if (flist_find_ignore_dirness(cur_flist, fp) < 0) {
int flags = DEL_RECURSE;
- if (!(fp->mode & S_IWUSR) && !am_root && (uid_t)F_OWNER(fp) == our_uid)
+ if (!(fp->mode & S_IWUSR) && !am_root && fp->flags & FLAG_OWNED_BY_US)
flags |= DEL_NO_UID_WRITE;
f_name(fp, delbuf);
if (delete_during == 2) {
}
flist_free(dirlist);
-
- if (!save_uid_ndx) {
- --file_extra_cnt;
- uid_ndx = 0;
- }
}
/* This deletes any files on the receiving side that are not present on the
rprintf(FINFO, " \r");
}
-static inline int time_differs(struct file_struct *file, stat_x *sxp)
+static BOOL preserve_time_of(struct file_struct *file)
+{
+ if (S_ISDIR(file->mode))
+ return preserve_times & PRESERVE_DIR_TIMES;
+ else if (S_ISLNK(file->mode))
+ /* PRESERVE_LINK_TIMES will only be set if CAN_SET_SYMLINK_TIMES. */
+ return preserve_times & PRESERVE_LINK_TIMES;
+ else
+ return preserve_times;
+}
+
+static BOOL report_time(struct file_struct *file, stat_x *sxp)
{
- return cmp_time(sxp->st.st_mtime, file->modtime);
+ return preserve_time_of(file) &&
+ cmp_time(sxp->st.st_mtime, file->modtime);
}
-static inline int perms_differ(struct file_struct *file, stat_x *sxp)
+static BOOL report_perms(struct file_struct *file, stat_x *sxp)
{
+#ifndef CAN_CHMOD_SYMLINK
+ if (S_ISLNK(file->mode))
+ return 0;
+#endif
+
if (preserve_perms)
return !BITS_EQUAL(sxp->st.st_mode, file->mode, CHMOD_BITS);
return 0;
}
-static inline int ownership_differs(struct file_struct *file, stat_x *sxp)
+static BOOL report_owner(struct file_struct *file, stat_x *sxp)
{
- if (am_root && uid_ndx && sxp->st.st_uid != (uid_t)F_OWNER(file))
- return 1;
+#ifndef CAN_CHOWN_SYMLINK
+ if (S_ISLNK(file->mode))
+ return 0;
+#endif
- if (gid_ndx && !(file->flags & FLAG_SKIP_GROUP) && sxp->st.st_gid != (gid_t)F_GROUP(file))
- return 1;
+ return uid_ndx && am_root && sxp->st.st_uid != (uid_t)F_OWNER(file);
+}
- return 0;
+static BOOL report_group(struct file_struct *file, stat_x *sxp)
+{
+#ifndef CAN_CHOWN_SYMLINK
+ if (S_ISLNK(file->mode))
+ return 0;
+#endif
+
+ return gid_ndx && !(file->flags & FLAG_SKIP_GROUP) && sxp->st.st_gid != (gid_t)F_GROUP(file);
}
#ifdef SUPPORT_ACLS
-static inline int acls_differ(const char *fname, struct file_struct *file, stat_x *sxp)
+static BOOL report_acls(const char *fname, struct file_struct *file, stat_x *sxp)
{
+#ifndef CAN_SET_SYMLINK_ACLS /* not currently */
+ if (S_ISLNK(file->mode))
+ return 0;
+#endif
+
if (preserve_acls) {
if (!ACL_READY(*sxp))
get_acl(fname, sxp);
#endif
#ifdef SUPPORT_XATTRS
-static inline int xattrs_differ(const char *fname, struct file_struct *file, stat_x *sxp)
+static BOOL report_xattrs(const char *fname, struct file_struct *file, stat_x *sxp,
+ BOOL mark_needed)
{
+#ifdef NO_SYMLINK_XATTRS
+ if (S_ISLNK(file->mode))
+ return 0;
+#endif
+
if (preserve_xattrs) {
if (!XATTR_READY(*sxp))
get_xattr(fname, sxp);
- if (xattr_diff(file, sxp, 0))
+ if (xattr_diff(file, sxp, mark_needed))
return 1;
}
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;
+ return !(report_time(file, sxp)
+ || report_perms(file, sxp)
+ || report_owner(file, sxp)
+ || report_group(file, sxp)
#ifdef SUPPORT_ACLS
- if (acls_differ(fname, file, sxp))
- return 0;
+ || report_acls(fname, file, sxp)
#endif
#ifdef SUPPORT_XATTRS
- if (xattrs_differ(fname, file, sxp))
- return 0;
+ || report_xattrs(fname, file, sxp, False)
#endif
- }
-
- return 1;
+ );
}
void itemize(const char *fnamecmp, struct file_struct *file, int ndx, int statret,
const char *xname)
{
if (statret >= 0) { /* A from-dest-dir statret can == 1! */
- int keep_time = !preserve_times ? 0
- : 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;
if (file->flags & FLAG_TIME_FAILED) { /* symlinks only */
if (iflags & ITEM_LOCAL_CHANGE)
iflags |= symlink_timeset_failed_flags;
- } else if (keep_time
+ } else if (preserve_time_of(file)
? cmp_time(file->modtime, sxp->st.st_mtime) != 0
: iflags & (ITEM_TRANSFER|ITEM_LOCAL_CHANGE) && !(iflags & ITEM_MATCHED)
&& (!(iflags & ITEM_XNAME_FOLLOWS) || *xname))
iflags |= ITEM_REPORT_TIME;
-#if !defined HAVE_LCHMOD && !defined HAVE_SETATTRLIST
- if (S_ISLNK(file->mode)) {
- ;
- } else
-#endif
- if (preserve_perms) {
- if (!BITS_EQUAL(sxp->st.st_mode, file->mode, CHMOD_BITS))
- iflags |= ITEM_REPORT_PERMS;
- } else if (preserve_executability
- && ((sxp->st.st_mode & 0111 ? 1 : 0) ^ (file->mode & 0111 ? 1 : 0)))
+ if (report_perms(file, sxp))
iflags |= ITEM_REPORT_PERMS;
- if (uid_ndx && am_root && (uid_t)F_OWNER(file) != sxp->st.st_uid)
+ if (report_owner(file, sxp))
iflags |= ITEM_REPORT_OWNER;
- if (gid_ndx && !(file->flags & FLAG_SKIP_GROUP)
- && sxp->st.st_gid != (gid_t)F_GROUP(file))
+ if (report_group(file, sxp))
iflags |= ITEM_REPORT_GROUP;
#ifdef SUPPORT_ACLS
- if (preserve_acls && !S_ISLNK(file->mode)) {
- if (!ACL_READY(*sxp))
- get_acl(fnamecmp, sxp);
- if (set_acl(NULL, file, sxp, file->mode))
- iflags |= ITEM_REPORT_ACL;
- }
+ if (report_acls(fnamecmp, file, sxp))
+ iflags |= ITEM_REPORT_ACL;
#endif
#ifdef SUPPORT_XATTRS
- if (preserve_xattrs) {
- if (!XATTR_READY(*sxp))
- get_xattr(fnamecmp, sxp);
- if (xattr_diff(file, sxp, 1))
- iflags |= ITEM_REPORT_XATTR;
- }
+ if (report_xattrs(fnamecmp, file, sxp, True))
+ iflags |= ITEM_REPORT_XATTR;
#endif
} else {
#ifdef SUPPORT_XATTRS
- if (preserve_xattrs && xattr_diff(file, NULL, 1))
+ if (preserve_xattrs && xattr_diff(file, NULL, True))
iflags |= ITEM_REPORT_XATTR;
#endif
iflags |= ITEM_IS_NEW;
#ifdef SUPPORT_XATTRS
if (preserve_xattrs && do_xfers
&& iflags & (ITEM_REPORT_XATTR|ITEM_TRANSFER)) {
- send_xattr_request(NULL, file,
- iflags & ITEM_REPORT_XATTR ? sock_f_out : -1);
+ int fd = iflags & ITEM_REPORT_XATTR
+ && (protocol_version < 31 || !BITS_SET(iflags, ITEM_XNAME_FOLLOWS|ITEM_LOCAL_CHANGE))
+ ? sock_f_out : -1;
+ send_xattr_request(NULL, file, fd);
}
#endif
} else if (ndx >= 0) {
handle_skipped_hlink(file, itemizing, code, f_out);
#endif
rprintf(FERROR_XFER,
- "skipping daemon-excluded %s \"%s\"\n",
+ "ERROR: daemon refused to receive %s \"%s\"\n",
is_dir ? "directory" : "file", fname);
if (is_dir)
goto skipping_dir_contents;
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;
}
}
+
#ifdef SUPPORT_XATTRS
if (preserve_xattrs && statret == 1)
copy_xattrs(fnamecmpbuf, fname);