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