A simpler move-files patch

Wayne Davison wayned at users.sourceforge.net
Sat May 4 12:47:01 EST 2002


In an effort to get my long-desired move-files functionality into rsync,
I have created a version of my patch that runs as an extra pass at the
end of the processing.  This results in a simpler set of changes to
rsync.

I still think it would be nice to have incremental deletions during
large transfers (as my first patch provides), but acceptance of this
patch would relegate such quibbling to a discussion of future
optimizations.

One thing that this patch does differently than my last one is this:
it removes all synchronized files from the server, even ones that were
already up-to-date.  (I had been meaning to make my previous patch also
include up-to-date files, but hadn't gotten around to it before this.)
As before, directories are not affected.

This patch is for CVS, but the offsets assume that my last patch to
rsync.yo has already been applied.

Let me know what you think.

..wayne..

---8<------8<------8<------8<---cut here--->8------>8------>8------>8---
Index: options.c
--- save/options.c	Sat May  4 11:22:22 2002
+++ options.c	Sat May  4 11:27:17 2002
@@ -86,6 +86,7 @@
 int modify_window=0;
 #endif
 int blocking_io=-1;
+int move_files=0;
 
 
 /** Network address family. **/
@@ -240,6 +241,7 @@
   rprintf(F,"     --delete-after          delete after transferring, not before\n");
   rprintf(F,"     --ignore-errors         delete even if there are IO errors\n");
   rprintf(F,"     --max-delete=NUM        don't delete more than NUM files\n");
+  rprintf(F,"     --move-files            remove the synchronized files from the sending side\n");
   rprintf(F,"     --partial               keep partially transferred files\n");
   rprintf(F,"     --force                 force deletion of directories even if not empty\n");
   rprintf(F,"     --numeric-ids           don't map uid/gid values by user/group name\n");
@@ -290,7 +292,7 @@
       OPT_LOG_FORMAT, OPT_PASSWORD_FILE, OPT_SIZE_ONLY, OPT_ADDRESS,
       OPT_DELETE_AFTER, OPT_EXISTING, OPT_MAX_DELETE, OPT_BACKUP_DIR, 
       OPT_IGNORE_ERRORS, OPT_BWLIMIT, OPT_BLOCKING_IO,
-      OPT_NO_BLOCKING_IO, OPT_WHOLE_FILE, OPT_NO_WHOLE_FILE,
+      OPT_NO_BLOCKING_IO, OPT_WHOLE_FILE, OPT_NO_WHOLE_FILE, OPT_MOVE_FILES,
       OPT_MODIFY_WINDOW, OPT_READ_BATCH, OPT_WRITE_BATCH, OPT_IGNORE_EXISTING};
 
 static struct poptOption long_options[] = {
@@ -365,6 +367,7 @@
   {"hard-links",      'H', POPT_ARG_NONE,   &preserve_hard_links , 0, 0, 0 },
   {"read-batch",       0,  POPT_ARG_STRING, &batch_prefix, OPT_READ_BATCH, 0, 0 },
   {"write-batch",      0,  POPT_ARG_STRING, &batch_prefix, OPT_WRITE_BATCH, 0, 0 },
+  {"move-files",       0,  POPT_ARG_NONE,   &move_files, 0, 0, 0 },
 #ifdef INET6
   {0,		      '4', POPT_ARG_VAL,    &default_af_hint,   AF_INET , 0, 0 },
   {0,		      '6', POPT_ARG_VAL,    &default_af_hint,   AF_INET6 , 0, 0 },
@@ -813,6 +816,9 @@
 		args[ac++] = "--compare-dest";
 		args[ac++] = compare_dest;
 	}
+
+	if (move_files)
+		args[ac++] = "--move-files";
 
 	*argc = ac;
 }
Index: rsync.h
--- rsync.h	2002/04/11 02:18:51	1.131
+++ rsync.h	2002/05/04 19:20:29
@@ -47,6 +47,7 @@
 #define SAME_NAME SAME_DIR
 #define LONG_NAME (1<<6)
 #define SAME_TIME (1<<7)
+#define FLAG_NO_DELETE (1<<8)
 
 /* update this if you make incompatible changes */
 #define PROTOCOL_VERSION 26
Index: rsync.yo
--- save/rsync.yo	Fri May  3 16:35:18 2002
+++ rsync.yo	Sat May  4 11:53:41 2002
@@ -254,6 +254,7 @@
      --delete-after          delete after transferring, not before
      --ignore-errors         delete even if there are IO errors
      --max-delete=NUM        don't delete more than NUM files
+     --move-files            remove the synchronized files from the sending side
      --partial               keep partially transferred files
      --force                 force deletion of directories even if not empty
      --numeric-ids           don't map uid/gid values by user/group name
@@ -496,6 +497,10 @@
 
 dit(bf(--ignore-errors)) Tells --delete to go ahead and delete files
 even when there are IO errors.
+
+dit(bf(--move-files)) This tells rsync to remove the source files on the
+sending side that are either successfully transferred to the receiving
+side or are already up-to-date (directories are not removed).
 
 dit(bf(--force)) This options tells rsync to delete directories even if
 they are not empty when they are to be replaced by non-directories.  This
Index: sender.c
--- sender.c	2002/04/09 06:03:50	1.17
+++ sender.c	2002/05/04 19:20:29
@@ -26,6 +26,7 @@
 extern int io_error;
 extern int dry_run;
 extern int am_server;
+extern int move_files;
 
 
 /**
@@ -184,6 +185,7 @@
 				rprintf(FERROR,"send_files failed to open %s: %s\n",
 					fname,strerror(errno));
 				free_sums(s);
+				file->flags |= FLAG_NO_DELETE;
 				continue;
 			}
 	  
@@ -265,6 +267,7 @@
                       rprintf (FINFO,"readbatch & checksums don't match\n");
                       rprintf (FINFO,"filename=%s is being skipped\n",
 			       fname);
+		      file->flags |= FLAG_NO_DELETE;
                       continue;
                    }
                 } else  {
@@ -281,6 +284,28 @@
 	  
 		if (verbose > 2)
 			rprintf(FINFO,"sender finished %s\n",fname);
+	}
+
+	if (move_files && !dry_run) {
+		for (i = 0; i < flist->count; i++) {
+			file = flist->files[i];
+			if (S_ISDIR(file->mode) || file->flags & FLAG_NO_DELETE)
+				continue;
+			fname[0] = 0;
+			if (file->basedir) {
+				strlcpy(fname,file->basedir,MAXPATHLEN);
+				if (strlen(fname) == MAXPATHLEN-1) {
+					io_error = 1;
+					rprintf(FERROR, "send_files failed on long-named directory %s\n",
+						fname);
+					return;
+				}
+				strlcat(fname,"/",MAXPATHLEN);
+			}
+			strlcat(fname,f_name(file),MAXPATHLEN);
+			if (do_unlink(fname) == 0 && verbose > 1)
+				rprintf(FINFO,"sender removed %s\n",fname);
+		}
 	}
 
 	if (verbose > 2)
---8<------8<------8<------8<---cut here--->8------>8------>8------>8---





More information about the rsync mailing list