X-Git-Url: https://mattmccutchen.net/rsync/rsync.git/blobdiff_plain/c4c9bb944bf6d1e17b8884a41a932db26528372e..ddaef70cede8b8ed24b084b93208a2353745b1bd:/generator.c diff --git a/generator.c b/generator.c index 4ebc5e55..909c0f4d 100644 --- a/generator.c +++ b/generator.c @@ -4,7 +4,7 @@ * Copyright (C) 1996-2000 Andrew Tridgell * Copyright (C) 1996 Paul Mackerras * Copyright (C) 2002 Martin Pool - * Copyright (C) 2003-2007 Wayne Davison + * Copyright (C) 2003-2008 Wayne Davison * * 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 @@ -27,7 +27,6 @@ extern int dry_run; extern int do_xfers; extern int stdout_format_has_i; extern int logfile_format_has_i; -extern int receiver_symlink_times; extern int am_root; extern int am_server; extern int am_daemon; @@ -111,6 +110,7 @@ static char *deldelay_buf = NULL; static int deldelay_fd = -1; static int lull_mod; static int dir_tweaking; +static int symlink_timeset_failed_flags; static int need_retouch_dir_times; static int need_retouch_dir_perms; static const char *solo_file = NULL; @@ -582,10 +582,11 @@ int unchanged_attrs(const char *fname, struct file_struct *file, stat_x *sxp) if (preserve_times && cmp_time(sxp->st.st_mtime, file->modtime) != 0) return 0; - if (preserve_perms && !BITS_EQUAL(sxp->st.st_mode, file->mode, CHMOD_BITS)) - return 0; - - if (preserve_executability && ((sxp->st.st_mode & 0111 ? 1 : 0) ^ (file->mode & 0111 ? 1 : 0))) + 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; if (am_root && uid_ndx && sxp->st.st_uid != (uid_t)F_OWNER(file)) @@ -622,24 +623,31 @@ void itemize(const char *fnamecmp, struct file_struct *file, int ndx, int statre int keep_time = !preserve_times ? 0 : S_ISDIR(file->mode) ? preserve_times > 1 : #if defined HAVE_LUTIMES && defined HAVE_UTIMES - (receiver_symlink_times && !(file->flags & FLAG_TIME_FAILED)) || -#endif + 1; +#else !S_ISLNK(file->mode); +#endif if (S_ISREG(file->mode) && F_LENGTH(file) != sxp->st.st_size) iflags |= ITEM_REPORT_SIZE; - if ((iflags & (ITEM_TRANSFER|ITEM_LOCAL_CHANGE) && !keep_time - && !(iflags & ITEM_MATCHED) + if (file->flags & FLAG_TIME_FAILED) { /* symlinks only */ + if (iflags & ITEM_LOCAL_CHANGE) + iflags |= symlink_timeset_failed_flags; + } else if (keep_time + ? cmp_time(file->modtime, sxp->st.st_mtime) != 0 + : iflags & (ITEM_TRANSFER|ITEM_LOCAL_CHANGE) && !(iflags & ITEM_MATCHED) && (!(iflags & ITEM_XNAME_FOLLOWS) || *xname)) - || (keep_time && cmp_time(file->modtime, sxp->st.st_mtime) != 0)) iflags |= ITEM_REPORT_TIME; #if !defined HAVE_LCHMOD && !defined HAVE_SETATTRLIST if (S_ISLNK(file->mode)) { ; } else #endif - if ((preserve_perms || preserve_executability) - && !BITS_EQUAL(sxp->st.st_mode, file->mode, CHMOD_BITS)) + 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))) iflags |= ITEM_REPORT_PERMS; if (uid_ndx && am_root && (uid_t)F_OWNER(file) != sxp->st.st_uid) iflags |= ITEM_REPORT_OWNER; @@ -1155,8 +1163,7 @@ static int try_dests_non(struct file_struct *file, char *fname, int ndx, if (itemizing && stdout_format_has_i && (verbose > 1 || stdout_format_has_i > 1)) { int chg = 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; itemize(cmpbuf, file, ndx, 0, sxp, chg + ITEM_MATCHED, 0, lp); } @@ -1351,6 +1358,13 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx, && !am_root && sx.st.st_uid == our_uid) del_opts |= DEL_NO_UID_WRITE; + if (ignore_existing > 0 && statret == 0 + && (!is_dir || !S_ISDIR(sx.st.st_mode))) { + if (verbose > 1 && is_dir >= 0) + rprintf(FINFO, "%s exists\n", fname); + goto cleanup; + } + if (is_dir) { if (!implied_dirs && file->flags & FLAG_IMPLIED_DIR) goto cleanup; @@ -1534,7 +1548,7 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx, set_file_attrs(fname, file, NULL, NULL, 0); if (itemizing) { itemize(fname, file, ndx, statret, &sx, - ITEM_LOCAL_CHANGE, 0, NULL); + ITEM_LOCAL_CHANGE|ITEM_REPORT_CHANGE, 0, NULL); } if (code != FNONE && verbose) rprintf(code, "%s -> %s\n", fname, sl); @@ -1618,7 +1632,7 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx, set_file_attrs(fname, file, NULL, NULL, 0); if (itemizing) { itemize(fname, file, ndx, statret, &sx, - ITEM_LOCAL_CHANGE, 0, NULL); + ITEM_LOCAL_CHANGE|ITEM_REPORT_CHANGE, 0, NULL); } if (code != FNONE && verbose) rprintf(code, "%s\n", fname); @@ -1656,12 +1670,6 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx, goto cleanup; } - if (ignore_existing > 0 && statret == 0) { - if (verbose > 1) - rprintf(FINFO, "%s exists\n", fname); - goto cleanup; - } - if (update_only > 0 && statret == 0 && cmp_time(sx.st.st_mtime, file->modtime) > 0) { if (verbose > 1) @@ -1849,7 +1857,7 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx, rprintf(FINFO, "generating and sending sums for %d\n", ndx); notify_others: - if (remove_source_files && !delay_updates && !phase) + if (remove_source_files && !delay_updates && !phase && !dry_run) increment_active_files(ndx, itemizing, code); if (inc_recurse && !dry_run) cur_flist->in_progress++; @@ -1861,7 +1869,7 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx, if (itemizing) { int iflags = ITEM_TRANSFER; if (always_checksum > 0) - iflags |= ITEM_REPORT_CHECKSUM; + iflags |= ITEM_REPORT_CHANGE; if (fnamecmp_type != FNAMECMP_FNAME) iflags |= ITEM_BASIS_TYPE_FOLLOWS; if (fnamecmp_type == FNAMECMP_FUZZY) @@ -1949,8 +1957,12 @@ static void touch_up_dirs(struct file_list *flist, int ndx) fname = f_name(file, NULL); if (!(file->mode & S_IWUSR)) do_chmod(fname, file->mode); - if (need_retouch_dir_times) - set_modtime(fname, file->modtime, file->mode); + if (need_retouch_dir_times) { + STRUCT_STAT st; + if (link_stat(fname, &st, 0) == 0 + && cmp_time(st.st_mtime, file->modtime) != 0) + set_modtime(fname, file->modtime, file->mode); + } if (allowed_lull && !(counter % lull_mod)) maybe_send_keepalive(); else if (!(counter & 0xFF)) @@ -2068,6 +2080,8 @@ void generate_files(int f_out, const char *local_name) dir_tweaking = !(list_only || solo_file || dry_run); need_retouch_dir_times = preserve_times > 1; lull_mod = allowed_lull * 5; + symlink_timeset_failed_flags = ITEM_REPORT_TIME + | (protocol_version >= 30 || !am_server ? ITEM_REPORT_TIMEFAIL : 0); if (verbose > 2) rprintf(FINFO, "generator starting pid=%ld\n", (long)getpid());