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