Fixed failing hunks.
[rsync/rsync-patches.git] / backup-dir-dels.diff
CommitLineData
8af83008 1This patches creates two new command line options as follows:
79f132a1
WD
2 --backup-dir-rm
3 --backup-suffix-rm=SUFFIX
8af83008 4
79f132a1
WD
5The backup-dir-rm and backup-suffix-rm options give the ability to store
6backup of removed files on the receiver in different directories or with
7different suffix than the backup of files that have been changed but that
8are still on the source drive. Both commands can be combined.
8af83008
WD
9
10The default behaviour if one or both of the options are not specified
11is the previous behaviour, both backups use the same directory or
12suffix.
13
14Marc St-Onge
15
4f9b6a01 16--- orig/backup.c 2005-01-25 12:14:14
44917741 17+++ backup.c 2004-09-22 02:36:06
8af83008
WD
18@@ -22,11 +22,17 @@
19
20 extern int verbose;
21 extern int backup_suffix_len;
79f132a1 22+extern int backup_suffix_rm_len;
8af83008 23 extern int backup_dir_len;
79f132a1 24+extern int backup_dir_rm_len;
8af83008 25 extern unsigned int backup_dir_remainder;
79f132a1 26+extern unsigned int backup_dir_rm_remainder;
8af83008 27 extern char backup_dir_buf[MAXPATHLEN];
79f132a1 28+extern char backup_dir_rm_buf[MAXPATHLEN];
8af83008 29 extern char *backup_suffix;
79f132a1 30+extern char *backup_suffix_rm;
8af83008 31 extern char *backup_dir;
79f132a1 32+extern char *backup_dir_rm;
8af83008
WD
33
34 extern int am_root;
35 extern int preserve_devices;
36@@ -35,6 +41,8 @@ extern int preserve_hard_links;
37 extern int orig_umask;
38 extern int safe_symlinks;
39
40+static int deleting;
41+
42 /* make a complete pathname for backup file */
43 char *get_backup_name(char *fname)
44 {
45@@ -52,10 +60,27 @@ char *get_backup_name(char *fname)
46 return NULL;
47 }
48
49+static char *get_delete_name(char *fname)
50+{
79f132a1
WD
51+ if (backup_dir_rm) {
52+ if (stringjoin(backup_dir_rm_buf + backup_dir_rm_len, backup_dir_rm_remainder,
53+ fname, backup_suffix_rm, NULL) < backup_dir_rm_remainder)
54+ return backup_dir_rm_buf;
8af83008 55+ } else {
79f132a1
WD
56+ if (stringjoin(backup_dir_rm_buf, MAXPATHLEN,
57+ fname, backup_suffix_rm, NULL) < MAXPATHLEN)
58+ return backup_dir_rm_buf;
8af83008
WD
59+ }
60+
61+ rprintf(FERROR, "delete filename too long\n");
62+ return NULL;
63+}
64+
65 /* simple backup creates a backup with a suffix in the same directory */
66 static int make_simple_backup(char *fname)
67 {
68- char *fnamebak = get_backup_name(fname);
69+ char *fnamebak = deleting ? get_delete_name(fname)
70+ : get_backup_name(fname);
71
72 if (!fnamebak)
73 return 0;
74@@ -81,7 +106,8 @@ path
75 static int make_bak_dir(char *fullpath)
76 {
77 STRUCT_STAT st;
78- char *rel = fullpath + backup_dir_len;
79f132a1 79+ int dir_len = deleting ? backup_dir_rm_len : backup_dir_len;
8af83008
WD
80+ char *rel = fullpath + dir_len;
81 char *end = rel + strlen(rel);
82 char *p = end;
83
2f2a7c3e 84@@ -168,7 +194,8 @@ static int keep_backup(char *fname)
4f9b6a01 85 if (!(file = make_file(fname, NULL, NO_FILTERS)))
8af83008
WD
86 return 1; /* the file could have disappeared */
87
88- if (!(buf = get_backup_name(fname)))
89+ buf = deleting ? get_delete_name(fname) : get_backup_name(fname);
90+ if (!buf)
91 return 0;
92
57e73b72 93 /* Check to see if this is a device file, or link */
2f2a7c3e 94@@ -259,3 +286,13 @@ int make_backup(char *fname)
44917741
WD
95 return keep_backup(fname);
96 return make_simple_backup(fname);
97 }
8af83008 98+
79f132a1 99+/* backup switch routine called only when backing-up removed file */
8af83008
WD
100+int safe_delete(char *fname)
101+{
44917741 102+ int ret;
8af83008 103+ deleting = 1;
44917741
WD
104+ ret = make_backup(fname);
105+ deleting = 0;
106+ return ret;
107+}
79f132a1 108--- orig/flist.c 2005-01-28 19:08:20
fd0e045e 109+++ flist.c 2005-01-24 02:21:33
ac23c334
WD
110@@ -47,6 +47,8 @@ extern char curr_dir[MAXPATHLEN];
111 extern unsigned int curr_dir_len;
fd0e045e
WD
112 extern char *backup_dir;
113 extern char *backup_suffix;
79f132a1
WD
114+extern char *backup_dir_rm;
115+extern char *backup_suffix_rm;
fd0e045e
WD
116 extern int filesfrom_fd;
117
118 extern int one_file_system;
ac23c334 119@@ -61,6 +63,7 @@ extern int relative_paths;
fd0e045e
WD
120 extern int implied_dirs;
121 extern int make_backups;
122 extern int backup_suffix_len;
79f132a1 123+extern int backup_suffix_rm_len;
fd0e045e
WD
124 extern int copy_links;
125 extern int copy_unsafe_links;
126 extern int protocol_version;
79f132a1 127@@ -1674,10 +1677,14 @@ char *f_name(struct file_struct *f)
fd0e045e
WD
128 return f_name_to(f, names[n]);
129 }
130
131+/* Function now checks if file matches backup or delete suffix patterns */
132 static int is_backup_file(char *fn)
133 {
134 int k = strlen(fn) - backup_suffix_len;
135- return k > 0 && strcmp(fn+k, backup_suffix) == 0;
136+ if (k > 0 && strcmp(fn+k, backup_suffix) == 0)
137+ return 1;
79f132a1
WD
138+ k += backup_suffix_len - backup_suffix_rm_len;
139+ return k > 0 && strcmp(fn+k, backup_suffix_rm) == 0;
fd0e045e
WD
140 }
141
142 void delete_in_dir(struct file_list *flist, char *fname)
79f132a1 143@@ -1731,11 +1738,12 @@ void delete_in_dir(struct file_list *fli
fd0e045e
WD
144 || (delete_during && S_ISDIR(mode)
145 && !S_ISDIR(flist->files[j]->mode))) {
146 char *f = f_name(del_flist->files[i]);
147- if (make_backups && (backup_dir || !is_backup_file(f))
148+ int backup_file = is_backup_file(f);
79f132a1 149+ if (make_backups && (backup_dir_rm || !backup_file)
fd0e045e
WD
150 && !S_ISDIR(mode)) {
151- make_backup(f);
152+ safe_delete(f);
153 if (verbose) {
154- rprintf(FINFO, "deleting %s\n",
155+ rprintf(FINFO, "safe-deleting %s\n",
156 safe_fname(f));
157 }
158 } else {
79f132a1
WD
159--- orig/options.c 2005-01-28 19:08:20
160+++ options.c 2005-01-28 19:17:35
fd0e045e 161@@ -119,10 +119,14 @@ int no_detach = 0;
8af83008
WD
162 int write_batch = 0;
163 int read_batch = 0;
164 int backup_dir_len = 0;
79f132a1 165+int backup_dir_rm_len = 0;
8af83008 166 int backup_suffix_len;
79f132a1 167+int backup_suffix_rm_len;
8af83008 168 unsigned int backup_dir_remainder;
79f132a1 169+unsigned int backup_dir_rm_remainder;
8af83008
WD
170
171 char *backup_suffix = NULL;
79f132a1 172+char *backup_suffix_rm = NULL;
8af83008
WD
173 char *tmpdir = NULL;
174 char *partial_dir = NULL;
daceaa67 175 char *basis_dir[MAX_BASIS_DIRS+1];
fd0e045e 176@@ -132,7 +136,9 @@ char *log_format = NULL;
8af83008
WD
177 char *password_file = NULL;
178 char *rsync_path = RSYNC_PATH;
179 char *backup_dir = NULL;
79f132a1 180+char *backup_dir_rm = NULL;
8af83008 181 char backup_dir_buf[MAXPATHLEN];
79f132a1 182+char backup_dir_rm_buf[MAXPATHLEN];
daceaa67 183 int rsync_port = 0;
c59d6641 184 int compare_dest = 0;
daceaa67 185 int copy_dest = 0;
79f132a1 186@@ -256,6 +262,8 @@ void usage(enum logcode F)
8af83008 187 rprintf(F," -b, --backup make backups (see --suffix & --backup-dir)\n");
79f132a1
WD
188 rprintf(F," --backup-dir=DIR make backups into hierarchy based in DIR\n");
189 rprintf(F," --suffix=SUFFIX set backup suffix (default %s w/o --backup-dir)\n",BACKUP_SUFFIX);
190+ rprintf(F," --backup-dir-rm make backups of removed files into current dir\n");
191+ rprintf(F," --backup-suffix-rm=SUF set removed-files suffix (defaults to --suffix)\n");
192 rprintf(F," -u, --update skip files that are newer on the receiver\n");
0b2fb126 193 rprintf(F," --inplace update destination files in-place (SEE MAN PAGE)\n");
fd0e045e 194 rprintf(F," -d, --dirs transfer directories without recursing\n");
79f132a1 195@@ -348,6 +356,7 @@ static struct poptOption long_options[]
8af83008 196 /* longName, shortName, argInfo, argPtr, value, descrip, argDesc */
57e73b72 197 {"version", 0, POPT_ARG_NONE, 0, OPT_VERSION, 0, 0},
8af83008 198 {"suffix", 0, POPT_ARG_STRING, &backup_suffix, 0, 0, 0 },
79f132a1 199+ {"backup-suffix-rm", 0, POPT_ARG_STRING, &backup_suffix_rm, 0, 0, 0 },
8af83008
WD
200 {"rsync-path", 0, POPT_ARG_STRING, &rsync_path, 0, 0, 0 },
201 {"password-file", 0, POPT_ARG_STRING, &password_file, 0, 0, 0 },
202 {"ignore-times", 'I', POPT_ARG_NONE, &ignore_times, 0, 0, 0 },
79f132a1 203@@ -424,6 +433,7 @@ static struct poptOption long_options[]
57e73b72 204 {"log-format", 0, POPT_ARG_STRING, &log_format, 0, 0, 0 },
8af83008 205 {"bwlimit", 0, POPT_ARG_INT, &bwlimit, 0, 0, 0 },
8af83008 206 {"backup-dir", 0, POPT_ARG_STRING, &backup_dir, 0, 0, 0 },
79f132a1 207+ {"backup-dir-rm", 0, POPT_ARG_STRING, &backup_dir_rm, 0, 0, 0 },
8af83008 208 {"hard-links", 'H', POPT_ARG_NONE, &preserve_hard_links, 0, 0, 0 },
57e73b72
WD
209 {"read-batch", 0, POPT_ARG_STRING, &batch_name, OPT_READ_BATCH, 0, 0 },
210 {"write-batch", 0, POPT_ARG_STRING, &batch_name, OPT_WRITE_BATCH, 0, 0 },
79f132a1 211@@ -932,6 +942,8 @@ int parse_arguments(int *argc, const cha
daceaa67 212 partial_dir = sanitize_path(NULL, partial_dir, NULL, 0);
8af83008
WD
213 if (backup_dir)
214 backup_dir = sanitize_path(NULL, backup_dir, NULL, 0);
79f132a1
WD
215+ if (backup_dir_rm)
216+ backup_dir_rm = sanitize_path(NULL, backup_dir_rm, NULL, 0);
8af83008
WD
217 if (files_from)
218 files_from = sanitize_path(NULL, files_from, NULL, 0);
219 }
79f132a1 220@@ -958,6 +970,12 @@ int parse_arguments(int *argc, const cha
4f9b6a01 221 if (check_filter(elp, backup_dir, 1) < 0)
8af83008
WD
222 goto options_rejected;
223 }
79f132a1
WD
224+ /* Clean backup_dir_rm same as for backup_dir */
225+ if (backup_dir_rm) {
226+ clean_fname(backup_dir_rm, 1);
227+ if (check_exclude(elp, backup_dir_rm, 1) < 0)
8af83008
WD
228+ goto options_rejected;
229+ }
230 }
4f9b6a01 231 if (server_filter_list.head && files_from) {
8af83008 232 clean_fname(files_from, 1);
79f132a1 233@@ -978,6 +996,16 @@ int parse_arguments(int *argc, const cha
8af83008
WD
234 backup_suffix);
235 return 0;
236 }
79f132a1
WD
237+ /* if suffix_rm not supplied, default to backup_suffix */
238+ if (!backup_suffix_rm)
239+ backup_suffix_rm = backup_dir_rm ? "" : backup_suffix;
240+ backup_suffix_rm_len = strlen(backup_suffix_rm);
241+ if (strchr(backup_suffix_rm, '/') != NULL) {
8af83008 242+ snprintf(err_buf, sizeof err_buf,
79f132a1
WD
243+ "--backup-suffix-rm cannot contain slashes: %s\n",
244+ backup_suffix_rm);
8af83008
WD
245+ return 0;
246+ }
247 if (backup_dir) {
248 backup_dir_len = strlcpy(backup_dir_buf, backup_dir, sizeof backup_dir_buf);
249 backup_dir_remainder = sizeof backup_dir_buf - backup_dir_len;
79f132a1 250@@ -997,6 +1025,31 @@ int parse_arguments(int *argc, const cha
8af83008
WD
251 "--suffix cannot be a null string without --backup-dir\n");
252 return 0;
253 }
79f132a1
WD
254+ /* If backup_dir_rm not supplied default to backup_dir if it has been supplied */
255+ if (backup_dir && !backup_dir_rm) {
256+ backup_dir_rm = backup_dir;
257+ backup_dir_rm_len = backup_dir_len;
258+ backup_dir_rm_remainder = backup_dir_remainder;
259+ strlcpy(backup_dir_rm_buf, backup_dir_buf, sizeof backup_dir_buf);
260+ } else if (backup_dir_rm) {
261+ backup_dir_rm_len = strlcpy(backup_dir_rm_buf, backup_dir_rm, sizeof backup_dir_rm_buf);
262+ backup_dir_rm_remainder = sizeof backup_dir_rm_buf - backup_dir_rm_len;
263+ if (backup_dir_rm_remainder < 32) {
8af83008 264+ snprintf(err_buf, sizeof err_buf,
79f132a1 265+ "the --backup-dir-rm path is WAY too long.\n");
8af83008
WD
266+ return 0;
267+ }
79f132a1
WD
268+ if (backup_dir_rm_buf[backup_dir_rm_len - 1] != '/') {
269+ backup_dir_rm_buf[backup_dir_rm_len++] = '/';
270+ backup_dir_rm_buf[backup_dir_rm_len] = '\0';
8af83008
WD
271+ }
272+ if (verbose > 1 && !am_sender)
79f132a1
WD
273+ rprintf(FINFO, "backup_dir_rm is %s\n", backup_dir_rm_buf);
274+ } else if (!backup_suffix_rm_len && (!am_server || !am_sender)) {
8af83008 275+ snprintf(err_buf, sizeof err_buf,
79f132a1 276+ "--backup-suffix-rm cannot be a null string without --backup-dir-rm\n");
8af83008
WD
277+ return 0;
278+ }
279
280 if (do_progress && !verbose)
281 verbose = 1;
79f132a1 282@@ -1214,6 +1267,10 @@ void server_options(char **args,int *arg
8af83008
WD
283 args[ac++] = "--backup-dir";
284 args[ac++] = backup_dir;
285 }
79f132a1
WD
286+ if (backup_dir_rm) {
287+ args[ac++] = "--backup-dir-rm";
288+ args[ac++] = backup_dir_rm;
8af83008
WD
289+ }
290
291 /* Only send --suffix if it specifies a non-default value. */
292 if (strcmp(backup_suffix, backup_dir ? "" : BACKUP_SUFFIX) != 0) {
79f132a1 293@@ -1222,7 +1279,13 @@ void server_options(char **args,int *arg
8af83008
WD
294 goto oom;
295 args[ac++] = arg;
296 }
297-
79f132a1
WD
298+ /* Only send --backup-suffix-rm if it specifies a non-default value. */
299+ if (strcmp(backup_suffix_rm, backup_dir_rm ? "" : BACKUP_SUFFIX) != 0) {
8af83008 300+ /* We use the following syntax to avoid weirdness with '~'. */
79f132a1 301+ if (asprintf(&arg, "--backup-suffix-rm=%s", backup_suffix_rm) < 0)
8af83008
WD
302+ goto oom;
303+ args[ac++] = arg;
304+ }
305 if (am_sender) {
306 if (delete_excluded)
307 args[ac++] = "--delete-excluded";