Added the new --partial-dir option.
[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 *partial_dir;
46 extern char *compare_dest;
47 extern int link_dest;
48 extern int whole_file;
49 extern int local_server;
50 extern int list_only;
51 extern int read_batch;
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         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  */
109 void 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
141 static 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  */
211 static 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  */
261 static 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
539 void 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 }