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