Patch to not modify files in place unless "--inplace" option specified

Carl E. Thompson lists-rsync at carlthompson.net
Thu May 8 01:25:36 GMT 2008


Skipped content of type multipart/alternative-------------- next part --------------
diff -urN rsync-3.0.2-orig/generator.c rsync-3.0.2/generator.c
--- rsync-3.0.2-orig/generator.c	2008-03-28 10:30:11.000000000 -0700
+++ rsync-3.0.2/generator.c	2008-05-07 15:35:08.317364774 -0700
@@ -1508,6 +1508,7 @@
 
 	if (preserve_links && S_ISLNK(file->mode)) {
 #ifdef SUPPORT_LINKS
+		int iflags = 0;
 		const char *sl = F_SYMLINK(file);
 		if (safe_symlinks && unsafe_symlink(sl, fname)) {
 			if (verbose) {
@@ -1528,7 +1529,15 @@
 			else if ((len = readlink(fname, lnk, MAXPATHLEN-1)) > 0
 			      && strncmp(lnk, sl, len) == 0 && sl[len] == '\0') {
 				/* The link is pointing to the right place. */
-				set_file_attrs(fname, file, &sx, NULL, maybe_ATTRS_REPORT);
+				if (inplace) {
+					if (verbose > 2)
+						rprintf(FINFO, "possibly tweaking attributes of %s\n", fname);
+					set_file_attrs(fname, file, &sx, NULL, maybe_ATTRS_REPORT);
+				} else if (!unchanged_attrs(fname, file, &sx)) {
+					if (verbose > 2)
+						rprintf(FINFO, "recreating %s due to changed attributes\n", fname);
+					goto recreate_symlink;
+				}
 				if (itemizing)
 					itemize(fname, file, ndx, 0, &sx, 0, 0, NULL);
 #if defined SUPPORT_HARD_LINKS && defined CAN_HARDLINK_SYMLINK
@@ -1538,7 +1547,9 @@
 				if (remove_source_files == 1)
 					goto return_with_success;
 				goto cleanup;
-			}
+			} else
+				iflags = ITEM_REPORT_CHANGE;
+		recreate_symlink:
 			/* Not the right symlink (or not a symlink), so
 			 * delete it. */
 			if (delete_item(fname, sx.st.st_mode, del_opts | DEL_FOR_SYMLINK) != 0)
@@ -1572,18 +1583,20 @@
 			set_file_attrs(fname, file, NULL, NULL, 0);
 			if (itemizing) {
 				itemize(fname, file, ndx, statret, &sx,
-					ITEM_LOCAL_CHANGE|ITEM_REPORT_CHANGE, 0, NULL);
+					ITEM_LOCAL_CHANGE|iflags, 0, NULL);
 			}
-			if (code != FNONE && verbose)
+			if ((iflags & ITEM_REPORT_CHANGE) && code != FNONE && verbose)
 				rprintf(code, "%s -> %s\n", fname, sl);
 #ifdef SUPPORT_HARD_LINKS
 			if (preserve_hard_links && F_IS_HLINKED(file))
 				finish_hard_link(file, fname, ndx, NULL, itemizing, code, -1);
 #endif
-			/* This does not check remove_source_files == 1
-			 * because this is one of the items that the old
-			 * --remove-sent-files option would remove. */
-			if (remove_source_files)
+			/* When the symlink value changed, we do not check
+			 * remove_source_files == 1 because this is one of the
+			 * items that the old --remove-sent-files option would
+			 * remove. */
+			if ((iflags & ITEM_REPORT_CHANGE) ? remove_source_files
+				: remove_source_files == 1)
 				goto return_with_success;
 		}
 #endif
