1 Patch from Mark Curtis to implement the --inplace option.
3 --- match.c 3 Jan 2004 19:28:03 -0000 1.60
4 +++ match.c 27 Apr 2004 23:26:09 -0000
8 extern int do_progress;
11 typedef unsigned short tag;
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)
19 + /* if inplace, make sure the offset is greater than where we are */
20 + if (inplace && offset > s->sums[i].offset)
24 --- options.c 17 Apr 2004 17:07:23 -0000 1.147
25 +++ options.c 27 Apr 2004 23:26:10 -0000
26 @@ -91,6 +91,7 @@ int ignore_errors = 0;
27 int modify_window = 0;
29 int checksum_seed = 0;
31 unsigned int block_size = 0;
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)
54 + if (inplace && keep_partial)
59 if (*argc != 2 && !(am_server && am_sender && *argc == 1)) {
60 @@ -938,6 +944,9 @@ void server_options(char **args,int *arg
62 if (opt_ignore_existing && am_sender)
63 args[ac++] = "--ignore-existing";
66 + args[ac++] = "--inplace";
69 args[ac++] = "--temp-dir";
70 --- receiver.c 27 Apr 2004 19:51:33 -0000 1.76
71 +++ receiver.c 27 Apr 2004 23:26:10 -0000
72 @@ -45,6 +45,7 @@ extern int cleanup_got_literal;
74 extern int ignore_errors;
75 extern int orig_umask;
78 static void delete_one(char *fn, int is_dir)
80 @@ -249,16 +250,28 @@ static int receive_data(int f_in,struct
84 - if (fd != -1 && write_file(fd,map,len) != (int) len) {
85 - rprintf(FERROR, "write failed on %s: %s\n",
86 - full_fname(fname), strerror(errno));
87 - exit_cleanup(RERR_FILEIO);
88 + if (!inplace || offset != offset2) {
89 + if (fd != -1 && write_file(fd,map,len) != (int) len) {
90 + rprintf(FERROR, "write failed on %s: %s\n",
91 + full_fname(fname), strerror(errno));
92 + exit_cleanup(RERR_FILEIO);
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);
105 flush_write_file(fd);
108 + ftruncate(fd, offset);
111 end_progress(total_size);
113 @@ -410,37 +423,50 @@ int recv_files(int f_in,struct file_list
117 - if (!get_tmpname(fnametmp,fname)) {
118 - if (mapbuf) unmap_file(mapbuf);
119 - if (fd1 != -1) close(fd1);
122 + /* We now check to see if we are writing file "inplace" */
124 + fd2 = do_open(fnamecmp, O_WRONLY|O_CREAT, 0);
126 + rprintf(FERROR, "open %s failed: %s\n",
127 + full_fname(fnametmp), strerror(errno));
128 + receive_data(f_in,mapbuf,-1,NULL,file->length);
129 + if (mapbuf) unmap_file(mapbuf);
130 + if (fd1 != -1) close(fd1);
134 + if (!get_tmpname(fnametmp,fname)) {
135 + if (mapbuf) unmap_file(mapbuf);
136 + if (fd1 != -1) close(fd1);
140 - strlcpy(template, fnametmp, sizeof template);
141 + strlcpy(template, fnametmp, sizeof template);
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);
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);
166 - rprintf(FERROR, "mkstemp %s failed: %s\n",
167 - full_fname(fnametmp), strerror(errno));
168 - receive_data(f_in,mapbuf,-1,NULL,file->length);
169 - if (mapbuf) unmap_file(mapbuf);
170 - if (fd1 != -1) close(fd1);
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);
182 + rprintf(FERROR, "mkstemp %s failed: %s\n",
183 + full_fname(fnametmp), strerror(errno));
184 + receive_data(f_in,mapbuf,-1,NULL,file->length);
185 + if (mapbuf) unmap_file(mapbuf);
186 + if (fd1 != -1) close(fd1);
191 cleanup_set(fnametmp, fname, file, mapbuf, fd1, fd2);
192 --- rsync.c 23 Mar 2004 16:16:15 -0000 1.135
193 +++ rsync.c 27 Apr 2004 23:26:11 -0000
194 @@ -33,6 +33,7 @@ extern int preserve_uid;
195 extern int preserve_gid;
196 extern int preserve_perms;
197 extern int make_backups;
202 @@ -234,6 +235,11 @@ void finish_transfer(char *fname, char *
204 if (make_backups && !make_backup(fname))
208 + set_perms(fname,file,NULL,0);
212 /* move tmp file over real file */
213 ret = robust_rename(fnametmp, fname, file->mode & INITACCESSPERMS);
214 --- rsync.yo 27 Apr 2004 03:55:37 -0000 1.165
215 +++ rsync.yo 27 Apr 2004 23:26:12 -0000
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
224 @@ -475,6 +476,17 @@ is on the objects. In other words, if t
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).
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.
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.
237 +WARNING: If the transfer is interrupted, you will have an inconsistent file
238 +and the transfer should be run again.
240 dit(bf(-l, --links)) When symlinks are encountered, recreate the
241 symlink on the destination.