X-Git-Url: https://mattmccutchen.net/rsync/rsync.git/blobdiff_plain/e60c8b59fed2ef52bc6ea635e5f74979bc5b0570..743348e848915aa1217d970bd5673364345174e0:/generator.c diff --git a/generator.c b/generator.c index c0bffb2e..61a23059 100644 --- a/generator.c +++ b/generator.c @@ -388,46 +388,101 @@ static void do_delete_pass(void) 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; } @@ -437,12 +492,9 @@ void itemize(const char *fnamecmp, struct file_struct *file, int ndx, int statre { 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; @@ -567,6 +619,12 @@ static void sum_sizes_sqroot(struct sum_struct *sum, int64 len) 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) @@ -1032,7 +1090,7 @@ static void list_file_entry(struct file_struct *f) #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 @@ -1043,7 +1101,7 @@ static void list_file_entry(struct file_struct *f) 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)); } } @@ -1354,10 +1412,11 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx, 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); @@ -2049,7 +2108,7 @@ void generate_files(int f_out, const char *local_name) } 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);