versions prior to 1.7.0 (protcol version 17) cannot talk to
[rsync/rsync.git] / generator.c
CommitLineData
ef1aa910 1/* -*- c-file-style: "linux" -*-
91262d5d
MP
2
3 rsync -- fast file replication program
2cda2560
WD
4
5 Copyright (C) 1996-2000 by Andrew Tridgell
2f03f956 6 Copyright (C) Paul Mackerras 1996
91262d5d 7 Copyright (C) 2002 by Martin Pool <mbp@samba.org>
2cda2560 8
2f03f956
AT
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2 of the License, or
12 (at your option) any later version.
2cda2560 13
2f03f956
AT
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
2cda2560 18
2f03f956
AT
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22*/
23
24#include "rsync.h"
25
26extern int verbose;
27extern int dry_run;
28extern int relative_paths;
29extern int preserve_links;
30extern int am_root;
31extern int preserve_devices;
32extern int preserve_hard_links;
33extern int update_only;
3d6feada 34extern int opt_ignore_existing;
2f03f956
AT
35extern int block_size;
36extern int csum_length;
37extern int ignore_times;
f83f0548 38extern int size_only;
2f03f956
AT
39extern int io_timeout;
40extern int remote_version;
41extern int always_checksum;
5b56cc19 42extern int modify_window;
60c8d7bc 43extern char *compare_dest;
59c95e42 44extern int link_dest;
2f03f956
AT
45
46
47/* choose whether to skip a particular file */
48static int skip_file(char *fname,
49 struct file_struct *file, STRUCT_STAT *st)
50{
51 if (st->st_size != file->length) {
52 return 0;
53 }
59c95e42 54 if (link_dest) {
bb24028f
S
55 extern int preserve_perms;
56 extern int preserve_uid;
57 extern int preserve_gid;
58
6e128863
S
59 if(preserve_perms
60 && (st->st_mode & ~_S_IFMT) != (file->mode & ~_S_IFMT))
bb24028f
S
61 return 0;
62
63 if (preserve_uid && st->st_uid != file->uid)
59c95e42 64 return 0;
bb24028f
S
65
66 if (preserve_gid && st->st_gid != file->gid)
59c95e42 67 return 0;
59c95e42
DD
68 }
69
2cda2560 70 /* if always checksum is set then we use the checksum instead
2f03f956
AT
71 of the file time to determine whether to sync */
72 if (always_checksum && S_ISREG(st->st_mode)) {
73 char sum[MD4_SUM_LENGTH];
60c8d7bc
DD
74 char fnamecmpdest[MAXPATHLEN];
75
76 if (compare_dest != NULL) {
77 if (access(fname, 0) != 0) {
8950ac03 78 snprintf(fnamecmpdest,MAXPATHLEN,"%s/%s",
2cda2560 79 compare_dest,fname);
60c8d7bc
DD
80 fname = fnamecmpdest;
81 }
82 }
2f03f956 83 file_checksum(fname,sum,st->st_size);
f855a7d0
AT
84 if (remote_version < 21) {
85 return (memcmp(sum,file->sum,2) == 0);
86 } else {
87 return (memcmp(sum,file->sum,MD4_SUM_LENGTH) == 0);
88 }
2f03f956
AT
89 }
90
f83f0548
AT
91 if (size_only) {
92 return 1;
93 }
94
2f03f956
AT
95 if (ignore_times) {
96 return 0;
97 }
98
5b56cc19 99 return (cmp_modtime(st->st_mtime,file->modtime) == 0);
2f03f956
AT
100}
101
102
103/* use a larger block size for really big files */
104static int adapt_block_size(struct file_struct *file, int bsize)
105{
106 int ret;
107
108 if (bsize != BLOCK_SIZE) return bsize;
109
110 ret = file->length / (10000); /* rough heuristic */
111 ret = ret & ~15; /* multiple of 16 */
112 if (ret < bsize) ret = bsize;
113 if (ret > CHUNK_SIZE/2) ret = CHUNK_SIZE/2;
114 return ret;
115}
116
117
118/*
80605142 119 send a header that says "we have no checksums" down the f_out fd
2f03f956 120 */
80605142 121static void send_null_sums(int f_out)
2f03f956 122{
80605142
WD
123 write_int(f_out, 0);
124 write_int(f_out, block_size);
125 write_int(f_out, 0);
2f03f956
AT
126}
127
bceec82f 128
80605142 129
bceec82f
MP
130/**
131 * Perhaps we want to just send an empty checksum set for this file,
132 * which will force the whole thing to be literally transferred.
133 *
134 * When do we do this? If the user's explicitly said they
135 * want the whole thing, or if { they haven't explicitly
136 * requested a delta, and it's local but not batch mode.}
137 *
138 * Whew. */
139static BOOL disable_deltas_p(void)
140{
2cda2560 141 extern int whole_file;
bceec82f
MP
142 extern int local_server;
143 extern int write_batch;
144
2cda2560 145 if (whole_file > 0)
bceec82f 146 return True;
2cda2560 147 if (whole_file == 0 || write_batch)
bceec82f 148 return False;
2cda2560 149 return local_server;
bceec82f
MP
150}
151
152
80605142
WD
153/*
154 * Generate and send a stream of signatures/checksums that describe a buffer
e66dfd18 155 *
80605142
WD
156 * Generate approximately one checksum every block_len bytes.
157 */
158static void generate_and_send_sums(struct map_struct *buf, OFF_T len,
159 int block_len, int f_out)
2f03f956 160{
80605142
WD
161 size_t i;
162 struct sum_struct sum;
2f03f956
AT
163 OFF_T offset = 0;
164
80605142
WD
165 sum.count = (len + (block_len - 1)) / block_len;
166 sum.remainder = (len % block_len);
167 sum.n = block_len;
168 sum.flength = len;
169 /* not needed here sum.sums = NULL; */
2f03f956 170
80605142 171 if (sum.count && verbose > 3) {
67684d03 172 rprintf(FINFO, "count=%ld rem=%ld n=%ld flength=%.0f\n",
80605142
WD
173 (long) sum.count, (long) sum.remainder,
174 (long) sum.n, (double) sum.flength);
67684d03 175 }
e66dfd18 176
80605142
WD
177 write_int(f_out, sum.count);
178 write_int(f_out, sum.n);
179 write_int(f_out, sum.remainder);
2f03f956 180
80605142
WD
181 for (i = 0; i < sum.count; i++) {
182 int n1 = MIN(len, block_len);
e66dfd18 183 char *map = map_ptr(buf, offset, n1);
80605142
WD
184 uint32 sum1 = get_checksum1(map, n1);
185 char sum2[SUM_LENGTH];
2f03f956 186
80605142 187 get_checksum2(map, n1, sum2);
2f03f956 188
80605142 189 if (verbose > 3) {
e66dfd18 190 rprintf(FINFO,
80605142
WD
191 "chunk[%d] offset=%.0f len=%d sum1=%08lx\n",
192 i, (double) offset, n1, (unsigned long) sum1);
193 }
194 write_int(f_out, sum1);
195 write_buf(f_out, sum2, csum_length);
2f03f956
AT
196 len -= n1;
197 offset += n1;
198 }
2f03f956
AT
199}
200
201
ef1aa910 202
420ef2c4
MP
203/**
204 * Acts on file number @p i from @p flist, whose name is @p fname.
ef1aa910
MP
205 *
206 * First fixes up permissions, then generates checksums for the file.
207 *
420ef2c4
MP
208 * @note This comment was added later by mbp who was trying to work it
209 * out. It might be wrong.
2cda2560 210 **/
420ef2c4 211void recv_generator(char *fname, struct file_list *flist, int i, int f_out)
2cda2560 212{
2f03f956
AT
213 int fd;
214 STRUCT_STAT st;
215 struct map_struct *buf;
2f03f956
AT
216 int statret;
217 struct file_struct *file = flist->files[i];
375a4556
DD
218 char *fnamecmp;
219 char fnamecmpbuf[MAXPATHLEN];
220 extern char *compare_dest;
f7632fc6 221 extern int list_only;
4df9f368 222 extern int preserve_perms;
1347d512 223 extern int only_existing;
b35d0d8e 224 extern int orig_umask;
f7632fc6
AT
225
226 if (list_only) return;
2f03f956
AT
227
228 if (verbose > 2)
229 rprintf(FINFO,"recv_generator(%s,%d)\n",fname,i);
230
231 statret = link_stat(fname,&st);
63787382 232
1347d512
AT
233 if (only_existing && statret == -1 && errno == ENOENT) {
234 /* we only want to update existing files */
1bbd10fe 235 if (verbose > 1) rprintf(FINFO, "not creating new file \"%s\"\n",fname);
1347d512
AT
236 return;
237 }
238
2cda2560
WD
239 if (statret == 0 &&
240 !preserve_perms &&
4df9f368
AT
241 (S_ISDIR(st.st_mode) == S_ISDIR(file->mode))) {
242 /* if the file exists already and we aren't perserving
2cda2560
WD
243 * permissions then act as though the remote end sent
244 * us the file permissions we already have */
7e0ca8e2 245 file->mode = (file->mode & _S_IFMT) | (st.st_mode & ~_S_IFMT);
4df9f368
AT
246 }
247
2f03f956 248 if (S_ISDIR(file->mode)) {
2cda2560
WD
249 /* The file to be received is a directory, so we need
250 * to prepare appropriately. If there is already a
251 * file of that name and it is *not* a directory, then
252 * we need to delete it. If it doesn't exist, then
253 * recursively create it. */
254
85d4d142 255 if (dry_run) return; /* XXXX -- might cause inaccuracies?? -- mbp */
2f03f956 256 if (statret == 0 && !S_ISDIR(st.st_mode)) {
c7c11a0d 257 if (robust_unlink(fname) != 0) {
85d4d142
MP
258 rprintf(FERROR, RSYNC_NAME
259 ": recv_generator: unlink \"%s\" to make room for directory: %s\n",
2cda2560 260 fname,strerror(errno));
2f03f956
AT
261 return;
262 }
263 statret = -1;
264 }
265 if (statret != 0 && do_mkdir(fname,file->mode) != 0 && errno != EEXIST) {
2cda2560
WD
266 if (!(relative_paths && errno==ENOENT &&
267 create_directory_path(fname, orig_umask)==0 &&
2f03f956 268 do_mkdir(fname,file->mode)==0)) {
85d4d142 269 rprintf(FERROR, RSYNC_NAME ": recv_generator: mkdir \"%s\": %s (2)\n",
2f03f956
AT
270 fname,strerror(errno));
271 }
272 }
2cda2560 273 /* f_out is set to -1 when doing final directory
de343e3c 274 permission and modification time repair */
2cda2560 275 if (set_perms(fname,file,NULL,0) && verbose && (f_out != -1))
2f03f956
AT
276 rprintf(FINFO,"%s/\n",fname);
277 return;
278 }
279
280 if (preserve_links && S_ISLNK(file->mode)) {
281#if SUPPORT_LINKS
282 char lnk[MAXPATHLEN];
283 int l;
284 extern int safe_symlinks;
285
286 if (safe_symlinks && unsafe_symlink(file->link, fname)) {
287 if (verbose) {
1bbd10fe 288 rprintf(FINFO,"ignoring unsafe symlink \"%s\" -> \"%s\"\n",
2f03f956
AT
289 fname,file->link);
290 }
291 return;
292 }
293 if (statret == 0) {
294 l = readlink(fname,lnk,MAXPATHLEN-1);
295 if (l > 0) {
296 lnk[l] = 0;
85d4d142
MP
297 /* A link already pointing to the
298 * right place -- no further action
299 * required. */
7e0ca8e2 300 if (strcmp(lnk,file->link) == 0) {
2f03f956
AT
301 set_perms(fname,file,&st,1);
302 return;
303 }
2cda2560 304 }
85d4d142
MP
305 /* Not a symlink, so delete whatever's
306 * already there and put a new symlink
2cda2560 307 * in place. */
4b3977bf 308 delete_file(fname);
2f03f956 309 }
2f03f956 310 if (do_symlink(file->link,fname) != 0) {
85d4d142 311 rprintf(FERROR,RSYNC_NAME": symlink \"%s\" -> \"%s\": %s\n",
2f03f956
AT
312 fname,file->link,strerror(errno));
313 } else {
314 set_perms(fname,file,NULL,0);
315 if (verbose) {
1bbd10fe 316 rprintf(FINFO,"%s -> %s\n", fname,file->link);
2f03f956
AT
317 }
318 }
319#endif
320 return;
321 }
322
323#ifdef HAVE_MKNOD
324 if (am_root && preserve_devices && IS_DEVICE(file->mode)) {
2cda2560 325 if (statret != 0 ||
2f03f956 326 st.st_mode != file->mode ||
2cda2560 327 st.st_rdev != file->rdev) {
2f03f956
AT
328 delete_file(fname);
329 if (verbose > 2)
330 rprintf(FINFO,"mknod(%s,0%o,0x%x)\n",
331 fname,(int)file->mode,(int)file->rdev);
332 if (do_mknod(fname,file->mode,file->rdev) != 0) {
333 rprintf(FERROR,"mknod %s : %s\n",fname,strerror(errno));
334 } else {
335 set_perms(fname,file,NULL,0);
336 if (verbose)
337 rprintf(FINFO,"%s\n",fname);
338 }
339 } else {
340 set_perms(fname,file,&st,1);
341 }
342 return;
343 }
344#endif
345
346 if (preserve_hard_links && check_hard_link(file)) {
347 if (verbose > 1)
fba31efb 348 rprintf(FINFO, "recv_generator: \"%s\" is a hard link\n",f_name(file));
2f03f956
AT
349 return;
350 }
351
352 if (!S_ISREG(file->mode)) {
1bbd10fe 353 rprintf(FINFO, "skipping non-regular file \"%s\"\n",fname);
2f03f956
AT
354 return;
355 }
356
375a4556
DD
357 fnamecmp = fname;
358
359 if ((statret == -1) && (compare_dest != NULL)) {
360 /* try the file at compare_dest instead */
361 int saveerrno = errno;
8950ac03 362 snprintf(fnamecmpbuf,MAXPATHLEN,"%s/%s",compare_dest,fname);
375a4556
DD
363 statret = link_stat(fnamecmpbuf,&st);
364 if (!S_ISREG(st.st_mode))
365 statret = -1;
366 if (statret == -1)
367 errno = saveerrno;
59c95e42
DD
368#if HAVE_LINK
369 else if (link_dest && !dry_run) {
370 if (do_link(fnamecmpbuf, fname) != 0) {
371 if (verbose > 0)
372 rprintf(FINFO,"link %s => %s : %s\n",
373 fnamecmpbuf,
374 fname,
375 strerror(errno));
376 }
377 fnamecmp = fnamecmpbuf;
378 }
379#endif
375a4556
DD
380 else
381 fnamecmp = fnamecmpbuf;
382 }
383
2f03f956
AT
384 if (statret == -1) {
385 if (errno == ENOENT) {
386 write_int(f_out,i);
80605142 387 if (!dry_run) send_null_sums(f_out);
2f03f956
AT
388 } else {
389 if (verbose > 1)
fb47591d
MP
390 rprintf(FERROR, RSYNC_NAME
391 ": recv_generator failed to open \"%s\": %s\n",
392 fname, strerror(errno));
2f03f956
AT
393 }
394 return;
395 }
396
397 if (!S_ISREG(st.st_mode)) {
398 if (delete_file(fname) != 0) {
399 return;
400 }
401
402 /* now pretend the file didn't exist */
403 write_int(f_out,i);
80605142 404 if (!dry_run) send_null_sums(f_out);
2f03f956
AT
405 return;
406 }
407
2cda2560 408 if (opt_ignore_existing && fnamecmp == fname) {
3d6feada
MP
409 if (verbose > 1)
410 rprintf(FINFO,"%s exists\n",fname);
411 return;
2cda2560 412 }
3d6feada 413
5b56cc19 414 if (update_only && cmp_modtime(st.st_mtime,file->modtime)>0 && fnamecmp == fname) {
2f03f956
AT
415 if (verbose > 1)
416 rprintf(FINFO,"%s is newer\n",fname);
417 return;
418 }
419
420 if (skip_file(fname, file, &st)) {
bd4ed7f7
DD
421 if (fnamecmp == fname)
422 set_perms(fname,file,&st,1);
2f03f956
AT
423 return;
424 }
425
426 if (dry_run) {
427 write_int(f_out,i);
428 return;
429 }
430
bceec82f 431 if (disable_deltas_p()) {
2f03f956 432 write_int(f_out,i);
80605142 433 send_null_sums(f_out);
2f03f956
AT
434 return;
435 }
436
2cda2560 437 /* open the file */
8c9fd200 438 fd = do_open(fnamecmp, O_RDONLY, 0);
2f03f956
AT
439
440 if (fd == -1) {
85d4d142 441 rprintf(FERROR,RSYNC_NAME": failed to open \"%s\", continuing : %s\n",fnamecmp,strerror(errno));
60be6acf
DD
442 /* pretend the file didn't exist */
443 write_int(f_out,i);
80605142 444 send_null_sums(f_out);
2f03f956
AT
445 return;
446 }
447
448 if (st.st_size > 0) {
449 buf = map_file(fd,st.st_size);
450 } else {
451 buf = NULL;
452 }
453
454 if (verbose > 3)
5f808dfb 455 rprintf(FINFO,"gen mapped %s of size %.0f\n",fnamecmp,(double)st.st_size);
2f03f956 456
2f03f956 457 if (verbose > 2)
80605142 458 rprintf(FINFO, "generating and sending sums for %d\n", i);
2f03f956
AT
459
460 write_int(f_out,i);
80605142
WD
461 generate_and_send_sums(buf, st.st_size,
462 adapt_block_size(file, block_size), f_out);
2f03f956
AT
463
464 close(fd);
465 if (buf) unmap_file(buf);
2f03f956
AT
466}
467
468
469
470void generate_files(int f,struct file_list *flist,char *local_name,int f_recv)
471{
472 int i;
473 int phase=0;
474
475 if (verbose > 2)
476 rprintf(FINFO,"generator starting pid=%d count=%d\n",
477 (int)getpid(),flist->count);
478
3e7053ac
MP
479 if (verbose >= 2) {
480 rprintf(FINFO,
2cda2560 481 disable_deltas_p()
3e7053ac
MP
482 ? "delta-transmission disabled for local transfer or --whole-file\n"
483 : "delta transmission enabled\n");
484 }
2cda2560 485
a57873b7
AT
486 /* we expect to just sit around now, so don't exit on a
487 timeout. If we really get a timeout then the other process should
488 exit */
489 io_timeout = 0;
490
2f03f956
AT
491 for (i = 0; i < flist->count; i++) {
492 struct file_struct *file = flist->files[i];
493 mode_t saved_mode = file->mode;
494 if (!file->basename) continue;
495
496 /* we need to ensure that any directories we create have writeable
497 permissions initially so that we can create the files within
498 them. This is then fixed after the files are transferred */
499 if (!am_root && S_ISDIR(file->mode)) {
500 file->mode |= S_IWUSR; /* user write */
2cda2560
WD
501 /* XXX: Could this be causing a problem on SCO? Perhaps their
502 * handling of permissions is strange? */
2f03f956
AT
503 }
504
2cda2560 505 recv_generator(local_name?local_name:f_name(file), flist,i,f);
2f03f956
AT
506
507 file->mode = saved_mode;
508 }
509
510 phase++;
511 csum_length = SUM_LENGTH;
512 ignore_times=1;
513
514 if (verbose > 2)
515 rprintf(FINFO,"generate_files phase=%d\n",phase);
516
517 write_int(f,-1);
518
bc63ae3f
S
519 /* files can cycle through the system more than once
520 * to catch initial checksum errors */
521 for (i=read_int(f_recv); i != -1; i=read_int(f_recv)) {
522 struct file_struct *file = flist->files[i];
523 recv_generator(local_name?local_name:f_name(file), flist,i,f);
524 }
2f03f956 525
bc63ae3f
S
526 phase++;
527 if (verbose > 2)
528 rprintf(FINFO,"generate_files phase=%d\n",phase);
2f03f956 529
bc63ae3f 530 write_int(f,-1);
2f03f956 531}