Commit | Line | Data |
---|---|---|
a2d23604 WD |
1 | Patch from Mark Curtis to implement the --inplace option. |
2 | ||
7f2baf27 | 3 | --- match.c 13 May 2004 06:46:20 -0000 1.61 |
fe6407b5 | 4 | +++ match.c 15 May 2004 20:23:18 -0000 |
a2d23604 WD |
5 | @@ -22,6 +22,7 @@ |
6 | extern int verbose; | |
7 | extern int am_server; | |
8 | extern int do_progress; | |
9 | +extern int inplace; | |
10 | ||
11 | typedef unsigned short tag; | |
12 | ||
13 | @@ -197,6 +198,10 @@ static void hash_search(int f,struct sum | |
14 | /* also make sure the two blocks are the same length */ | |
15 | l = MIN((OFF_T)s->blength, len-offset); | |
16 | if (l != s->sums[i].len) | |
17 | + continue; | |
18 | + | |
19 | + /* if inplace, make sure the offset is greater than where we are */ | |
20 | + if (inplace && offset > s->sums[i].offset) | |
21 | continue; | |
22 | ||
23 | if (verbose > 3) | |
ea238f1c | 24 | --- options.c 6 May 2004 21:08:01 -0000 1.148 |
fe6407b5 | 25 | +++ options.c 15 May 2004 20:23:19 -0000 |
a2d23604 WD |
26 | @@ -91,6 +91,7 @@ int ignore_errors = 0; |
27 | int modify_window = 0; | |
28 | int blocking_io = -1; | |
29 | int checksum_seed = 0; | |
30 | +int inplace = 0; | |
31 | unsigned int block_size = 0; | |
32 | ||
33 | ||
34 | @@ -231,6 +232,7 @@ void usage(enum logcode F) | |
35 | rprintf(F," --backup-dir make backups into this directory\n"); | |
36 | rprintf(F," --suffix=SUFFIX backup suffix (default %s w/o --backup-dir)\n",BACKUP_SUFFIX); | |
37 | rprintf(F," -u, --update update only (don't overwrite newer files)\n"); | |
38 | + rprintf(F," --inplace update the destination file inplace *SEE MAN PAGE*\n"); | |
39 | rprintf(F," -l, --links copy symlinks as symlinks\n"); | |
40 | rprintf(F," -L, --copy-links copy the referent of all symlinks\n"); | |
41 | rprintf(F," --copy-unsafe-links copy the referent of \"unsafe\" symlinks\n"); | |
42 | @@ -321,6 +323,7 @@ static struct poptOption long_options[] | |
43 | {"delete", 0, POPT_ARG_NONE, &delete_mode, 0, 0, 0 }, | |
44 | {"existing", 0, POPT_ARG_NONE, &only_existing, 0, 0, 0 }, | |
45 | {"ignore-existing", 0, POPT_ARG_NONE, &opt_ignore_existing, 0, 0, 0 }, | |
46 | + {"inplace", 0, POPT_ARG_NONE, &inplace, 0, 0, 0 }, | |
47 | {"delete-after", 0, POPT_ARG_NONE, 0, OPT_DELETE_AFTER, 0, 0 }, | |
48 | {"delete-excluded", 0, POPT_ARG_NONE, 0, OPT_DELETE_EXCLUDED, 0, 0 }, | |
49 | {"force", 0, POPT_ARG_NONE, &force_delete, 0, 0, 0 }, | |
50 | @@ -723,6 +726,9 @@ int parse_arguments(int *argc, const cha | |
51 | if (do_progress && !verbose) | |
52 | verbose = 1; | |
53 | ||
54 | + if (inplace && keep_partial) | |
55 | + keep_partial = 0; | |
56 | + | |
57 | if (files_from) { | |
58 | char *colon; | |
59 | if (*argc != 2 && !(am_server && am_sender && *argc == 1)) { | |
60 | @@ -938,6 +944,9 @@ void server_options(char **args,int *arg | |
61 | ||
62 | if (opt_ignore_existing && am_sender) | |
63 | args[ac++] = "--ignore-existing"; | |
64 | + | |
65 | + if (inplace) | |
66 | + args[ac++] = "--inplace"; | |
67 | ||
68 | if (tmpdir) { | |
69 | args[ac++] = "--temp-dir"; | |
fe6407b5 WD |
70 | --- receiver.c 15 May 2004 19:31:10 -0000 1.78 |
71 | +++ receiver.c 15 May 2004 20:23:19 -0000 | |
7f2baf27 | 72 | @@ -46,6 +46,7 @@ extern int module_id; |
a2d23604 WD |
73 | extern int ignore_errors; |
74 | extern int orig_umask; | |
7f2baf27 | 75 | extern int keep_partial; |
a2d23604 WD |
76 | +extern int inplace; |
77 | ||
78 | static void delete_one(char *fn, int is_dir) | |
79 | { | |
fe6407b5 | 80 | @@ -251,16 +252,28 @@ static int receive_data(int f_in,struct |
a2d23604 WD |
81 | sum_update(map,len); |
82 | } | |
83 | ||
84 | - if (fd != -1 && write_file(fd,map,len) != (int) len) { | |
fe6407b5 WD |
85 | - rsyserr(FERROR, errno, "write failed on %s", |
86 | - full_fname(fname)); | |
a2d23604 WD |
87 | - exit_cleanup(RERR_FILEIO); |
88 | + if (!inplace || offset != offset2) { | |
89 | + if (fd != -1 && write_file(fd,map,len) != (int) len) { | |
fe6407b5 WD |
90 | + rsyserr(FERROR, errno, "write failed on %s", |
91 | + full_fname(fname)); | |
a2d23604 WD |
92 | + exit_cleanup(RERR_FILEIO); |
93 | + } | |
94 | + } else { | |
95 | + flush_write_file(fd); | |
96 | + if (do_lseek(fd,(OFF_T)len,SEEK_CUR) != offset+len) { | |
97 | + rprintf(FERROR, "lseek failed on %s: %s, %lli, %lli, %i\n", | |
98 | + full_fname(fname), strerror(errno), do_lseek(fd,0,SEEK_CUR), (offset+len), i); | |
99 | + exit_cleanup(RERR_FILEIO); | |
100 | + } | |
101 | } | |
102 | offset += len; | |
103 | } | |
104 | ||
105 | flush_write_file(fd); | |
106 | ||
107 | + if (inplace) | |
108 | + ftruncate(fd, offset); | |
109 | + | |
110 | if (do_progress) | |
111 | end_progress(total_size); | |
112 | ||
fe6407b5 | 113 | @@ -412,37 +425,50 @@ int recv_files(int f_in,struct file_list |
a2d23604 WD |
114 | } else |
115 | mapbuf = NULL; | |
116 | ||
117 | - if (!get_tmpname(fnametmp,fname)) { | |
118 | - if (mapbuf) unmap_file(mapbuf); | |
119 | - if (fd1 != -1) close(fd1); | |
120 | - continue; | |
121 | - } | |
122 | + /* We now check to see if we are writing file "inplace" */ | |
123 | + if (inplace) { | |
124 | + fd2 = do_open(fnamecmp, O_WRONLY|O_CREAT, 0); | |
125 | + if (fd2 == -1) { | |
fe6407b5 WD |
126 | + rsyserr(FERROR, errno, "open %s failed", |
127 | + full_fname(fnametmp)); | |
a2d23604 WD |
128 | + receive_data(f_in,mapbuf,-1,NULL,file->length); |
129 | + if (mapbuf) unmap_file(mapbuf); | |
130 | + if (fd1 != -1) close(fd1); | |
131 | + continue; | |
132 | + } | |
133 | + } else { | |
134 | + if (!get_tmpname(fnametmp,fname)) { | |
135 | + if (mapbuf) unmap_file(mapbuf); | |
136 | + if (fd1 != -1) close(fd1); | |
137 | + continue; | |
138 | + } | |
139 | ||
140 | - strlcpy(template, fnametmp, sizeof template); | |
141 | + strlcpy(template, fnametmp, sizeof template); | |
142 | ||
143 | - /* we initially set the perms without the | |
144 | - * setuid/setgid bits to ensure that there is no race | |
145 | - * condition. They are then correctly updated after | |
146 | - * the lchown. Thanks to snabb@epipe.fi for pointing | |
147 | - * this out. We also set it initially without group | |
148 | - * access because of a similar race condition. */ | |
149 | - fd2 = do_mkstemp(fnametmp, file->mode & INITACCESSPERMS); | |
150 | - | |
151 | - /* in most cases parent directories will already exist | |
152 | - * because their information should have been previously | |
153 | - * transferred, but that may not be the case with -R */ | |
154 | - if (fd2 == -1 && relative_paths && errno == ENOENT && | |
155 | - create_directory_path(fnametmp, orig_umask) == 0) { | |
156 | - strlcpy(fnametmp, template, sizeof fnametmp); | |
157 | + /* we initially set the perms without the | |
158 | + * setuid/setgid bits to ensure that there is no race | |
159 | + * condition. They are then correctly updated after | |
160 | + * the lchown. Thanks to snabb@epipe.fi for pointing | |
161 | + * this out. We also set it initially without group | |
162 | + * access because of a similar race condition. */ | |
163 | fd2 = do_mkstemp(fnametmp, file->mode & INITACCESSPERMS); | |
164 | - } | |
165 | - if (fd2 == -1) { | |
fe6407b5 WD |
166 | - rsyserr(FERROR, errno, "mkstemp %s failed", |
167 | - full_fname(fnametmp)); | |
a2d23604 WD |
168 | - receive_data(f_in,mapbuf,-1,NULL,file->length); |
169 | - if (mapbuf) unmap_file(mapbuf); | |
170 | - if (fd1 != -1) close(fd1); | |
171 | - continue; | |
172 | + | |
173 | + /* in most cases parent directories will already exist | |
174 | + * because their information should have been previously | |
175 | + * transferred, but that may not be the case with -R */ | |
176 | + if (fd2 == -1 && relative_paths && errno == ENOENT | |
177 | + && create_directory_path(fnametmp, orig_umask) == 0) { | |
178 | + strlcpy(fnametmp, template, sizeof fnametmp); | |
179 | + fd2 = do_mkstemp(fnametmp, file->mode & INITACCESSPERMS); | |
180 | + } | |
181 | + if (fd2 == -1) { | |
fe6407b5 WD |
182 | + rsyserr(FERROR, errno, "mkstemp %s failed", |
183 | + full_fname(fnametmp)); | |
a2d23604 WD |
184 | + receive_data(f_in,mapbuf,-1,NULL,file->length); |
185 | + if (mapbuf) unmap_file(mapbuf); | |
186 | + if (fd1 != -1) close(fd1); | |
187 | + continue; | |
188 | + } | |
189 | } | |
190 | ||
191 | cleanup_set(fnametmp, fname, file, mapbuf, fd1, fd2); | |
fe6407b5 WD |
192 | --- rsync.c 15 May 2004 19:31:10 -0000 1.139 |
193 | +++ rsync.c 15 May 2004 20:23:19 -0000 | |
7f2baf27 WD |
194 | @@ -31,6 +31,7 @@ extern int am_generator; |
195 | extern int preserve_uid; | |
a2d23604 | 196 | extern int preserve_gid; |
a2d23604 WD |
197 | extern int make_backups; |
198 | +extern int inplace; | |
199 | ||
200 | ||
201 | /* | |
7f2baf27 | 202 | @@ -235,6 +236,11 @@ void finish_transfer(char *fname, char * |
a2d23604 WD |
203 | |
204 | if (make_backups && !make_backup(fname)) | |
205 | return; | |
206 | + | |
207 | + if (inplace) { | |
208 | + set_perms(fname,file,NULL,0); | |
209 | + return; | |
210 | + } | |
211 | ||
212 | /* move tmp file over real file */ | |
213 | ret = robust_rename(fnametmp, fname, file->mode & INITACCESSPERMS); | |
ea238f1c | 214 | --- rsync.yo 7 May 2004 00:18:37 -0000 1.169 |
fe6407b5 | 215 | +++ rsync.yo 15 May 2004 20:23:20 -0000 |
a2d23604 WD |
216 | @@ -289,6 +289,7 @@ verb( |
217 | --backup-dir make backups into this directory | |
218 | --suffix=SUFFIX backup suffix (default ~ w/o --backup-dir) | |
219 | -u, --update update only (don't overwrite newer files) | |
220 | + --inplace update the destination file inplace | |
221 | -l, --links copy symlinks as symlinks | |
222 | -L, --copy-links copy the referent of all symlinks | |
223 | --copy-unsafe-links copy the referent of "unsafe" symlinks | |
ea238f1c | 224 | @@ -477,6 +478,17 @@ is on the objects. In other words, if t |
a2d23604 WD |
225 | symlink where the destination has a file, the transfer would occur |
226 | regardless of the timestamps. This might change in the future (feel | |
227 | free to comment on this on the mailing list if you have an opinion). | |
228 | + | |
229 | +dit(bf(--inplace)) This causes rsync not to create a new copy of the file | |
230 | +and then move it into place. Instead rsync will overwrite the existing | |
231 | +file, meaning that the rsync algorithm can't extract the full ammount of | |
232 | +network reduction it might otherwise. | |
233 | + | |
234 | +This option is useful for transfer of large files with block based changes | |
235 | +and also on systems that are disk bound not network bound. | |
236 | + | |
237 | +WARNING: If the transfer is interrupted, you will have an inconsistent file | |
238 | +and the transfer should be run again. | |
239 | ||
240 | dit(bf(-l, --links)) When symlinks are encountered, recreate the | |
241 | symlink on the destination. |