Patch from J.W. Schultz to have --include-from and --exclude-from on
[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 preserve_links;
30 extern int am_root;
31 extern int preserve_devices;
32 extern int preserve_hard_links;
33 extern int update_only;
34 extern int opt_ignore_existing;
35 extern int block_size;
36 extern int csum_length;
37 extern int ignore_times;
38 extern int size_only;
39 extern int io_timeout;
40 extern int remote_version;
41 extern int always_checksum;
42 extern int modify_window;
43 extern char *compare_dest;
44
45
46 /* choose whether to skip a particular file */
47 static int skip_file(char *fname,
48                      struct file_struct *file, STRUCT_STAT *st)
49 {
50         if (st->st_size != file->length) {
51                 return 0;
52         }
53         
54         /* if always checksum is set then we use the checksum instead 
55            of the file time to determine whether to sync */
56         if (always_checksum && S_ISREG(st->st_mode)) {
57                 char sum[MD4_SUM_LENGTH];
58                 char fnamecmpdest[MAXPATHLEN];
59
60                 if (compare_dest != NULL) {
61                         if (access(fname, 0) != 0) {
62                                 snprintf(fnamecmpdest,MAXPATHLEN,"%s/%s",
63                                                     compare_dest,fname);
64                                 fname = fnamecmpdest;
65                         }
66                 }
67                 file_checksum(fname,sum,st->st_size);
68                 if (remote_version < 21) {
69                         return (memcmp(sum,file->sum,2) == 0);
70                 } else {
71                         return (memcmp(sum,file->sum,MD4_SUM_LENGTH) == 0);
72                 }
73         }
74
75         if (size_only) {
76                 return 1;
77         }
78
79         if (ignore_times) {
80                 return 0;
81         }
82
83         return (cmp_modtime(st->st_mtime,file->modtime) == 0);
84 }
85
86
87 /* use a larger block size for really big files */
88 static int adapt_block_size(struct file_struct *file, int bsize)
89 {
90         int ret;
91
92         if (bsize != BLOCK_SIZE) return bsize;
93
94         ret = file->length / (10000); /* rough heuristic */
95         ret = ret & ~15; /* multiple of 16 */
96         if (ret < bsize) ret = bsize;
97         if (ret > CHUNK_SIZE/2) ret = CHUNK_SIZE/2;
98         return ret;
99 }
100
101
102 /*
103   send a header that says "we have no checksums" down the f_out fd
104   */
105 static void send_null_sums(int f_out)
106 {
107         write_int(f_out, 0);
108         write_int(f_out, block_size);
109         write_int(f_out, 0);
110 }
111
112
113
114 /**
115  * Perhaps we want to just send an empty checksum set for this file,
116  * which will force the whole thing to be literally transferred.
117  *
118  * When do we do this?  If the user's explicitly said they
119  * want the whole thing, or if { they haven't explicitly
120  * requested a delta, and it's local but not batch mode.}
121  *
122  * Whew. */
123 static BOOL disable_deltas_p(void)
124 {
125         extern int whole_file, no_whole_file;
126         extern int local_server;
127         extern int write_batch;
128
129         assert(whole_file == 0 || whole_file == 1);
130
131         /* whole_file and no_whole_file are never both on at the same time */
132
133         if (whole_file)
134                 return True;
135         else if (no_whole_file)
136                 return False;
137         else if (write_batch)
138                 return False;
139         else
140                 return local_server;
141 }
142
143
144 /*
145  * Generate and send a stream of signatures/checksums that describe a buffer
146  *
147  * Generate approximately one checksum every block_len bytes.
148  */
149 static void generate_and_send_sums(struct map_struct *buf, OFF_T len,
150                                    int block_len, int f_out)
151 {
152         size_t i;
153         struct sum_struct sum;
154         OFF_T offset = 0;
155
156         sum.count = (len + (block_len - 1)) / block_len;
157         sum.remainder = (len % block_len);
158         sum.n = block_len;
159         sum.flength = len;
160         /* not needed here  sum.sums = NULL; */
161
162         if (sum.count && verbose > 3) {
163                 rprintf(FINFO, "count=%ld rem=%ld n=%ld flength=%.0f\n",
164                         (long) sum.count, (long) sum.remainder,
165                         (long) sum.n, (double) sum.flength);
166         }
167
168         write_int(f_out, sum.count);
169         write_int(f_out, sum.n);
170         write_int(f_out, sum.remainder);
171
172         for (i = 0; i < sum.count; i++) {
173                 int n1 = MIN(len, block_len);
174                 char *map = map_ptr(buf, offset, n1);
175                 uint32 sum1 = get_checksum1(map, n1);
176                 char sum2[SUM_LENGTH];
177
178                 get_checksum2(map, n1, sum2);
179
180                 if (verbose > 3) {
181                         rprintf(FINFO,
182                                 "chunk[%d] offset=%.0f len=%d sum1=%08lx\n",
183                                 i, (double) offset, n1, (unsigned long) sum1);
184                 }
185                 write_int(f_out, sum1);
186                 write_buf(f_out, sum2, csum_length);
187                 len -= n1;
188                 offset += n1;
189         }
190 }
191
192
193
194 /**
195  * Acts on file number @p i from @p flist, whose name is @p fname.
196  *
197  * First fixes up permissions, then generates checksums for the file.
198  *
199  * @note This comment was added later by mbp who was trying to work it
200  * out.  It might be wrong.
201  **/ 
202 void recv_generator(char *fname, struct file_list *flist, int i, int f_out)
203 {  
204         int fd;
205         STRUCT_STAT st;
206         struct map_struct *buf;
207         int statret;
208         struct file_struct *file = flist->files[i];
209         char *fnamecmp;
210         char fnamecmpbuf[MAXPATHLEN];
211         extern char *compare_dest;
212         extern int list_only;
213         extern int preserve_perms;
214         extern int only_existing;
215         extern int orig_umask;
216
217         if (list_only) return;
218
219         if (verbose > 2)
220                 rprintf(FINFO,"recv_generator(%s,%d)\n",fname,i);
221
222         statret = link_stat(fname,&st);
223
224         if (only_existing && statret == -1 && errno == ENOENT) {
225                 /* we only want to update existing files */
226                 if (verbose > 1) rprintf(FINFO, "not creating new file \"%s\"\n",fname);
227                 return;
228         }
229
230         if (statret == 0 && 
231             !preserve_perms && 
232             (S_ISDIR(st.st_mode) == S_ISDIR(file->mode))) {
233                 /* if the file exists already and we aren't perserving
234                    presmissions then act as though the remote end sent
235                    us the file permissions we already have */
236                 file->mode = (file->mode & _S_IFMT) | (st.st_mode & ~_S_IFMT);
237         }
238
239         if (S_ISDIR(file->mode)) {
240                 /* The file to be received is a directory, so we need
241                  * to prepare appropriately.  If there is already a
242                  * file of that name and it is *not* a directory, then
243                  * we need to delete it.  If it doesn't exist, then
244                  * recursively create it. */
245           
246                 if (dry_run) return; /* XXXX -- might cause inaccuracies?? -- mbp */
247                 if (statret == 0 && !S_ISDIR(st.st_mode)) {
248                         if (robust_unlink(fname) != 0) {
249                                 rprintf(FERROR, RSYNC_NAME
250                                         ": recv_generator: unlink \"%s\" to make room for directory: %s\n",
251                                         fname,strerror(errno));
252                                 return;
253                         }
254                         statret = -1;
255                 }
256                 if (statret != 0 && do_mkdir(fname,file->mode) != 0 && errno != EEXIST) {
257                         if (!(relative_paths && errno==ENOENT && 
258                               create_directory_path(fname, orig_umask)==0 && 
259                               do_mkdir(fname,file->mode)==0)) {
260                                 rprintf(FERROR, RSYNC_NAME ": recv_generator: mkdir \"%s\": %s (2)\n",
261                                         fname,strerror(errno));
262                         }
263                 }
264                 /* f_out is set to -1 when doing final directory 
265                    permission and modification time repair */
266                 if (set_perms(fname,file,NULL,0) && verbose && (f_out != -1)) 
267                         rprintf(FINFO,"%s/\n",fname);
268                 return;
269         }
270
271         if (preserve_links && S_ISLNK(file->mode)) {
272 #if SUPPORT_LINKS
273                 char lnk[MAXPATHLEN];
274                 int l;
275                 extern int safe_symlinks;
276
277                 if (safe_symlinks && unsafe_symlink(file->link, fname)) {
278                         if (verbose) {
279                                 rprintf(FINFO,"ignoring unsafe symlink \"%s\" -> \"%s\"\n",
280                                         fname,file->link);
281                         }
282                         return;
283                 }
284                 if (statret == 0) {
285                         l = readlink(fname,lnk,MAXPATHLEN-1);
286                         if (l > 0) {
287                                 lnk[l] = 0;
288                                 /* A link already pointing to the
289                                  * right place -- no further action
290                                  * required. */
291                                 if (strcmp(lnk,file->link) == 0) {
292                                         set_perms(fname,file,&st,1);
293                                         return;
294                                 }
295                         }  
296                         /* Not a symlink, so delete whatever's
297                          * already there and put a new symlink
298                          * in place. */                    
299                         delete_file(fname);
300                 }
301                 if (do_symlink(file->link,fname) != 0) {
302                         rprintf(FERROR,RSYNC_NAME": symlink \"%s\" -> \"%s\": %s\n",
303                                 fname,file->link,strerror(errno));
304                 } else {
305                         set_perms(fname,file,NULL,0);
306                         if (verbose) {
307                                 rprintf(FINFO,"%s -> %s\n", fname,file->link);
308                         }
309                 }
310 #endif
311                 return;
312         }
313
314 #ifdef HAVE_MKNOD
315         if (am_root && preserve_devices && IS_DEVICE(file->mode)) {
316                 if (statret != 0 || 
317                     st.st_mode != file->mode ||
318                     st.st_rdev != file->rdev) { 
319                         delete_file(fname);
320                         if (verbose > 2)
321                                 rprintf(FINFO,"mknod(%s,0%o,0x%x)\n",
322                                         fname,(int)file->mode,(int)file->rdev);
323                         if (do_mknod(fname,file->mode,file->rdev) != 0) {
324                                 rprintf(FERROR,"mknod %s : %s\n",fname,strerror(errno));
325                         } else {
326                                 set_perms(fname,file,NULL,0);
327                                 if (verbose)
328                                         rprintf(FINFO,"%s\n",fname);
329                         }
330                 } else {
331                         set_perms(fname,file,&st,1);
332                 }
333                 return;
334         }
335 #endif
336
337         if (preserve_hard_links && check_hard_link(file)) {
338                 if (verbose > 1)
339                         rprintf(FINFO, "recv_generator: \"%s\" is a hard link\n",f_name(file));
340                 return;
341         }
342
343         if (!S_ISREG(file->mode)) {
344                 rprintf(FINFO, "skipping non-regular file \"%s\"\n",fname);
345                 return;
346         }
347
348         fnamecmp = fname;
349
350         if ((statret == -1) && (compare_dest != NULL)) {
351                 /* try the file at compare_dest instead */
352                 int saveerrno = errno;
353                 snprintf(fnamecmpbuf,MAXPATHLEN,"%s/%s",compare_dest,fname);
354                 statret = link_stat(fnamecmpbuf,&st);
355                 if (!S_ISREG(st.st_mode))
356                         statret = -1;
357                 if (statret == -1)
358                         errno = saveerrno;
359                 else
360                         fnamecmp = fnamecmpbuf;
361         }
362
363         if (statret == -1) {
364                 if (errno == ENOENT) {
365                         write_int(f_out,i);
366                         if (!dry_run) send_null_sums(f_out);
367                 } else {
368                         if (verbose > 1)
369                                 rprintf(FERROR, RSYNC_NAME
370                                         ": recv_generator failed to open \"%s\": %s\n",
371                                         fname, strerror(errno));
372                 }
373                 return;
374         }
375
376         if (!S_ISREG(st.st_mode)) {
377                 if (delete_file(fname) != 0) {
378                         return;
379                 }
380
381                 /* now pretend the file didn't exist */
382                 write_int(f_out,i);
383                 if (!dry_run) send_null_sums(f_out);
384                 return;
385         }
386
387         if (opt_ignore_existing && fnamecmp == fname) { 
388                 if (verbose > 1)
389                         rprintf(FINFO,"%s exists\n",fname);
390                 return;
391         } 
392
393         if (update_only && cmp_modtime(st.st_mtime,file->modtime)>0 && fnamecmp == fname) {
394                 if (verbose > 1)
395                         rprintf(FINFO,"%s is newer\n",fname);
396                 return;
397         }
398
399         if (skip_file(fname, file, &st)) {
400                 if (fnamecmp == fname)
401                         set_perms(fname,file,&st,1);
402                 return;
403         }
404
405         if (dry_run) {
406                 write_int(f_out,i);
407                 return;
408         }
409
410         if (disable_deltas_p()) {
411                 write_int(f_out,i);
412                 send_null_sums(f_out);
413                 return;
414         }
415
416         /* open the file */  
417         fd = do_open(fnamecmp, O_RDONLY, 0);
418
419         if (fd == -1) {
420                 rprintf(FERROR,RSYNC_NAME": failed to open \"%s\", continuing : %s\n",fnamecmp,strerror(errno));
421                 /* pretend the file didn't exist */
422                 write_int(f_out,i);
423                 send_null_sums(f_out);
424                 return;
425         }
426
427         if (st.st_size > 0) {
428                 buf = map_file(fd,st.st_size);
429         } else {
430                 buf = NULL;
431         }
432
433         if (verbose > 3)
434                 rprintf(FINFO,"gen mapped %s of size %.0f\n",fnamecmp,(double)st.st_size);
435
436         if (verbose > 2)
437                 rprintf(FINFO, "generating and sending sums for %d\n", i);
438
439         write_int(f_out,i);
440         generate_and_send_sums(buf, st.st_size,
441                                adapt_block_size(file, block_size), f_out);
442
443         close(fd);
444         if (buf) unmap_file(buf);
445 }
446
447
448
449 void generate_files(int f,struct file_list *flist,char *local_name,int f_recv)
450 {
451         int i;
452         int phase=0;
453
454         if (verbose > 2)
455                 rprintf(FINFO,"generator starting pid=%d count=%d\n",
456                         (int)getpid(),flist->count);
457
458         if (verbose >= 2) {
459                 rprintf(FINFO,
460                         disable_deltas_p() 
461                         ? "delta-transmission disabled for local transfer or --whole-file\n"
462                         : "delta transmission enabled\n");
463         }
464         
465         /* we expect to just sit around now, so don't exit on a
466            timeout. If we really get a timeout then the other process should
467            exit */
468         io_timeout = 0;
469
470         for (i = 0; i < flist->count; i++) {
471                 struct file_struct *file = flist->files[i];
472                 mode_t saved_mode = file->mode;
473                 if (!file->basename) continue;
474
475                 /* we need to ensure that any directories we create have writeable
476                    permissions initially so that we can create the files within
477                    them. This is then fixed after the files are transferred */
478                 if (!am_root && S_ISDIR(file->mode)) {
479                         file->mode |= S_IWUSR; /* user write */
480                         /* XXX: Could this be causing a problem on SCO?  Perhaps their
481                          * handling of permissions is strange? */
482                 }
483
484                 recv_generator(local_name?local_name:f_name(file),
485                                flist,i,f);
486
487                 file->mode = saved_mode;
488         }
489
490         phase++;
491         csum_length = SUM_LENGTH;
492         ignore_times=1;
493
494         if (verbose > 2)
495                 rprintf(FINFO,"generate_files phase=%d\n",phase);
496
497         write_int(f,-1);
498
499         if (remote_version >= 13) {
500                 /* in newer versions of the protocol the files can cycle through
501                    the system more than once to catch initial checksum errors */
502                 for (i=read_int(f_recv); i != -1; i=read_int(f_recv)) {
503                         struct file_struct *file = flist->files[i];
504                         recv_generator(local_name?local_name:f_name(file),
505                                        flist,i,f);    
506                 }
507
508                 phase++;
509                 if (verbose > 2)
510                         rprintf(FINFO,"generate_files phase=%d\n",phase);
511
512                 write_int(f,-1);
513         }
514 }