Patch from J.W. Schultz to have --include-from and --exclude-from on
[rsync/rsync.git] / generator.c
CommitLineData
ef1aa910 1/* -*- c-file-style: "linux" -*-
91262d5d
MP
2
3 rsync -- fast file replication program
ef1aa910
MP
4
5 Copyright (C) 1996-2000 by Andrew Tridgell
2f03f956 6 Copyright (C) Paul Mackerras 1996
91262d5d 7 Copyright (C) 2002 by Martin Pool <mbp@samba.org>
2f03f956
AT
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 preserve_links;
30extern int am_root;
31extern int preserve_devices;
32extern int preserve_hard_links;
33extern int update_only;
3d6feada 34extern int opt_ignore_existing;
2f03f956
AT
35extern int block_size;
36extern int csum_length;
37extern int ignore_times;
f83f0548 38extern int size_only;
2f03f956
AT
39extern int io_timeout;
40extern int remote_version;
41extern int always_checksum;
5b56cc19 42extern int modify_window;
60c8d7bc 43extern char *compare_dest;
2f03f956
AT
44
45
46/* choose whether to skip a particular file */
47static 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];
60c8d7bc
DD
58 char fnamecmpdest[MAXPATHLEN];
59
60 if (compare_dest != NULL) {
61 if (access(fname, 0) != 0) {
8950ac03 62 snprintf(fnamecmpdest,MAXPATHLEN,"%s/%s",
60c8d7bc
DD
63 compare_dest,fname);
64 fname = fnamecmpdest;
65 }
66 }
2f03f956 67 file_checksum(fname,sum,st->st_size);
f855a7d0
AT
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 }
2f03f956
AT
73 }
74
f83f0548
AT
75 if (size_only) {
76 return 1;
77 }
78
2f03f956
AT
79 if (ignore_times) {
80 return 0;
81 }
82
5b56cc19 83 return (cmp_modtime(st->st_mtime,file->modtime) == 0);
2f03f956
AT
84}
85
86
87/* use a larger block size for really big files */
88static 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/*
80605142 103 send a header that says "we have no checksums" down the f_out fd
2f03f956 104 */
80605142 105static void send_null_sums(int f_out)
2f03f956 106{
80605142
WD
107 write_int(f_out, 0);
108 write_int(f_out, block_size);
109 write_int(f_out, 0);
2f03f956
AT
110}
111
bceec82f 112
80605142 113
bceec82f
MP
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. */
123static 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
b8709f50 131 /* whole_file and no_whole_file are never both on at the same time */
bceec82f
MP
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
80605142
WD
144/*
145 * Generate and send a stream of signatures/checksums that describe a buffer
e66dfd18 146 *
80605142
WD
147 * Generate approximately one checksum every block_len bytes.
148 */
149static void generate_and_send_sums(struct map_struct *buf, OFF_T len,
150 int block_len, int f_out)
2f03f956 151{
80605142
WD
152 size_t i;
153 struct sum_struct sum;
2f03f956
AT
154 OFF_T offset = 0;
155
80605142
WD
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; */
2f03f956 161
80605142 162 if (sum.count && verbose > 3) {
67684d03 163 rprintf(FINFO, "count=%ld rem=%ld n=%ld flength=%.0f\n",
80605142
WD
164 (long) sum.count, (long) sum.remainder,
165 (long) sum.n, (double) sum.flength);
67684d03 166 }
e66dfd18 167
80605142
WD
168 write_int(f_out, sum.count);
169 write_int(f_out, sum.n);
170 write_int(f_out, sum.remainder);
2f03f956 171
80605142
WD
172 for (i = 0; i < sum.count; i++) {
173 int n1 = MIN(len, block_len);
e66dfd18 174 char *map = map_ptr(buf, offset, n1);
80605142
WD
175 uint32 sum1 = get_checksum1(map, n1);
176 char sum2[SUM_LENGTH];
2f03f956 177
80605142 178 get_checksum2(map, n1, sum2);
2f03f956 179
80605142 180 if (verbose > 3) {
e66dfd18 181 rprintf(FINFO,
80605142
WD
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);
2f03f956
AT
187 len -= n1;
188 offset += n1;
189 }
2f03f956
AT
190}
191
192
ef1aa910 193
420ef2c4
MP
194/**
195 * Acts on file number @p i from @p flist, whose name is @p fname.
ef1aa910
MP
196 *
197 * First fixes up permissions, then generates checksums for the file.
198 *
420ef2c4
MP
199 * @note This comment was added later by mbp who was trying to work it
200 * out. It might be wrong.
201 **/
202void recv_generator(char *fname, struct file_list *flist, int i, int f_out)
2f03f956
AT
203{
204 int fd;
205 STRUCT_STAT st;
206 struct map_struct *buf;
2f03f956
AT
207 int statret;
208 struct file_struct *file = flist->files[i];
375a4556
DD
209 char *fnamecmp;
210 char fnamecmpbuf[MAXPATHLEN];
211 extern char *compare_dest;
f7632fc6 212 extern int list_only;
4df9f368 213 extern int preserve_perms;
1347d512 214 extern int only_existing;
b35d0d8e 215 extern int orig_umask;
f7632fc6
AT
216
217 if (list_only) return;
2f03f956
AT
218
219 if (verbose > 2)
220 rprintf(FINFO,"recv_generator(%s,%d)\n",fname,i);
221
222 statret = link_stat(fname,&st);
63787382 223
1347d512
AT
224 if (only_existing && statret == -1 && errno == ENOENT) {
225 /* we only want to update existing files */
1bbd10fe 226 if (verbose > 1) rprintf(FINFO, "not creating new file \"%s\"\n",fname);
1347d512
AT
227 return;
228 }
229
4df9f368
AT
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 */
7e0ca8e2 236 file->mode = (file->mode & _S_IFMT) | (st.st_mode & ~_S_IFMT);
4df9f368
AT
237 }
238
2f03f956 239 if (S_ISDIR(file->mode)) {
a1b1b1da
MP
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
85d4d142 246 if (dry_run) return; /* XXXX -- might cause inaccuracies?? -- mbp */
2f03f956 247 if (statret == 0 && !S_ISDIR(st.st_mode)) {
c7c11a0d 248 if (robust_unlink(fname) != 0) {
85d4d142
MP
249 rprintf(FERROR, RSYNC_NAME
250 ": recv_generator: unlink \"%s\" to make room for directory: %s\n",
a1b1b1da 251 fname,strerror(errno));
2f03f956
AT
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 &&
b35d0d8e 258 create_directory_path(fname, orig_umask)==0 &&
2f03f956 259 do_mkdir(fname,file->mode)==0)) {
85d4d142 260 rprintf(FERROR, RSYNC_NAME ": recv_generator: mkdir \"%s\": %s (2)\n",
2f03f956
AT
261 fname,strerror(errno));
262 }
263 }
de343e3c
DD
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))
2f03f956
AT
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) {
1bbd10fe 279 rprintf(FINFO,"ignoring unsafe symlink \"%s\" -> \"%s\"\n",
2f03f956
AT
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;
85d4d142
MP
288 /* A link already pointing to the
289 * right place -- no further action
290 * required. */
7e0ca8e2 291 if (strcmp(lnk,file->link) == 0) {
2f03f956
AT
292 set_perms(fname,file,&st,1);
293 return;
294 }
85d4d142
MP
295 }
296 /* Not a symlink, so delete whatever's
297 * already there and put a new symlink
298 * in place. */
4b3977bf 299 delete_file(fname);
2f03f956 300 }
2f03f956 301 if (do_symlink(file->link,fname) != 0) {
85d4d142 302 rprintf(FERROR,RSYNC_NAME": symlink \"%s\" -> \"%s\": %s\n",
2f03f956
AT
303 fname,file->link,strerror(errno));
304 } else {
305 set_perms(fname,file,NULL,0);
306 if (verbose) {
1bbd10fe 307 rprintf(FINFO,"%s -> %s\n", fname,file->link);
2f03f956
AT
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)
fba31efb 339 rprintf(FINFO, "recv_generator: \"%s\" is a hard link\n",f_name(file));
2f03f956
AT
340 return;
341 }
342
343 if (!S_ISREG(file->mode)) {
1bbd10fe 344 rprintf(FINFO, "skipping non-regular file \"%s\"\n",fname);
2f03f956
AT
345 return;
346 }
347
375a4556
DD
348 fnamecmp = fname;
349
350 if ((statret == -1) && (compare_dest != NULL)) {
351 /* try the file at compare_dest instead */
352 int saveerrno = errno;
8950ac03 353 snprintf(fnamecmpbuf,MAXPATHLEN,"%s/%s",compare_dest,fname);
375a4556
DD
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
2f03f956
AT
363 if (statret == -1) {
364 if (errno == ENOENT) {
365 write_int(f_out,i);
80605142 366 if (!dry_run) send_null_sums(f_out);
2f03f956
AT
367 } else {
368 if (verbose > 1)
fb47591d
MP
369 rprintf(FERROR, RSYNC_NAME
370 ": recv_generator failed to open \"%s\": %s\n",
371 fname, strerror(errno));
2f03f956
AT
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);
80605142 383 if (!dry_run) send_null_sums(f_out);
2f03f956
AT
384 return;
385 }
386
3d6feada
MP
387 if (opt_ignore_existing && fnamecmp == fname) {
388 if (verbose > 1)
389 rprintf(FINFO,"%s exists\n",fname);
390 return;
391 }
392
5b56cc19 393 if (update_only && cmp_modtime(st.st_mtime,file->modtime)>0 && fnamecmp == fname) {
2f03f956
AT
394 if (verbose > 1)
395 rprintf(FINFO,"%s is newer\n",fname);
396 return;
397 }
398
399 if (skip_file(fname, file, &st)) {
bd4ed7f7
DD
400 if (fnamecmp == fname)
401 set_perms(fname,file,&st,1);
2f03f956
AT
402 return;
403 }
404
405 if (dry_run) {
406 write_int(f_out,i);
407 return;
408 }
409
bceec82f 410 if (disable_deltas_p()) {
2f03f956 411 write_int(f_out,i);
80605142 412 send_null_sums(f_out);
2f03f956
AT
413 return;
414 }
415
416 /* open the file */
8c9fd200 417 fd = do_open(fnamecmp, O_RDONLY, 0);
2f03f956
AT
418
419 if (fd == -1) {
85d4d142 420 rprintf(FERROR,RSYNC_NAME": failed to open \"%s\", continuing : %s\n",fnamecmp,strerror(errno));
60be6acf
DD
421 /* pretend the file didn't exist */
422 write_int(f_out,i);
80605142 423 send_null_sums(f_out);
2f03f956
AT
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)
5f808dfb 434 rprintf(FINFO,"gen mapped %s of size %.0f\n",fnamecmp,(double)st.st_size);
2f03f956 435
2f03f956 436 if (verbose > 2)
80605142 437 rprintf(FINFO, "generating and sending sums for %d\n", i);
2f03f956
AT
438
439 write_int(f_out,i);
80605142
WD
440 generate_and_send_sums(buf, st.st_size,
441 adapt_block_size(file, block_size), f_out);
2f03f956
AT
442
443 close(fd);
444 if (buf) unmap_file(buf);
2f03f956
AT
445}
446
447
448
449void 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
3e7053ac
MP
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
a57873b7
AT
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
2f03f956
AT
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 */
a1b1b1da
MP
480 /* XXX: Could this be causing a problem on SCO? Perhaps their
481 * handling of permissions is strange? */
2f03f956
AT
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
2f03f956
AT
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}