Commit | Line | Data |
---|---|---|
df8c196d WD |
1 | --- orig/cleanup.c 2004-07-20 21:36:07 |
2 | +++ cleanup.c 2004-07-23 19:19:47 | |
3 | @@ -24,6 +24,7 @@ | |
4 | extern int io_error; | |
5 | extern int keep_partial; | |
6 | extern int log_got_error; | |
7 | +extern char *partial_dir; | |
8 | ||
9 | /** | |
10 | * Close all open sockets and files, allowing a (somewhat) graceful | |
11 | @@ -113,6 +114,8 @@ void _exit_cleanup(int code, const char | |
12 | ||
13 | if (cleanup_got_literal && cleanup_fname && keep_partial) { | |
14 | char *fname = cleanup_fname; | |
15 | + if (partial_dir) | |
16 | + do_mkdir(partial_dir, 0700); | |
17 | cleanup_fname = NULL; | |
18 | if (cleanup_fd_r != -1) | |
19 | close(cleanup_fd_r); | |
20 | --- orig/generator.c 2004-07-23 17:16:12 | |
21 | +++ generator.c 2004-07-23 19:19:47 | |
22 | @@ -42,6 +42,7 @@ extern int size_only; | |
23 | extern int io_timeout; | |
24 | extern int protocol_version; | |
25 | extern int always_checksum; | |
26 | +extern char *partial_dir; | |
27 | extern char *compare_dest; | |
28 | extern int link_dest; | |
29 | extern int whole_file; | |
30 | @@ -413,6 +414,21 @@ static void recv_generator(char *fname, | |
31 | ||
32 | fnamecmp = fname; | |
33 | ||
34 | + if (partial_dir) { | |
35 | + STRUCT_STAT st2; | |
36 | + char *fn = strrchr(fname, '/'); | |
37 | + if (fn) | |
38 | + fn++; | |
39 | + else | |
40 | + fn = fname; | |
41 | + pathjoin(fnamecmpbuf, sizeof fnamecmpbuf, partial_dir, fn); | |
42 | + if (link_stat(fnamecmpbuf, &st2, 0) == 0 && S_ISREG(st2.st_mode)) { | |
43 | + statret = 0; | |
44 | + st = st2; | |
45 | + fnamecmp = fnamecmpbuf; | |
46 | + } | |
47 | + } | |
48 | + | |
49 | if (statret == -1 && compare_dest != NULL) { | |
50 | /* try the file at compare_dest instead */ | |
51 | int saveerrno = errno; | |
52 | --- orig/options.c 2004-07-23 17:16:13 | |
53 | +++ options.c 2004-07-23 19:19:48 | |
54 | @@ -118,6 +118,7 @@ unsigned int backup_dir_remainder; | |
55 | ||
56 | char *backup_suffix = NULL; | |
57 | char *tmpdir = NULL; | |
58 | +char *partial_dir = NULL; | |
59 | char *compare_dest = NULL; | |
60 | char *config_file = NULL; | |
61 | char *shell_cmd = NULL; | |
62 | @@ -268,6 +269,7 @@ void usage(enum logcode F) | |
63 | rprintf(F," --ignore-errors delete even if there are I/O errors\n"); | |
64 | rprintf(F," --max-delete=NUM don't delete more than NUM files\n"); | |
65 | rprintf(F," --partial keep partially transferred files\n"); | |
66 | + rprintf(F," --partial-dir=DIR put a partially transferred file into DIR\n"); | |
67 | rprintf(F," --force force deletion of directories even if not empty\n"); | |
68 | rprintf(F," --numeric-ids don't map uid/gid values by user/group name\n"); | |
69 | rprintf(F," --timeout=TIME set I/O timeout in seconds\n"); | |
70 | @@ -383,6 +385,7 @@ static struct poptOption long_options[] | |
71 | {"stats", 0, POPT_ARG_NONE, &do_stats, 0, 0, 0 }, | |
72 | {"progress", 0, POPT_ARG_NONE, &do_progress, 0, 0, 0 }, | |
73 | {"partial", 0, POPT_ARG_NONE, &keep_partial, 0, 0, 0 }, | |
74 | + {"partial-dir", 0, POPT_ARG_STRING, &partial_dir, 0, 0, 0 }, | |
75 | {"ignore-errors", 0, POPT_ARG_NONE, &ignore_errors, 0, 0, 0 }, | |
76 | {"blocking-io", 0, POPT_ARG_VAL, &blocking_io, 1, 0, 0 }, | |
77 | {"no-blocking-io", 0, POPT_ARG_VAL, &blocking_io, 0, 0, 0 }, | |
78 | @@ -770,6 +773,11 @@ int parse_arguments(int *argc, const cha | |
79 | ||
80 | if (inplace) { | |
81 | #if HAVE_FTRUNCATE | |
82 | + if (partial_dir) { | |
83 | + snprintf(err_buf, sizeof err_buf, | |
84 | + "--inplace cannot be used with --partial-dir\n"); | |
85 | + return 0; | |
86 | + } | |
87 | keep_partial = 0; | |
88 | #else | |
89 | snprintf(err_buf, sizeof err_buf, | |
90 | @@ -777,7 +785,8 @@ int parse_arguments(int *argc, const cha | |
91 | am_server ? "server" : "client"); | |
92 | return 0; | |
93 | #endif | |
94 | - } | |
95 | + } else if (partial_dir) | |
96 | + keep_partial = 1; | |
97 | ||
98 | if (files_from) { | |
99 | char *colon; | |
100 | @@ -969,7 +978,10 @@ void server_options(char **args,int *arg | |
101 | args[ac++] = arg; | |
102 | } | |
103 | ||
104 | - if (keep_partial) | |
105 | + if (partial_dir) { | |
106 | + args[ac++] = "--partial-dir"; | |
107 | + args[ac++] = partial_dir; | |
108 | + } else if (keep_partial) | |
109 | args[ac++] = "--partial"; | |
110 | ||
111 | if (force_delete) | |
112 | --- orig/receiver.c 2004-07-23 17:16:13 | |
113 | +++ receiver.c 2004-07-23 19:19:48 | |
114 | @@ -38,6 +38,7 @@ extern int preserve_perms; | |
115 | extern int cvs_exclude; | |
116 | extern int io_error; | |
117 | extern char *tmpdir; | |
118 | +extern char *partial_dir; | |
119 | extern char *compare_dest; | |
120 | extern int make_backups; | |
121 | extern int do_progress; | |
122 | @@ -339,7 +340,7 @@ int recv_files(int f_in, struct file_lis | |
123 | char template[MAXPATHLEN]; | |
124 | char fnametmp[MAXPATHLEN]; | |
125 | char *fnamecmp; | |
126 | - char fnamecmpbuf[MAXPATHLEN]; | |
127 | + char fnamecmpbuf[MAXPATHLEN], partialbuf[MAXPATHLEN]; | |
128 | struct file_struct *file; | |
129 | struct stats initial_stats; | |
130 | int save_make_backups = make_backups; | |
131 | @@ -406,8 +407,6 @@ int recv_files(int f_in, struct file_lis | |
132 | if (verbose > 2) | |
133 | rprintf(FINFO,"recv_files(%s)\n",fname); | |
134 | ||
135 | - fnamecmp = fname; | |
136 | - | |
137 | if (read_batch) { | |
138 | while (i > next_gen_i) { | |
139 | next_gen_i = read_int(batch_gen_fd); | |
140 | @@ -434,9 +433,25 @@ int recv_files(int f_in, struct file_lis | |
141 | continue; | |
142 | } | |
143 | ||
144 | + if (partial_dir) { | |
145 | + char *fn = strrchr(fname, '/'); | |
146 | + if (fn) | |
147 | + fn++; | |
148 | + else | |
149 | + fn = fname; | |
150 | + pathjoin(partialbuf, sizeof partialbuf, partial_dir, fn); | |
151 | + fnamecmp = partialbuf; | |
152 | + } else | |
153 | + fnamecmp = fname; | |
154 | + | |
155 | /* open the file */ | |
156 | fd1 = do_open(fnamecmp, O_RDONLY, 0); | |
157 | ||
158 | + if (fd1 == -1 && partial_dir) { | |
159 | + fnamecmp = fname; | |
160 | + fd1 = do_open(fnamecmp, O_RDONLY, 0); | |
161 | + } | |
162 | + | |
163 | if (fd1 == -1 && compare_dest != NULL) { | |
164 | /* try the file at compare_dest instead */ | |
165 | pathjoin(fnamecmpbuf, sizeof fnamecmpbuf, | |
166 | @@ -524,7 +539,8 @@ int recv_files(int f_in, struct file_lis | |
167 | continue; | |
168 | } | |
169 | ||
170 | - cleanup_set(fnametmp, fname, file, fd1, fd2); | |
171 | + cleanup_set(fnametmp, partial_dir ? partialbuf : fname, | |
172 | + file, fd1, fd2); | |
173 | } | |
174 | ||
175 | if (!am_server && verbose) | |
176 | @@ -549,6 +565,12 @@ int recv_files(int f_in, struct file_lis | |
177 | else | |
178 | do_unlink(fnametmp); | |
179 | ||
180 | + if (fnamecmp == partialbuf) { | |
181 | + do_unlink(partialbuf); | |
182 | + if (*partialbuf != '/') | |
183 | + do_rmdir(partial_dir); | |
184 | + } | |
185 | + | |
186 | cleanup_disable(); | |
187 | ||
188 | if (!recv_ok) { | |
189 | --- orig/rsync.yo 2004-07-23 17:16:13 | |
190 | +++ rsync.yo 2004-07-23 19:36:41 | |
191 | @@ -317,6 +317,7 @@ verb( | |
192 | --ignore-errors delete even if there are I/O errors | |
193 | --max-delete=NUM don't delete more than NUM files | |
194 | --partial keep partially transferred files | |
195 | + --partial-dir=DIR put a partially transferred file into DIR | |
196 | --force force deletion of dirs even if not empty | |
197 | --numeric-ids don't map uid/gid values by user/group name | |
198 | --timeout=TIME set I/O timeout in seconds | |
199 | @@ -865,6 +866,21 @@ it is more desirable to keep partially t | |
200 | --partial option tells rsync to keep the partial file which should | |
201 | make a subsequent transfer of the rest of the file much faster. | |
202 | ||
203 | +dit(bf(--partial-dir=DIR)) Turns on --partial mode, but tells rsync to | |
204 | +put a partially transferred file into DIR instead of writing out the | |
205 | +file to the destination dir. Rsync will also use a file found in this | |
206 | +dir as data to speed up a subsequent transfer. | |
207 | + | |
208 | +Rsync will create the dir if it is missing, so feel free to use a | |
209 | +relative path (such as quote(--partial-dir=.rsync-partial)) if you | |
210 | +want the file put into a directory relative to the current directory | |
211 | +in the tree (rsync will also try to remove the DIR if a partial file | |
212 | +was found and the DIR was specified as a relative path). | |
213 | + | |
214 | +If you want to delete files on the destination, be sure to use | |
215 | +--delete-after instead of --delete or the partial file may be deleted | |
216 | +before it can be used. | |
217 | + | |
218 | dit(bf(--progress)) This option tells rsync to print information | |
219 | showing the progress of the transfer. This gives a bored user | |
220 | something to watch. |