@@ -1592,6 +1605,7 @@
 
 	if ((am_root && preserve_devices && IS_DEVICE(file->mode))
 	 || (preserve_specials && IS_SPECIAL(file->mode))) {
+		int iflags = 0;
 		uint32 *devp = F_RDEV_P(file);
 		dev_t rdev = MAKEDEV(DEV_MAJOR(devp), DEV_MINOR(devp));
 		if (statret == 0) {
@@ -1609,7 +1623,15 @@
 			 && BITS_EQUAL(sx.st.st_mode, file->mode, _S_IFMT)
 			 && sx.st.st_rdev == rdev) {
 				/* The device or special file is identical. */
-				set_file_attrs(fname, file, &sx, NULL, maybe_ATTRS_REPORT);
+				if (inplace) {
+					if (verbose > 2)
+						rprintf(FINFO, "possibly tweaking attributes of %s\n", fname);
+					set_file_attrs(fname, file, &sx, NULL, maybe_ATTRS_REPORT);
+				} else if (!unchanged_attrs(fname, file, &sx)) {
+					if (verbose > 2)
+						rprintf(FINFO, "recreating %s due to changed attributes\n", fname);
+					goto recreate_D;
+				}
 				if (itemizing)
 					itemize(fname, file, ndx, 0, &sx, 0, 0, NULL);
 #ifdef SUPPORT_HARD_LINKS
@@ -1619,7 +1641,9 @@
 				if (remove_source_files == 1)
 					goto return_with_success;
 				goto cleanup;
-			}
+			} else
+				iflags = ITEM_REPORT_CHANGE;
+		recreate_D:
 			if (delete_item(fname, sx.st.st_mode, del_opts | del_for_flag) != 0)
 				goto cleanup;
 		} else if (basis_dir[0] != NULL) {
@@ -1656,9 +1680,9 @@
 			set_file_attrs(fname, file, NULL, NULL, 0);
 			if (itemizing) {
 				itemize(fname, file, ndx, statret, &sx,
-					ITEM_LOCAL_CHANGE|ITEM_REPORT_CHANGE, 0, NULL);
+					ITEM_LOCAL_CHANGE|iflags, 0, NULL);
 			}
-			if (code != FNONE && verbose)
+			if ((iflags & ITEM_REPORT_CHANGE) && code != FNONE && verbose)
 				rprintf(code, "%s\n", fname);
 #ifdef SUPPORT_HARD_LINKS
 			if (preserve_hard_links && F_IS_HLINKED(file))
@@ -1776,13 +1800,31 @@
 	else if (fnamecmp_type == FNAMECMP_FUZZY)
 		;
 	else if (unchanged_file(fnamecmp, file, &sx.st)) {
+		/* fnamecmp == fname, fnamecmp_type == FNAMECMP_FNAME */
+		int iflags = 0;
+
 		if (partialptr) {
 			do_unlink(partialptr);
 			handle_partial_dir(partialptr, PDIR_DELETE);
 		}
-		set_file_attrs(fname, file, &sx, NULL, maybe_ATTRS_REPORT);
+		if (inplace) {
+			/* Currently, we call set_file_attrs on all tweakable
+			 * files, though ideally it would have no effect when
+			 * unchanged_attrs returns true. */
+			if (verbose > 2)
+				rprintf(FINFO, "possibly tweaking attributes of %s\n", fname);
+			set_file_attrs(fname, file, &sx, NULL, maybe_ATTRS_REPORT);
+		} else if (!unchanged_attrs(fname, file, &sx)) {
+			/* Need to recreate the file.
+			 * copy_altdest_file sets its attributes, etc. */
+			if (verbose > 2)
+				rprintf(FINFO, "recreating %s due to changed attributes\n", fname);
+			if (!dry_run && copy_altdest_file(fnamecmp, fname, file))
+				goto cleanup;
+			iflags |= ITEM_LOCAL_CHANGE;
+		}
 		if (itemizing)
-			itemize(fnamecmp, file, ndx, statret, &sx, 0, 0, NULL);
+			itemize(fnamecmp, file, ndx, statret, &sx, iflags, 0, NULL);
 #ifdef SUPPORT_HARD_LINKS
 		if (preserve_hard_links && F_IS_HLINKED(file))
 			finish_hard_link(file, fname, ndx, &sx.st, itemizing, code, -1);


More information about the rsync mailing list