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