| 1 | This patch adds a --source-backup option that backs up source files |
| 2 | removed due to --remove-source-files. |
| 3 | |
| 4 | To use this patch, run these commands for a successful build: |
| 5 | |
| 6 | patch -p1 <patches/source-backup.diff |
| 7 | ./configure (optional if already run) |
| 8 | make |
| 9 | |
| 10 | -- Matt McCutchen <hashproduct@gmail.com> |
| 11 | |
| 12 | based-on: a01e3b490eb36ccf9e704840e1b6683dab867550 |
| 13 | diff --git a/options.c b/options.c |
| 14 | --- a/options.c |
| 15 | +++ b/options.c |
| 16 | @@ -33,6 +33,7 @@ extern filter_rule_list filter_list; |
| 17 | extern filter_rule_list daemon_filter_list; |
| 18 | |
| 19 | int make_backups = 0; |
| 20 | +int make_source_backups = 0; |
| 21 | |
| 22 | /** |
| 23 | * If 1, send the whole file as literal data rather than trying to |
| 24 | @@ -713,6 +714,7 @@ void usage(enum logcode F) |
| 25 | rprintf(F," --existing skip creating new files on receiver\n"); |
| 26 | rprintf(F," --ignore-existing skip updating files that already exist on receiver\n"); |
| 27 | rprintf(F," --remove-source-files sender removes synchronized files (non-dirs)\n"); |
| 28 | + rprintf(F," --source-backup ... and backs up those files\n"); |
| 29 | rprintf(F," --del an alias for --delete-during\n"); |
| 30 | rprintf(F," --delete delete extraneous files from destination dirs\n"); |
| 31 | rprintf(F," --delete-before receiver deletes before transfer, not during\n"); |
| 32 | @@ -967,6 +969,7 @@ static struct poptOption long_options[] = { |
| 33 | {"bwlimit", 0, POPT_ARG_STRING, &bwlimit_arg, OPT_BWLIMIT, 0, 0 }, |
| 34 | {"no-bwlimit", 0, POPT_ARG_VAL, &bwlimit, 0, 0, 0 }, |
| 35 | {"backup", 'b', POPT_ARG_VAL, &make_backups, 1, 0, 0 }, |
| 36 | + {"source-backup", 0, POPT_ARG_NONE, &make_source_backups, 0, 0, 0}, |
| 37 | {"no-backup", 0, POPT_ARG_VAL, &make_backups, 0, 0, 0 }, |
| 38 | {"backup-dir", 0, POPT_ARG_STRING, &backup_dir, 0, 0, 0 }, |
| 39 | {"suffix", 0, POPT_ARG_STRING, &backup_suffix, 0, 0, 0 }, |
| 40 | @@ -2536,6 +2539,8 @@ void server_options(char **args, int *argc_p) |
| 41 | goto oom; |
| 42 | args[ac++] = arg; |
| 43 | } |
| 44 | + if (make_source_backups) |
| 45 | + args[ac++] = "--source-backup"; |
| 46 | } |
| 47 | |
| 48 | /* --delete-missing-args needs the cooperation of both sides, but |
| 49 | diff --git a/rsync.yo b/rsync.yo |
| 50 | --- a/rsync.yo |
| 51 | +++ b/rsync.yo |
| 52 | @@ -368,6 +368,7 @@ to the detailed description below for a complete description. verb( |
| 53 | --existing skip creating new files on receiver |
| 54 | --ignore-existing skip updating files that exist on receiver |
| 55 | --remove-source-files sender removes synchronized files (non-dir) |
| 56 | + --source-backup ... and backs up those files |
| 57 | --del an alias for --delete-during |
| 58 | --delete delete extraneous files from dest dirs |
| 59 | --delete-before receiver deletes before xfer, not during |
| 60 | @@ -1198,6 +1199,14 @@ dit(bf(--remove-source-files)) This tells rsync to remove from the sending |
| 61 | side the files (meaning non-directories) that are a part of the transfer |
| 62 | and have been successfully duplicated on the receiving side. |
| 63 | |
| 64 | +dit(bf(--source-backup)) Makes the sender back up the source files it removes |
| 65 | +due to bf(--remove-source-files). This option is independent of |
| 66 | +bf(--backup) but uses the same bf(--backup-dir) and bf(--suffix) settings, |
| 67 | +if any. With bf(--backup-dir), rsync looks for each file's backup dir relative |
| 68 | +to the source argument the file came from. Consequently, if the |
| 69 | +bf(--backup-dir) path is relative, each source argument gets a separate backup |
| 70 | +dir at that path relative to the argument. |
| 71 | + |
| 72 | dit(bf(--delete)) This tells rsync to delete extraneous files from the |
| 73 | receiving side (ones that aren't on the sending side), but only for the |
| 74 | directories that are being synchronized. You must have asked rsync to |
| 75 | diff --git a/sender.c b/sender.c |
| 76 | --- a/sender.c |
| 77 | +++ b/sender.c |
| 78 | @@ -39,6 +39,7 @@ extern int protocol_version; |
| 79 | extern int remove_source_files; |
| 80 | extern int updating_basis_file; |
| 81 | extern int make_backups; |
| 82 | +extern int make_source_backups; |
| 83 | extern int inplace; |
| 84 | extern int batch_fd; |
| 85 | extern int write_batch; |
| 86 | @@ -126,6 +127,7 @@ void successful_send(int ndx) |
| 87 | char fname[MAXPATHLEN]; |
| 88 | struct file_struct *file; |
| 89 | struct file_list *flist; |
| 90 | + int result; |
| 91 | |
| 92 | if (!remove_source_files) |
| 93 | return; |
| 94 | @@ -136,7 +138,11 @@ void successful_send(int ndx) |
| 95 | return; |
| 96 | f_name(file, fname); |
| 97 | |
| 98 | - if (do_unlink(fname) == 0) { |
| 99 | + if (make_source_backups) |
| 100 | + result = !make_backup(fname, True); |
| 101 | + else |
| 102 | + result = do_unlink(fname); |
| 103 | + if (result == 0) { |
| 104 | if (INFO_GTE(REMOVE, 1)) |
| 105 | rprintf(FINFO, "sender removed %s\n", fname); |
| 106 | } else |