X-Git-Url: https://mattmccutchen.net/rsync/rsync.git/blobdiff_plain/69be312b5e335430e3e896e200def6a7c6f89c8d..ddc5ae3d9e6cc632b93bac327b6f92d0545b0537:/generator.c diff --git a/generator.c b/generator.c index f2c4233e..d5dc85f5 100644 --- a/generator.c +++ b/generator.c @@ -276,7 +276,6 @@ static void delete_in_dir(char *fbuf, struct file_struct *file, dev_t *fs_dev) 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); @@ -289,7 +288,7 @@ static void delete_in_dir(char *fbuf, struct file_struct *file, dev_t *fs_dev) 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, @@ -308,9 +307,6 @@ static void delete_in_dir(char *fbuf, struct file_struct *file, dev_t *fs_dev) 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 @@ -330,7 +326,7 @@ static void delete_in_dir(char *fbuf, struct file_struct *file, dev_t *fs_dev) * 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) { @@ -342,11 +338,6 @@ static void delete_in_dir(char *fbuf, struct file_struct *file, dev_t *fs_dev) } 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 @@ -386,13 +377,30 @@ static void do_delete_pass(void) 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); @@ -402,20 +410,34 @@ static inline int perms_differ(struct file_struct *file, stat_x *sxp) 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); @@ -428,12 +450,18 @@ static inline int acls_differ(const char *fname, struct file_struct *file, stat_ #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; } @@ -443,45 +471,17 @@ static inline int xattrs_differ(const char *fname, struct file_struct *file, sta 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, @@ -489,56 +489,33 @@ void itemize(const char *fnamecmp, struct file_struct *file, int ndx, int statre 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; @@ -558,8 +535,10 @@ void itemize(const char *fnamecmp, struct file_struct *file, int ndx, int statre #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) { @@ -1185,7 +1164,7 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx, 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; @@ -1360,6 +1339,7 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx, goto cleanup; } } + #ifdef SUPPORT_XATTRS if (preserve_xattrs && statret == 1) copy_xattrs(fnamecmpbuf, fname);