1 Patch from Mark Curtis to implement the --inplace option.
3 --- match.c 21 May 2004 08:27:04 -0000 1.62
4 +++ match.c 21 May 2004 09:03:09 -0000
5 @@ -23,6 +23,7 @@ extern int verbose;
7 extern int do_progress;
8 extern int checksum_seed;
11 typedef unsigned short tag;
13 @@ -200,6 +201,10 @@ static void hash_search(int f,struct sum
14 if (l != s->sums[i].len)
17 + /* if inplace, make sure the offset is greater than where we are */
18 + if (inplace && offset > s->sums[i].offset)
22 rprintf(FINFO,"potential match at %.0f target=%.0f %.0f sum=%08x\n",
23 (double)offset,(double)j,(double)i,sum);
24 --- options.c 6 May 2004 21:08:01 -0000 1.148
25 +++ options.c 21 May 2004 09:03:09 -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 @@ -939,6 +945,9 @@ void server_options(char **args,int *arg
61 if (opt_ignore_existing && am_sender)
62 args[ac++] = "--ignore-existing";
65 + args[ac++] = "--inplace";
68 args[ac++] = "--temp-dir";
70 --- receiver.c 21 May 2004 08:27:04 -0000 1.79
71 +++ receiver.c 21 May 2004 09:03:09 -0000
72 @@ -47,6 +47,7 @@ extern int ignore_errors;
73 extern int orig_umask;
74 extern int keep_partial;
75 extern int checksum_seed;
78 static void delete_one(char *fn, int is_dir)
80 @@ -252,16 +253,28 @@ static int receive_data(int f_in,struct
84 - if (fd != -1 && write_file(fd,map,len) != (int) len) {
85 - rsyserr(FERROR, errno, "write failed on %s",
87 - exit_cleanup(RERR_FILEIO);
88 + if (!inplace || offset != offset2) {
89 + if (fd != -1 && write_file(fd,map,len) != (int) len) {
90 + rsyserr(FERROR, errno, "write failed on %s",
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 @@ -413,37 +426,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 + rsyserr(FERROR, errno, "open %s failed",
127 + full_fname(fnametmp));
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 - rsyserr(FERROR, errno, "mkstemp %s failed",
167 - full_fname(fnametmp));
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 + rsyserr(FERROR, errno, "mkstemp %s failed",
183 + full_fname(fnametmp));
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 21 May 2004 08:43:03 -0000 1.140
193 +++ rsync.c 21 May 2004 09:03:09 -0000
194 @@ -34,6 +34,7 @@ extern int force_delete;
196 extern int make_backups;
197 extern char *backup_dir;
202 @@ -239,6 +240,11 @@ void finish_transfer(char *fname, char *
203 if (make_backups && !make_backup(fname))
207 + set_perms(fname,file,NULL,0);
211 /* move tmp file over real file */
212 ret = robust_rename(fnametmp, fname, file->mode & INITACCESSPERMS);
214 --- rsync.yo 7 May 2004 00:18:37 -0000 1.169
215 +++ rsync.yo 21 May 2004 09:03:10 -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 @@ -478,6 +479,17 @@ symlink where the destination has a file
225 regardless of the timestamps. This might change in the future (feel
226 free to comment on this on the mailing list if you have an opinion).
228 +dit(bf(--inplace)) This causes rsync not to create a new copy of the file
229 +and then move it into place. Instead rsync will overwrite the existing
230 +file, meaning that the rsync algorithm can't extract the full ammount of
231 +network reduction it might otherwise.
233 +This option is useful for transfer of large files with block based changes
234 +and also on systems that are disk bound not network bound.
236 +WARNING: If the transfer is interrupted, you will have an inconsistent file
237 +and the transfer should be run again.
239 dit(bf(-l, --links)) When symlinks are encountered, recreate the
240 symlink on the destination.