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