Got rid of delete_one() since we can (and do) use the updated
[rsync/rsync.git] / generator.c
... / ...
CommitLineData
1/* -*- c-file-style: "linux" -*-
2
3 rsync -- fast file replication program
4
5 Copyright (C) 1996-2000 by Andrew Tridgell
6 Copyright (C) Paul Mackerras 1996
7 Copyright (C) 2002 by Martin Pool <mbp@samba.org>
8
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.
13
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.
18
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 keep_dirlinks;
30extern int preserve_links;
31extern int am_root;
32extern int preserve_devices;
33extern int preserve_hard_links;
34extern int preserve_perms;
35extern int preserve_uid;
36extern int preserve_gid;
37extern int update_only;
38extern int opt_ignore_existing;
39extern int inplace;
40extern int make_backups;
41extern int csum_length;
42extern int ignore_times;
43extern int size_only;
44extern OFF_T max_size;
45extern int io_timeout;
46extern int protocol_version;
47extern int always_checksum;
48extern char *partial_dir;
49extern char *basis_dir[];
50extern int compare_dest;
51extern int link_dest;
52extern int whole_file;
53extern int local_server;
54extern int list_only;
55extern int read_batch;
56extern int only_existing;
57extern int orig_umask;
58extern int safe_symlinks;
59extern long block_size; /* "long" because popt can't set an int32. */
60
61extern struct exclude_list_struct server_exclude_list;
62
63static int unchanged_attrs(struct file_struct *file, STRUCT_STAT *st)
64{
65 if (preserve_perms
66 && (st->st_mode & CHMOD_BITS) != (file->mode & CHMOD_BITS))
67 return 0;
68
69 if (am_root && preserve_uid && st->st_uid != file->uid)
70 return 0;
71
72 if (preserve_gid && file->gid != GID_NONE && st->st_gid != file->gid)
73 return 0;
74
75 return 1;
76}
77
78/* Perform our quick-check heuristic for determining if a file is unchanged. */
79static int unchanged_file(char *fn, struct file_struct *file, STRUCT_STAT *st)
80{
81 if (st->st_size != file->length)
82 return 0;
83
84 /* if always checksum is set then we use the checksum instead
85 of the file time to determine whether to sync */
86 if (always_checksum && S_ISREG(st->st_mode)) {
87 char sum[MD4_SUM_LENGTH];
88 file_checksum(fn, sum, st->st_size);
89 return memcmp(sum, file->u.sum, protocol_version < 21 ? 2
90 : MD4_SUM_LENGTH) == 0;
91 }
92
93 if (size_only)
94 return 1;
95
96 if (ignore_times)
97 return 0;
98
99 return cmp_modtime(st->st_mtime, file->modtime) == 0;
100}
101
102
103/*
104 * NULL sum_struct means we have no checksums
105 */
106void write_sum_head(int f, struct sum_struct *sum)
107{
108 static struct sum_struct null_sum;
109
110 if (sum == NULL)
111 sum = &null_sum;
112
113 write_int(f, sum->count);
114 write_int(f, sum->blength);
115 if (protocol_version >= 27)
116 write_int(f, sum->s2length);
117 write_int(f, sum->remainder);
118}
119
120/*
121 * set (initialize) the size entries in the per-file sum_struct
122 * calculating dynamic block and checksum sizes.
123 *
124 * This is only called from generate_and_send_sums() but is a separate
125 * function to encapsulate the logic.
126 *
127 * The block size is a rounded square root of file length.
128 *
129 * The checksum size is determined according to:
130 * blocksum_bits = BLOCKSUM_EXP + 2*log2(file_len) - log2(block_len)
131 * provided by Donovan Baarda which gives a probability of rsync
132 * algorithm corrupting data and falling back using the whole md4
133 * checksums.
134 *
135 * This might be made one of several selectable heuristics.
136 */
137static void sum_sizes_sqroot(struct sum_struct *sum, uint64 len)
138{
139 int32 blength;
140 int s2length;
141
142 if (block_size)
143 blength = block_size;
144 else if (len <= BLOCK_SIZE * BLOCK_SIZE)
145 blength = BLOCK_SIZE;
146 else {
147 int32 c;
148 uint64 l;
149 int cnt;
150 for (c = 1, l = len, cnt = 0; l >>= 2; c <<= 1, cnt++) {}
151 if (cnt >= 31 || c >= MAX_BLOCK_SIZE)
152 blength = MAX_BLOCK_SIZE;
153 else {
154 blength = 0;
155 do {
156 blength |= c;
157 if (len < (uint64)blength * blength)
158 blength &= ~c;
159 c >>= 1;
160 } while (c >= 8); /* round to multiple of 8 */
161 blength = MAX(blength, BLOCK_SIZE);
162 }
163 }
164
165 if (protocol_version < 27) {
166 s2length = csum_length;
167 } else if (csum_length == SUM_LENGTH) {
168 s2length = SUM_LENGTH;
169 } else {
170 int32 c;
171 uint64 l;
172 int b = BLOCKSUM_BIAS;
173 for (l = len; l >>= 1; b += 2) {}
174 for (c = blength; c >>= 1 && b; b--) {}
175 /* add a bit, subtract rollsum, round up. */
176 s2length = (b + 1 - 32 + 7) / 8; /* --optimize in compiler-- */
177 s2length = MAX(s2length, csum_length);
178 s2length = MIN(s2length, SUM_LENGTH);
179 }
180
181 sum->flength = len;
182 sum->blength = blength;
183 sum->s2length = s2length;
184 sum->count = (len + (blength - 1)) / blength;
185 sum->remainder = (len % blength);
186
187 if (sum->count && verbose > 2) {
188 rprintf(FINFO,
189 "count=%.0f rem=%ld blength=%ld s2length=%d flength=%.0f\n",
190 (double)sum->count, (long)sum->remainder, (long)sum->blength,
191 sum->s2length, (double)sum->flength);
192 }
193}
194
195
196/*
197 * Generate and send a stream of signatures/checksums that describe a buffer
198 *
199 * Generate approximately one checksum every block_len bytes.
200 */
201static void generate_and_send_sums(int fd, OFF_T len, int f_out, int f_copy)
202{
203 size_t i;
204 struct map_struct *mapbuf;
205 struct sum_struct sum;
206 OFF_T offset = 0;
207
208 sum_sizes_sqroot(&sum, len);
209
210 if (len > 0)
211 mapbuf = map_file(fd, len, MAX_MAP_SIZE, sum.blength);
212 else
213 mapbuf = NULL;
214
215 write_sum_head(f_out, &sum);
216
217 for (i = 0; i < sum.count; i++) {
218 int32 n1 = (int32)MIN(len, (OFF_T)sum.blength);
219 char *map = map_ptr(mapbuf, offset, n1);
220 uint32 sum1 = get_checksum1(map, n1);
221 char sum2[SUM_LENGTH];
222
223 if (f_copy >= 0)
224 full_write(f_copy, map, n1);
225
226 get_checksum2(map, n1, sum2);
227
228 if (verbose > 3) {
229 rprintf(FINFO,
230 "chunk[%.0f] offset=%.0f len=%ld sum1=%08lx\n",
231 (double)i, (double)offset, (long)n1,
232 (unsigned long)sum1);
233 }
234 write_int(f_out, sum1);
235 write_buf(f_out, sum2, sum.s2length);
236 len -= n1;
237 offset += n1;
238 }
239
240 if (mapbuf)
241 unmap_file(mapbuf);
242}
243
244
245
246/*
247 * Acts on file number @p i from @p flist, whose name is @p fname.
248 *
249 * First fixes up permissions, then generates checksums for the file.
250 *
251 * @note This comment was added later by mbp who was trying to work it
252 * out. It might be wrong.
253 */
254static void recv_generator(char *fname, struct file_struct *file, int i,
255 int f_out, int f_out_name)
256{
257 int fd = -1, f_copy = -1;
258 STRUCT_STAT st, partial_st;
259 struct file_struct *back_file = NULL;
260 int statret, stat_errno;
261 char *fnamecmp, *partialptr, *backupptr = NULL;
262 char fnamecmpbuf[MAXPATHLEN];
263 uchar fnamecmp_type;
264
265 if (list_only)
266 return;
267
268 if (verbose > 2)
269 rprintf(FINFO, "recv_generator(%s,%d)\n", safe_fname(fname), i);
270
271 if (server_exclude_list.head
272 && check_exclude(&server_exclude_list, fname,
273 S_ISDIR(file->mode)) < 0) {
274 if (verbose) {
275 rprintf(FINFO, "skipping server-excluded file \"%s\"\n",
276 safe_fname(fname));
277 }
278 return;
279 }
280
281 if (dry_run > 1) {
282 statret = -1;
283 stat_errno = ENOENT;
284 } else {
285 statret = link_stat(fname, &st,
286 keep_dirlinks && S_ISDIR(file->mode));
287 stat_errno = errno;
288 }
289
290 if (only_existing && statret == -1 && stat_errno == ENOENT) {
291 /* we only want to update existing files */
292 if (verbose > 1) {
293 rprintf(FINFO, "not creating new file \"%s\"\n",
294 safe_fname(fname));
295 }
296 return;
297 }
298
299 if (statret == 0 && !preserve_perms
300 && S_ISDIR(st.st_mode) == S_ISDIR(file->mode)) {
301 /* if the file exists already and we aren't perserving
302 * permissions then act as though the remote end sent
303 * us the file permissions we already have */
304 file->mode = (file->mode & ~CHMOD_BITS)
305 | (st.st_mode & CHMOD_BITS);
306 }
307
308 if (S_ISDIR(file->mode)) {
309 /* The file to be received is a directory, so we need
310 * to prepare appropriately. If there is already a
311 * file of that name and it is *not* a directory, then
312 * we need to delete it. If it doesn't exist, then
313 * recursively create it. */
314
315 if (dry_run)
316 return; /* TODO: causes inaccuracies -- fix */
317 if (statret == 0 && !S_ISDIR(st.st_mode)) {
318 if (robust_unlink(fname) != 0) {
319 rsyserr(FERROR, errno,
320 "recv_generator: unlink %s to make room for directory",
321 full_fname(fname));
322 return;
323 }
324 statret = -1;
325 }
326 if (statret != 0 && do_mkdir(fname,file->mode) != 0 && errno != EEXIST) {
327 if (!(relative_paths && errno == ENOENT
328 && create_directory_path(fname, orig_umask) == 0
329 && do_mkdir(fname, file->mode) == 0)) {
330 rsyserr(FERROR, errno,
331 "recv_generator: mkdir %s failed",
332 full_fname(fname));
333 }
334 }
335 /* f_out is set to -1 when doing final directory-permission
336 * and modification-time repair. */
337 if (set_perms(fname, file, statret ? NULL : &st, 0)
338 && verbose && f_out != -1)
339 rprintf(FINFO, "%s/\n", safe_fname(fname));
340 return;
341 } else if (max_size && file->length > max_size) {
342 if (verbose > 1)
343 rprintf(FINFO, "%s is over max-size\n", fname);
344 return;
345 }
346
347 if (preserve_links && S_ISLNK(file->mode)) {
348#if SUPPORT_LINKS
349 char lnk[MAXPATHLEN];
350 int l;
351
352 if (safe_symlinks && unsafe_symlink(file->u.link, fname)) {
353 if (verbose) {
354 rprintf(FINFO, "ignoring unsafe symlink %s -> \"%s\"\n",
355 full_fname(fname), file->u.link);
356 }
357 return;
358 }
359 if (statret == 0) {
360 l = readlink(fname,lnk,MAXPATHLEN-1);
361 if (l > 0) {
362 lnk[l] = 0;
363 /* A link already pointing to the
364 * right place -- no further action
365 * required. */
366 if (strcmp(lnk,file->u.link) == 0) {
367 set_perms(fname, file, &st,
368 PERMS_REPORT);
369 return;
370 }
371 }
372 /* Not a symlink, so delete whatever's
373 * already there and put a new symlink
374 * in place. */
375 delete_file(fname);
376 }
377 if (do_symlink(file->u.link,fname) != 0) {
378 rsyserr(FERROR, errno, "symlink %s -> \"%s\" failed",
379 full_fname(fname), safe_fname(file->u.link));
380 } else {
381 set_perms(fname,file,NULL,0);
382 if (verbose) {
383 rprintf(FINFO, "%s -> %s\n", safe_fname(fname),
384 safe_fname(file->u.link));
385 }
386 }
387#endif
388 return;
389 }
390
391 if (am_root && preserve_devices && IS_DEVICE(file->mode)) {
392 if (statret != 0 ||
393 st.st_mode != file->mode ||
394 st.st_rdev != file->u.rdev) {
395 delete_file(fname);
396 if (verbose > 2) {
397 rprintf(FINFO,"mknod(%s,0%o,0x%x)\n",
398 safe_fname(fname),
399 (int)file->mode, (int)file->u.rdev);
400 }
401 if (do_mknod(fname,file->mode,file->u.rdev) != 0) {
402 rsyserr(FERROR, errno, "mknod %s failed",
403 full_fname(fname));
404 } else {
405 set_perms(fname,file,NULL,0);
406 if (verbose) {
407 rprintf(FINFO, "%s\n",
408 safe_fname(fname));
409 }
410 }
411 } else {
412 set_perms(fname, file, &st, PERMS_REPORT);
413 }
414 return;
415 }
416
417 if (preserve_hard_links && hard_link_check(file, HL_CHECK_MASTER))
418 return;
419
420 if (!S_ISREG(file->mode)) {
421 rprintf(FINFO, "skipping non-regular file \"%s\"\n",
422 safe_fname(fname));
423 return;
424 }
425
426 fnamecmp = fname;
427 fnamecmp_type = FNAMECMP_FNAME;
428
429 if (statret == -1 && basis_dir[0] != NULL) {
430 int fallback_match = -1;
431 int match_level = 0;
432 int i = 0;
433 do {
434 pathjoin(fnamecmpbuf, sizeof fnamecmpbuf,
435 basis_dir[i], fname);
436 if (link_stat(fnamecmpbuf, &st, 0) == 0
437 && S_ISREG(st.st_mode)) {
438 statret = 0;
439 if (link_dest) {
440 if (!match_level) {
441 fallback_match = i;
442 match_level = 1;
443 } else if (match_level == 2
444 && !unchanged_attrs(file, &st))
445 continue;
446 if (!unchanged_file(fnamecmpbuf, file, &st))
447 continue;
448 fallback_match = i;
449 match_level = 2;
450 if (!unchanged_attrs(file, &st))
451 continue;
452 }
453 match_level = 3;
454 break;
455 }
456 } while (basis_dir[++i] != NULL);
457 if (statret == 0) {
458 if (match_level < 3) {
459 i = fallback_match;
460 pathjoin(fnamecmpbuf, sizeof fnamecmpbuf,
461 basis_dir[i], fname);
462 }
463#if HAVE_LINK
464 if (link_dest && match_level == 3 && !dry_run) {
465 if (do_link(fnamecmpbuf, fname) < 0) {
466 if (verbose) {
467 rsyserr(FINFO, errno,
468 "link %s => %s",
469 fnamecmpbuf,
470 safe_fname(fname));
471 }
472 fnamecmp = fnamecmpbuf;
473 fnamecmp_type = i;
474 }
475 } else
476#endif
477 {
478 fnamecmp = fnamecmpbuf;
479 fnamecmp_type = i;
480 }
481 }
482 }
483
484 if (statret == 0 && !S_ISREG(st.st_mode)) {
485 if (delete_file(fname) != 0)
486 return;
487 statret = -1;
488 stat_errno = ENOENT;
489 }
490
491 if (partial_dir && (partialptr = partial_dir_fname(fname)) != NULL
492 && link_stat(partialptr, &partial_st, 0) == 0
493 && S_ISREG(partial_st.st_mode)) {
494 if (statret == -1)
495 goto prepare_to_open;
496 } else
497 partialptr = NULL;
498
499 if (statret == -1) {
500 if (preserve_hard_links && hard_link_check(file, HL_SKIP))
501 return;
502 if (stat_errno == ENOENT)
503 goto notify_others;
504 if (verbose > 1) {
505 rsyserr(FERROR, stat_errno,
506 "recv_generator: failed to stat %s",
507 full_fname(fname));
508 }
509 return;
510 }
511
512 if (opt_ignore_existing && fnamecmp_type == FNAMECMP_FNAME) {
513 if (verbose > 1)
514 rprintf(FINFO, "%s exists\n", safe_fname(fname));
515 return;
516 }
517
518 if (update_only && fnamecmp_type == FNAMECMP_FNAME
519 && cmp_modtime(st.st_mtime, file->modtime) > 0) {
520 if (verbose > 1)
521 rprintf(FINFO, "%s is newer\n", safe_fname(fname));
522 return;
523 }
524
525 if (!compare_dest && fnamecmp_type <= FNAMECMP_BASIS_DIR_HIGH)
526 ;
527 else if (unchanged_file(fnamecmp, file, &st)) {
528 if (fnamecmp_type == FNAMECMP_FNAME)
529 set_perms(fname, file, &st, PERMS_REPORT);
530 return;
531 }
532
533prepare_to_open:
534 if (partialptr) {
535 st = partial_st;
536 fnamecmp = partialptr;
537 fnamecmp_type = FNAMECMP_PARTIAL_DIR;
538 statret = 0;
539 }
540
541 if (dry_run || whole_file > 0) {
542 statret = -1;
543 goto notify_others;
544 }
545 if (read_batch)
546 goto notify_others;
547
548 /* open the file */
549 fd = do_open(fnamecmp, O_RDONLY, 0);
550
551 if (fd == -1) {
552 rsyserr(FERROR, errno, "failed to open %s, continuing",
553 full_fname(fnamecmp));
554 pretend_missing:
555 /* pretend the file didn't exist */
556 if (preserve_hard_links && hard_link_check(file, HL_SKIP))
557 return;
558 statret = -1;
559 goto notify_others;
560 }
561
562 if (inplace && make_backups) {
563 if (!(backupptr = get_backup_name(fname))) {
564 close(fd);
565 return;
566 }
567 if (!(back_file = make_file(fname, NULL, NO_EXCLUDES))) {
568 close(fd);
569 goto pretend_missing;
570 }
571 if (robust_unlink(backupptr) && errno != ENOENT) {
572 rsyserr(FERROR, errno, "unlink %s",
573 full_fname(backupptr));
574 free(back_file);
575 close(fd);
576 return;
577 }
578 if ((f_copy = do_open(backupptr,
579 O_WRONLY | O_CREAT | O_TRUNC | O_EXCL, 0600)) < 0) {
580 rsyserr(FERROR, errno, "open %s",
581 full_fname(backupptr));
582 free(back_file);
583 close(fd);
584 return;
585 }
586 fnamecmp_type = FNAMECMP_BACKUP;
587 }
588
589 if (verbose > 3) {
590 rprintf(FINFO, "gen mapped %s of size %.0f\n",
591 safe_fname(fnamecmp), (double)st.st_size);
592 }
593
594 if (verbose > 2)
595 rprintf(FINFO, "generating and sending sums for %d\n", i);
596
597notify_others:
598 write_int(f_out, i);
599 if (protocol_version >= 29 && inplace && !read_batch)
600 write_byte(f_out, fnamecmp_type);
601 if (f_out_name >= 0)
602 write_byte(f_out_name, fnamecmp_type);
603
604 if (dry_run || read_batch)
605 return;
606
607 if (statret == 0) {
608 generate_and_send_sums(fd, st.st_size, f_out, f_copy);
609
610 if (f_copy >= 0) {
611 close(f_copy);
612 set_perms(backupptr, back_file, NULL, 0);
613 if (verbose > 1) {
614 rprintf(FINFO, "backed up %s to %s\n",
615 fname, backupptr);
616 }
617 free(back_file);
618 }
619
620 close(fd);
621 } else
622 write_sum_head(f_out, NULL);
623}
624
625
626void generate_files(int f_out, struct file_list *flist, char *local_name,
627 int f_out_name)
628{
629 int i;
630 int phase = 0;
631 char fbuf[MAXPATHLEN];
632
633 if (verbose > 2) {
634 rprintf(FINFO, "generator starting pid=%ld count=%d\n",
635 (long)getpid(), flist->count);
636 }
637
638 if (verbose >= 2) {
639 rprintf(FINFO,
640 whole_file > 0
641 ? "delta-transmission disabled for local transfer or --whole-file\n"
642 : "delta transmission enabled\n");
643 }
644
645 /* we expect to just sit around now, so don't exit on a
646 timeout. If we really get a timeout then the other process should
647 exit */
648 io_timeout = 0;
649
650 for (i = 0; i < flist->count; i++) {
651 struct file_struct *file = flist->files[i];
652 struct file_struct copy;
653
654 if (!file->basename)
655 continue;
656 /* we need to ensure that any directories we create have writeable
657 permissions initially so that we can create the files within
658 them. This is then fixed after the files are transferred */
659 if (!am_root && S_ISDIR(file->mode) && !(file->mode & S_IWUSR)) {
660 copy = *file;
661 /* XXX: Could this be causing a problem on SCO? Perhaps their
662 * handling of permissions is strange? */
663 copy.mode |= S_IWUSR; /* user write */
664 file = &copy;
665 }
666
667 recv_generator(local_name ? local_name : f_name_to(file, fbuf),
668 file, i, f_out, f_out_name);
669 }
670
671 phase++;
672 csum_length = SUM_LENGTH;
673 ignore_times = 1;
674
675 if (verbose > 2)
676 rprintf(FINFO,"generate_files phase=%d\n",phase);
677
678 write_int(f_out, -1);
679
680 /* files can cycle through the system more than once
681 * to catch initial checksum errors */
682 while ((i = get_redo_num()) != -1) {
683 struct file_struct *file = flist->files[i];
684 recv_generator(local_name ? local_name : f_name_to(file, fbuf),
685 file, i, f_out, f_out_name);
686 }
687
688 phase++;
689 if (verbose > 2)
690 rprintf(FINFO,"generate_files phase=%d\n",phase);
691
692 write_int(f_out, -1);
693
694 /* Read post-redo-phase MSG_DONE and any prior messages. */
695 get_redo_num();
696
697 if (preserve_hard_links)
698 do_hard_links();
699
700 /* now we need to fix any directory permissions that were
701 * modified during the transfer */
702 for (i = 0; i < flist->count; i++) {
703 struct file_struct *file = flist->files[i];
704 if (!file->basename || !S_ISDIR(file->mode))
705 continue;
706 recv_generator(local_name ? local_name : f_name(file),
707 file, i, -1, -1);
708 }
709
710 if (verbose > 2)
711 rprintf(FINFO,"generate_files finished\n");
712}