added --max-delete option
authorAndrew Tridgell <tridge@samba.org>
Sun, 23 Jan 2000 11:43:04 +0000 (11:43 +0000)
committerAndrew Tridgell <tridge@samba.org>
Sun, 23 Jan 2000 11:43:04 +0000 (11:43 +0000)
options.c
receiver.c
rsync.yo

index e4924bf..8a3f7b7 100644 (file)
--- a/options.c
+++ b/options.c
@@ -64,6 +64,7 @@ int block_size=BLOCK_SIZE;
 int size_only=0;
 int delete_after=0;
 int only_existing=0;
+int max_delete=0;
 
 char *backup_suffix = BACKUP_SUFFIX;
 char *tmpdir = NULL;
@@ -130,6 +131,7 @@ void usage(int F)
   rprintf(F,"     --delete                delete files that don't exist on the sending side\n");
   rprintf(F,"     --delete-excluded       also delete excluded files on the receiving side\n");
   rprintf(F,"     --delete-after          delete after transferring, not before\n");
+  rprintf(F,"     --max-delete=NUM        don't delete more than NUM files\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");
@@ -167,7 +169,7 @@ enum {OPT_VERSION, OPT_SUFFIX, OPT_SENDER, OPT_SERVER, OPT_EXCLUDE,
       OPT_INCLUDE, OPT_INCLUDE_FROM, OPT_STATS, OPT_PARTIAL, OPT_PROGRESS,
       OPT_COPY_UNSAFE_LINKS, OPT_SAFE_LINKS, OPT_COMPARE_DEST,
       OPT_LOG_FORMAT, OPT_PASSWORD_FILE, OPT_SIZE_ONLY, OPT_ADDRESS,
-      OPT_DELETE_AFTER, OPT_EXISTING};
+      OPT_DELETE_AFTER, OPT_EXISTING, OPT_MAX_DELETE};
 
 static char *short_options = "oblLWHpguDCtcahvqrRIxnSe:B:T:zP";
 
@@ -228,6 +230,7 @@ static struct option long_options[] = {
   {"port",        1,     0,    OPT_PORT},
   {"log-format",  1,     0,    OPT_LOG_FORMAT},
   {"address",     1,     0,    OPT_ADDRESS},
+  {"max-delete",  1,     0,    OPT_MAX_DELETE},
   {0,0,0,0}};
 
 
@@ -488,6 +491,10 @@ int parse_arguments(int argc, char *argv[], int frommain)
                        block_size = atoi(optarg);
                        break;
 
+               case OPT_MAX_DELETE:
+                       max_delete = atoi(optarg);
+                       break;
+
                case OPT_TIMEOUT:
                        io_timeout = atoi(optarg);
                        break;
@@ -561,6 +568,7 @@ void server_options(char **args,int *argc)
        static char argstr[50];
        static char bsize[30];
        static char iotime[30];
+       static char mdelete[30];
        int i, x;
 
        args[ac++] = "--server";
@@ -618,12 +626,17 @@ void server_options(char **args,int *argc)
        if (x != 1) args[ac++] = argstr;
 
        if (block_size != BLOCK_SIZE) {
-               sprintf(bsize,"-B%d",block_size);
+               slprintf(bsize,sizeof(bsize),"-B%d",block_size);
                args[ac++] = bsize;
        }    
 
+       if (max_delete && am_sender) {
+               slprintf(mdelete,sizeof(mdelete),"--max-delete=%d",max_delete);
+               args[ac++] = mdelete;
+       }    
+
        if (io_timeout) {
-               sprintf(iotime,"--timeout=%d",io_timeout);
+               slprintf(iotime,sizeof(iotime),"--timeout=%d",io_timeout);
                args[ac++] = iotime;
        }    
 
@@ -659,7 +672,7 @@ void server_options(char **args,int *argc)
        if (numeric_ids)
                args[ac++] = "--numeric-ids";
 
-       if (only_existing)
+       if (only_existing && am_sender)
                args[ac++] = "--existing";
 
        if (tmpdir) {
index 3cd7f9e..7cc9a81 100644 (file)
@@ -43,7 +43,6 @@ static struct delete_list {
 } *delete_list;
 static int dlist_len, dlist_alloc_len;
 
-
 /* yuck! This function wouldn't have been necessary if I had the sorting
    algorithm right. Unfortunately fixing the sorting algorithm would introduce
    a backward incompatibility as file list indexes are sent over the link.
@@ -110,6 +109,8 @@ static void delete_files(struct file_list *flist)
        int i, j;
        char *name;
        extern int module_id;
+       extern int max_delete;
+       static int deletion_count;
 
        if (cvs_exclude)
                add_cvs_excludes();
@@ -137,6 +138,7 @@ static void delete_files(struct file_list *flist)
                        rprintf(FINFO,"deleting in %s\n", name);
 
                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 (remote_version < 19 &&
                            S_ISDIR(local_file_list->files[i]->mode))
@@ -148,6 +150,7 @@ static void delete_files(struct file_list *flist)
                                            (strcmp(f+k,backup_suffix) != 0))) {
                                        (void) make_backup(f);
                                } else {
+                                       deletion_count++;
                                        delete_one(local_file_list->files[i]);
                                }
                        }
index 75d9082..3fd7122 100644 (file)
--- a/rsync.yo
+++ b/rsync.yo
@@ -247,6 +247,7 @@ verb(
      --delete                delete files that don't exist on the sending side
      --delete-excluded       also delete excluded files on the receiving side
      --delete-after          delete after transferring, not before
+     --max-delete=NUM        don't delete more than NUM files
      --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
@@ -427,6 +428,10 @@ contents of only one filesystem.
 dit(bf(--existing)) This tells rsync not to create any new files -
 only update files that already exist on the destination.
 
+dit(bf(--max-delete=NUM)) This tells rsync not to delete more than NUM
+files or directories. This is useful when mirroring very large trees
+to prevent disasters.
+
 dit(bf(--delete)) This tells rsync to delete any files on the receiving
 side that aren't on the sending side.   Files that are excluded from
 transfer are excluded from being deleted unless you use --delete-excluded.