- Improved the recently-added exclude-list comment.
[rsync/rsync-patches.git] / inplace.diff
CommitLineData
a2d23604
WD
1Patch from Mark Curtis to implement the --inplace option.
2
7f2baf27
WD
3--- match.c 13 May 2004 06:46:20 -0000 1.61
4+++ match.c 13 May 2004 19:02:25 -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
7f2baf27 25+++ options.c 13 May 2004 19:02:25 -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";
7f2baf27
WD
70--- receiver.c 13 May 2004 07:08:22 -0000 1.77
71+++ receiver.c 13 May 2004 19:02:25 -0000
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 {
7f2baf27 80@@ -250,16 +251,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) {
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);
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
7f2baf27 113@@ -411,37 +424,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) {
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);
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) {
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);
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) {
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);
187+ continue;
188+ }
189 }
190
191 cleanup_set(fnametmp, fname, file, mapbuf, fd1, fd2);
7f2baf27
WD
192--- rsync.c 13 May 2004 18:51:22 -0000 1.138
193+++ rsync.c 13 May 2004 19:02:25 -0000
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
7f2baf27 215+++ rsync.yo 13 May 2004 19:02:26 -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.