Applied to the turnk (with a few tweaks).
authorWayne Davison <wayned@samba.org>
Mon, 24 Jan 2005 01:42:23 +0000 (01:42 +0000)
committerWayne Davison <wayned@samba.org>
Mon, 24 Jan 2005 01:42:23 +0000 (01:42 +0000)
delete-during.diff [deleted file]

diff --git a/delete-during.diff b/delete-during.diff
deleted file mode 100644 (file)
index c9ec188..0000000
+++ /dev/null
@@ -1,475 +0,0 @@
-This patch creates a --delete-during functionality that deletes files on
-the receiving side incrementally as we traverse the directories.  It also
-defines a --delete-before option, for the traditional way that --delete
-has worked before.
-
-This patch chooses to make --delete into a synonym for --delete-during, and
-hide --delete-during, but that can be easily changed if we want to preserve
-the old functionality (and indeed, the support for popt aliases that is now
-in CVS will let the user easily choose which method they'd like --delete to
-invoke, either personally or site-wide, without having to recompile rsync).
-
-Be sure to run "make proto" before "make".
-
---- orig/flist.c       2005-01-24 00:18:21
-+++ flist.c    2005-01-23 08:02:39
-@@ -35,6 +35,7 @@ extern int am_root;
- extern int am_server;
- extern int am_daemon;
- extern int am_sender;
-+extern int delete_during;
- extern int always_checksum;
- extern int module_id;
- extern int ignore_errors;
-@@ -45,6 +46,8 @@ extern int cvs_exclude;
- extern int recurse;
- extern int xfer_dirs;
- extern char curr_dir[MAXPATHLEN];
-+extern char *backup_dir;
-+extern char *backup_suffix;
- extern int filesfrom_fd;
- extern int one_file_system;
-@@ -57,11 +60,14 @@ extern int preserve_uid;
- extern int preserve_gid;
- extern int relative_paths;
- extern int implied_dirs;
-+extern int make_backups;
-+extern int backup_suffix_len;
- extern int copy_links;
- extern int copy_unsafe_links;
- extern int protocol_version;
- extern int sanitize_paths;
- extern int delete_excluded;
-+extern int max_delete;
- extern int orig_umask;
- extern int list_only;
-@@ -534,6 +540,8 @@ void receive_file_entry(struct file_stru
-       static gid_t gid;
-       static char lastname[MAXPATHLEN], *lastdir;
-       static int lastdir_depth, lastdir_len = -1;
-+      static unsigned int del_heir_name_len = -1;
-+      static int in_del_hier = 0;
-       char thisname[MAXPATHLEN];
-       unsigned int l1 = 0, l2 = 0;
-       int alloc_len, basename_len, dirname_len, linkname_len, sum_len;
-@@ -547,7 +555,8 @@ void receive_file_entry(struct file_stru
-               rdev_major = 0;
-               uid = 0, gid = 0;
-               *lastname = '\0';
--              lastdir_len = -1;
-+              del_heir_name_len = lastdir_len = -1;
-+              in_del_hier = 0;
-               return;
-       }
-@@ -645,13 +654,27 @@ void receive_file_entry(struct file_stru
-       memset(bp, 0, file_struct_len);
-       bp += file_struct_len;
--      file->flags = flags & XMIT_DEL_START ? FLAG_DEL_START : 0;
-+      file->flags = 0;
-       file->modtime = modtime;
-       file->length = file_length;
-       file->mode = mode;
-       file->uid = uid;
-       file->gid = gid;
-+      if (S_ISDIR(mode)) {
-+              if (flags & XMIT_DEL_START) {
-+                      in_del_hier = 1;
-+                      del_heir_name_len = l1 + l2;
-+                      file->flags |= FLAG_DEL_START;
-+              } else if (delete_during && in_del_hier) {
-+                      if (!relative_paths || (l1 >= del_heir_name_len
-+                          && thisname[del_heir_name_len] == '/'))
-+                              file->flags |= FLAG_DEL_START;
-+                      else
-+                              in_del_hier = 0;
-+              }
-+      }
-+
-       if (dirname_len) {
-               file->dirname = lastdir = bp;
-               lastdir_len = dirname_len - 1;
-@@ -1064,14 +1087,13 @@ static void send_directory(int f, struct
- }
--/**
-- * This function is normally called by the sender, but the receiver also
-- * uses it to construct its own file list if --delete has been specified.
-- * The delete_files() function in receiver.c sets f to -1 so that we just
-- * construct the file list in memory without sending it over the wire.  It
-- * also has the side-effect of ignoring user-excludes if delete_excluded
-- * is set (so that the delete list includes user-excluded files).
-- **/
-+/* This function is normally called by the sender, but the receiving side
-+ * also uses it to construct one or more file lists if one of the --delete
-+ * options have been specified.  The delete_in_dir() function sets f to -1
-+ * so that we just construct the file list in memory without sending it
-+ * over the wire.  It also has the side-effect of ignoring user-excludes if
-+ * delete_excluded is set (so that the delete list includes user-excluded
-+ * files). */
- struct file_list *send_file_list(int f, int argc, char *argv[])
- {
-       int l;
-@@ -1129,7 +1151,9 @@ struct file_list *send_file_list(int f, 
-                               fname[l] = '\0';
-                       }
-               }
--              if (fname[l-1] == '.' && (l == 1 || fname[l-2] == '/')) {
-+              if (f == -1 && delete_during)
-+                      ; /* recurse is pre-set */
-+              else if (fname[l-1] == '.' && (l == 1 || fname[l-2] == '/')) {
-                       if (!recurse && xfer_dirs)
-                               recurse = 1; /* allow one level */
-               } else if (recurse > 0)
-@@ -1644,3 +1668,77 @@ char *f_name(struct file_struct *f)
-       return f_name_to(f, names[n]);
- }
-+
-+static int is_backup_file(char *fn)
-+{
-+      int k = strlen(fn) - backup_suffix_len;
-+      return k > 0 && strcmp(fn+k, backup_suffix) == 0;
-+}
-+
-+void delete_in_dir(struct file_list *flist, char *fname)
-+{
-+      static int deletion_count = 0;
-+      struct file_list *del_flist;
-+      int save_recurse = recurse;
-+      int save_xfer_dirs = xfer_dirs;
-+      int save_implied_dirs = implied_dirs;
-+      int save_relative_paths = relative_paths;
-+      char *argv[1];
-+      int i, j, mode;
-+
-+      if (max_delete && deletion_count >= max_delete)
-+              return;
-+
-+      if (io_error && !(lp_ignore_errors(module_id) || ignore_errors)) {
-+              rprintf(FINFO, "IO error encountered - skipping file deletion\n");
-+              max_delete = -1; /* avoid duplicating the above warning */
-+              return;
-+      }
-+
-+      if (delete_during) {
-+              recurse = 1; /* allow one level only */
-+              xfer_dirs = 1;
-+              implied_dirs = 0;
-+              relative_paths = 1;
-+      }
-+
-+      argv[0] = fname;
-+      del_flist = send_file_list(-1, 1, argv);
-+
-+      relative_paths = save_relative_paths;
-+      implied_dirs = save_implied_dirs;
-+      xfer_dirs = save_xfer_dirs;
-+      recurse = save_recurse;
-+
-+      if (!del_flist)
-+              return;
-+
-+      if (verbose > 1)
-+              rprintf(FINFO, "deleting in %s\n", safe_fname(fname));
-+
-+      for (i = del_flist->count-1; i >= 0; i--) {
-+              if (max_delete && deletion_count >= max_delete)
-+                      break;
-+              if (!del_flist->files[i]->basename)
-+                      continue;
-+              mode = del_flist->files[i]->mode;
-+              if ((j = flist_find(flist, del_flist->files[i])) < 0
-+                  || (delete_during && S_ISDIR(mode)
-+                   && !S_ISDIR(flist->files[j]->mode))) {
-+                      char *f = f_name(del_flist->files[i]);
-+                      if (make_backups && (backup_dir || !is_backup_file(f))
-+                        && !S_ISDIR(mode)) {
-+                              make_backup(f);
-+                              if (verbose) {
-+                                      rprintf(FINFO, "deleting %s\n",
-+                                              safe_fname(f));
-+                              }
-+                      } else {
-+                              delete_file(f, S_ISDIR(mode)
-+                                              ? DEL_DIR | DEL_RECURSE : 0);
-+                      }
-+                      deletion_count++;
-+              }
-+      }
-+      flist_free(del_flist);
-+}
---- orig/generator.c   2005-01-20 23:05:34
-+++ generator.c        2005-01-23 07:55:40
-@@ -34,6 +34,7 @@ extern int preserve_hard_links;
- extern int preserve_perms;
- extern int preserve_uid;
- extern int preserve_gid;
-+extern int delete_during;
- extern int update_only;
- extern int opt_ignore_existing;
- extern int inplace;
-@@ -233,7 +234,8 @@ static void generate_and_send_sums(int f
-  * @note This comment was added later by mbp who was trying to work it
-  * out.  It might be wrong.
-  */
--static void recv_generator(char *fname, struct file_struct *file, int i,
-+static void recv_generator(char *fname, struct file_list *flist,
-+                         struct file_struct *file, int i,
-                          int f_out, int f_out_name)
- {
-       int fd = -1, f_copy = -1;
-@@ -308,6 +310,11 @@ static void recv_generator(char *fname, 
-               }
-               /* f_out is set to -1 when doing final directory-permission
-                * and modification-time repair. */
-+              if (delete_during && f_out != -1
-+                  && (file->flags & FLAG_DEL_START)) {
-+                      delete_in_dir(flist, fname);
-+                      statret = 1;
-+              }
-               if (set_perms(fname, file, statret ? NULL : &st, 0)
-                   && verbose && f_out != -1)
-                       rprintf(FINFO, "%s/\n", safe_fname(fname));
-@@ -641,7 +648,7 @@ void generate_files(int f_out, struct fi
-               }
-               recv_generator(local_name ? local_name : f_name_to(file, fbuf),
--                             file, i, f_out, f_out_name);
-+                             flist, file, i, f_out, f_out_name);
-       }
-       phase++;
-@@ -658,7 +665,7 @@ void generate_files(int f_out, struct fi
-       while ((i = get_redo_num()) != -1) {
-               struct file_struct *file = flist->files[i];
-               recv_generator(local_name ? local_name : f_name_to(file, fbuf),
--                             file, i, f_out, f_out_name);
-+                             flist, file, i, f_out, f_out_name);
-       }
-       phase++;
-@@ -680,7 +687,7 @@ void generate_files(int f_out, struct fi
-               if (!file->basename || !S_ISDIR(file->mode))
-                       continue;
-               recv_generator(local_name ? local_name : f_name(file),
--                             file, i, -1, -1);
-+                             flist, file, i, -1, -1);
-       }
-       if (verbose > 2)
---- orig/main.c        2005-01-23 07:27:24
-+++ main.c     2005-01-23 01:48:52
-@@ -736,6 +736,8 @@ int client_run(int f_in, int f_out, pid_
-       if (!read_batch)
-               send_exclude_list(f_out);
-+      if (cvs_exclude)
-+              add_cvs_excludes();
-       if (filesfrom_fd >= 0) {
-               io_set_filesfrom_fds(filesfrom_fd, f_out);
---- orig/options.c     2005-01-24 00:18:21
-+++ options.c  2005-01-23 01:53:35
-@@ -54,6 +54,7 @@ int dry_run = 0;
- int local_server = 0;
- int ignore_times = 0;
- int delete_mode = 0;
-+int delete_during = 0;
- int delete_before = 0;
- int delete_after = 0;
- int delete_excluded = 0;
-@@ -274,7 +275,8 @@ void usage(enum logcode F)
-   rprintf(F,"     --existing              only update files that already exist\n");
-   rprintf(F,"     --ignore-existing       ignore files that already exist on receiving side\n");
-   rprintf(F,"     --delete                delete files that don't exist on the sending side\n");
--  rprintf(F,"     --delete-after          receiver deletes after transferring, not before\n");
-+  rprintf(F,"     --delete-before         receiver deletes before transfer, not during\n");
-+  rprintf(F,"     --delete-after          receiver deletes after transfer, not during\n");
-   rprintf(F,"     --delete-excluded       also delete excluded files on the receiving side\n");
-   rprintf(F,"     --ignore-errors         delete even if there are I/O errors\n");
-   rprintf(F,"     --force                 force deletion of directories even if not empty\n");
-@@ -341,7 +343,9 @@ static struct poptOption long_options[] 
-   {"one-file-system", 'x', POPT_ARG_NONE,   &one_file_system, 0, 0, 0 },
-   {"existing",         0,  POPT_ARG_NONE,   &only_existing, 0, 0, 0 },
-   {"ignore-existing",  0,  POPT_ARG_NONE,   &opt_ignore_existing, 0, 0, 0 },
--  {"delete",           0,  POPT_ARG_NONE,   &delete_before, 0, 0, 0 },
-+  {"delete",           0,  POPT_ARG_NONE,   &delete_during, 0, 0, 0 },
-+  {"delete-during",    0,  POPT_ARG_NONE,   &delete_during, 0, 0, 0 },
-+  {"delete-before",    0,  POPT_ARG_NONE,   &delete_before, 0, 0, 0 },
-   {"delete-after",     0,  POPT_ARG_NONE,   &delete_after, 0, 0, 0 },
-   {"delete-excluded",  0,  POPT_ARG_NONE,   &delete_excluded, 0, 0, 0 },
-   {"force",            0,  POPT_ARG_NONE,   &force_delete, 0, 0, 0 },
-@@ -854,10 +858,10 @@ int parse_arguments(int *argc, const cha
-       if (relative_paths < 0)
-               relative_paths = files_from? 1 : 0;
--      if (delete_before || delete_after)
-+      if (delete_during || delete_before || delete_after)
-               delete_mode = 1;
-       if (delete_excluded && !delete_mode)
--              delete_mode = delete_before = 1;
-+              delete_mode = delete_during = 1;
-       *argv = poptGetArgs(pc);
-       *argc = count_args(*argv);
-@@ -1160,7 +1164,9 @@ void server_options(char **args,int *arg
-       if (am_sender) {
-               if (delete_excluded)
-                       args[ac++] = "--delete-excluded";
--              else if (delete_before || delete_after)
-+              else if (delete_before)
-+                      args[ac++] = "--delete-before";
-+              else if (delete_during || delete_after)
-                       args[ac++] = "--delete";
-               if (delete_after)
---- orig/receiver.c    2005-01-23 07:27:24
-+++ receiver.c 2005-01-23 07:55:58
-@@ -23,7 +23,6 @@
- extern int verbose;
- extern int recurse;
- extern int delete_after;
--extern int max_delete;
- extern int csum_length;
- extern struct stats stats;
- extern int dry_run;
-@@ -35,7 +34,6 @@ extern int relative_paths;
- extern int keep_dirlinks;
- extern int preserve_hard_links;
- extern int preserve_perms;
--extern int cvs_exclude;
- extern int io_error;
- extern char *tmpdir;
- extern char *partial_dir;
-@@ -43,9 +41,6 @@ extern char *basis_dir[];
- extern int basis_dir_cnt;
- extern int make_backups;
- extern int do_progress;
--extern char *backup_dir;
--extern char *backup_suffix;
--extern int backup_suffix_len;
- extern int cleanup_got_literal;
- extern int module_id;
- extern int ignore_errors;
-@@ -57,66 +52,19 @@ extern int inplace;
- extern struct exclude_list_struct server_exclude_list;
--static int is_backup_file(char *fn)
--{
--      int k = strlen(fn) - backup_suffix_len;
--      return k > 0 && strcmp(fn+k, backup_suffix) == 0;
--}
--
--
--/* This deletes any files on the receiving side that are not present
-- * on the sending side. */
-+/* This deletes any files on the receiving side that are not present on the
-+ * sending side.  This is used by --delete-before and --delete-after. */
- void delete_files(struct file_list *flist)
- {
--      struct file_list *local_file_list;
--      int i, j;
--      char *argv[1], fbuf[MAXPATHLEN];
--      static int deletion_count;
--
--      if (cvs_exclude)
--              add_cvs_excludes();
--
--      if (io_error && !(lp_ignore_errors(module_id) || ignore_errors)) {
--              rprintf(FINFO,"IO error encountered - skipping file deletion\n");
--              return;
--      }
-+      char fbuf[MAXPATHLEN];
-+      int j;
-       for (j = 0; j < flist->count; j++) {
-               if (!(flist->files[j]->flags & FLAG_DEL_START)
-                   || !S_ISDIR(flist->files[j]->mode))
-                       continue;
--              argv[0] = f_name_to(flist->files[j], fbuf);
--
--              if (!(local_file_list = send_file_list(-1, 1, argv)))
--                      continue;
--
--              if (verbose > 1)
--                      rprintf(FINFO, "deleting in %s\n", safe_fname(fbuf));
--
--              for (i = local_file_list->count-1; i >= 0; i--) {
--                      if (max_delete && deletion_count >= max_delete)
--                              break;
--                      if (!local_file_list->files[i]->basename)
--                              continue;
--                      if (flist_find(flist,local_file_list->files[i]) < 0) {
--                              char *f = f_name(local_file_list->files[i]);
--                              int mode = local_file_list->files[i]->mode;
--                              if (make_backups && (backup_dir || !is_backup_file(f))
--                                && !S_ISDIR(mode)) {
--                                      make_backup(f);
--                                      if (verbose) {
--                                              rprintf(FINFO, "deleting %s\n",
--                                                      safe_fname(f));
--                                      }
--                              } else {
--                                      delete_file(f, S_ISDIR(mode)
--                                              ? DEL_DIR | DEL_RECURSE : 0);
--                              }
--                              deletion_count++;
--                      }
--              }
--              flist_free(local_file_list);
-+              delete_in_dir(flist, f_name_to(flist->files[j], fbuf));
-       }
- }
---- orig/rsync.yo      2005-01-24 00:18:21
-+++ rsync.yo   2005-01-23 02:57:49
-@@ -342,7 +342,8 @@ verb(
-      --existing              only update files that already exist
-      --ignore-existing       ignore files that already exist on receiver
-      --delete                delete files that don't exist on sender
--     --delete-after          receiver deletes after transfer, not before
-+     --delete-before         receiver deletes before xfer, not during
-+     --delete-after          receiver deletes after transfer, not during
-      --delete-excluded       also delete excluded files on receiver
-      --ignore-errors         delete even if there are I/O errors
-      --force                 force deletion of dirs even if not empty
-@@ -689,14 +690,23 @@ prevent temporary filesystem failures (s
- sending side causing a massive deletion of files on the
- destination.  You can override this with the --ignore-errors option.
--dit(bf(--delete-after)) By default rsync does file deletions on the
--receiving side before transferring files to try to ensure that there is
--sufficient space on the receiving filesystem. If you want to delete
--after transferring, use the --delete-after switch. Implies --delete.
--
--One reason to use --delete-after is to avoid a delay before the start of
--the transfer (while the receiving side is scanned for deletions) as this
--delay might cause the transfer to timeout.  
-+By default rsync does file deletions on the receiving side during the
-+transfer of files to try make it as efficient as possible.  For other
-+options, see --delete-before and --delte-after.
-+
-+dit(bf(--delete-before)) Request that the file-deletions on the receving
-+side be done prior to starting the transfer, not incrementally as the
-+transfer happens.  Implies --delete.
-+
-+One reason to use --delete-before is if the filesystem is tight for space
-+and removing extraneous files would help to make the transfer possible.
-+However, it does introduce a delay before the start of the transfer (while
-+the receiving side is being scanned for deletions) and this delay might
-+cause the transfer to timeout.  
-+
-+dit(bf(--delete-after)) Request that the file-deletions on the receving
-+side be done after the transfer has completed, not incrementally as the
-+transfer happens.  Implies --delete.
- dit(bf(--delete-excluded)) In addition to deleting the files on the
- receiving side that are not on the sending side, this tells rsync to also