Output the same backup-message prefix when verbose > 1 regardless of
[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,
257 int f_out)
2cda2560 258{
cd6aa5b5 259 int fd, f_copy;
89f7eff3 260 STRUCT_STAT st, partial_st;
cd6aa5b5 261 struct file_struct *back_file;
e7d13fe5 262 int statret, stat_errno;
cd6aa5b5 263 char *fnamecmp, *partialptr, *backupptr;
375a4556 264 char fnamecmpbuf[MAXPATHLEN];
f7632fc6 265
dfd5ba6a
WD
266 if (list_only)
267 return;
2f03f956
AT
268
269 if (verbose > 2)
ecc81fce 270 rprintf(FINFO, "recv_generator(%s,%d)\n", safe_fname(fname), i);
2f03f956 271
97f9dcae
WD
272 if (server_exclude_list.head
273 && check_exclude(&server_exclude_list, fname,
3e35c34b
WD
274 S_ISDIR(file->mode)) < 0) {
275 if (verbose) {
276 rprintf(FINFO, "skipping server-excluded file \"%s\"\n",
ecc81fce 277 safe_fname(fname));
3e35c34b 278 }
97f9dcae 279 return;
3e35c34b 280 }
97f9dcae 281
73f7af0e
WD
282 if (dry_run > 1) {
283 statret = -1;
284 stat_errno = ENOENT;
285 } else {
286 statret = link_stat(fname, &st,
287 keep_dirlinks && S_ISDIR(file->mode));
288 stat_errno = errno;
289 }
63787382 290
a7260c40 291 if (only_existing && statret == -1 && stat_errno == ENOENT) {
1347d512 292 /* we only want to update existing files */
ecc81fce
WD
293 if (verbose > 1) {
294 rprintf(FINFO, "not creating new file \"%s\"\n",
295 safe_fname(fname));
296 }
1347d512
AT
297 return;
298 }
299
d9b4d267
WD
300 if (statret == 0 && !preserve_perms
301 && S_ISDIR(st.st_mode) == S_ISDIR(file->mode)) {
4df9f368 302 /* if the file exists already and we aren't perserving
2cda2560
WD
303 * permissions then act as though the remote end sent
304 * us the file permissions we already have */
67e78a82
WD
305 file->mode = (file->mode & ~CHMOD_BITS)
306 | (st.st_mode & CHMOD_BITS);
4df9f368
AT
307 }
308
2f03f956 309 if (S_ISDIR(file->mode)) {
2cda2560
WD
310 /* The file to be received is a directory, so we need
311 * to prepare appropriately. If there is already a
312 * file of that name and it is *not* a directory, then
313 * we need to delete it. If it doesn't exist, then
314 * recursively create it. */
315
ec8290c8
WD
316 if (dry_run)
317 return; /* TODO: causes inaccuracies -- fix */
2f03f956 318 if (statret == 0 && !S_ISDIR(st.st_mode)) {
c7c11a0d 319 if (robust_unlink(fname) != 0) {
d62bcc17
WD
320 rsyserr(FERROR, errno,
321 "recv_generator: unlink %s to make room for directory",
322 full_fname(fname));
2f03f956
AT
323 return;
324 }
325 statret = -1;
326 }
327 if (statret != 0 && do_mkdir(fname,file->mode) != 0 && errno != EEXIST) {
d62bcc17
WD
328 if (!(relative_paths && errno == ENOENT
329 && create_directory_path(fname, orig_umask) == 0
330 && do_mkdir(fname, file->mode) == 0)) {
331 rsyserr(FERROR, errno,
332 "recv_generator: mkdir %s failed",
333 full_fname(fname));
2f03f956
AT
334 }
335 }
716e73d4
WD
336 /* f_out is set to -1 when doing final directory-permission
337 * and modification-time repair. */
338 if (set_perms(fname, file, statret ? NULL : &st, 0)
339 && verbose && f_out != -1)
ecc81fce 340 rprintf(FINFO, "%s/\n", safe_fname(fname));
2f03f956
AT
341 return;
342 }
343
344 if (preserve_links && S_ISLNK(file->mode)) {
345#if SUPPORT_LINKS
346 char lnk[MAXPATHLEN];
347 int l;
2f03f956 348
728d0922 349 if (safe_symlinks && unsafe_symlink(file->u.link, fname)) {
2f03f956 350 if (verbose) {
ea42541f 351 rprintf(FINFO, "ignoring unsafe symlink %s -> \"%s\"\n",
728d0922 352 full_fname(fname), file->u.link);
2f03f956
AT
353 }
354 return;
355 }
356 if (statret == 0) {
357 l = readlink(fname,lnk,MAXPATHLEN-1);
358 if (l > 0) {
359 lnk[l] = 0;
85d4d142
MP
360 /* A link already pointing to the
361 * right place -- no further action
362 * required. */
728d0922 363 if (strcmp(lnk,file->u.link) == 0) {
c41b52c4
WD
364 set_perms(fname, file, &st,
365 PERMS_REPORT);
2f03f956
AT
366 return;
367 }
2cda2560 368 }
85d4d142
MP
369 /* Not a symlink, so delete whatever's
370 * already there and put a new symlink
2cda2560 371 * in place. */
4b3977bf 372 delete_file(fname);
2f03f956 373 }
728d0922 374 if (do_symlink(file->u.link,fname) != 0) {
d62bcc17 375 rsyserr(FERROR, errno, "symlink %s -> \"%s\" failed",
ecc81fce 376 full_fname(fname), safe_fname(file->u.link));
2f03f956
AT
377 } else {
378 set_perms(fname,file,NULL,0);
379 if (verbose) {
ecc81fce
WD
380 rprintf(FINFO, "%s -> %s\n", safe_fname(fname),
381 safe_fname(file->u.link));
2f03f956
AT
382 }
383 }
384#endif
385 return;
386 }
387
388#ifdef HAVE_MKNOD
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 }
414#endif
415
6dff5992 416 if (preserve_hard_links && hard_link_check(file, HL_CHECK_MASTER))
2f03f956 417 return;
2f03f956
AT
418
419 if (!S_ISREG(file->mode)) {
ecc81fce
WD
420 rprintf(FINFO, "skipping non-regular file \"%s\"\n",
421 safe_fname(fname));
2f03f956
AT
422 return;
423 }
424
375a4556
DD
425 fnamecmp = fname;
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;
e7bc9b64 442 }
e7d13fe5 443 } else
59c95e42 444#endif
e7d13fe5
WD
445 fnamecmp = fnamecmpbuf;
446 statret = 0;
447 }
448 }
449
450 if (statret == 0 && !S_ISREG(st.st_mode)) {
451 if (delete_file(fname) != 0)
452 return;
453 statret = -1;
454 stat_errno = ENOENT;
375a4556
DD
455 }
456
72c19bb3
WD
457 if (partial_dir && (partialptr = partial_dir_fname(fname))
458 && link_stat(partialptr, &partial_st, 0) == 0
459 && S_ISREG(partial_st.st_mode)) {
460 if (statret == -1)
461 goto prepare_to_open;
462 } else
463 partialptr = NULL;
89f7eff3 464
2f03f956 465 if (statret == -1) {
6dff5992
WD
466 if (preserve_hard_links && hard_link_check(file, HL_SKIP))
467 return;
e7d13fe5 468 if (stat_errno == ENOENT) {
2f03f956 469 write_int(f_out,i);
727b35f6 470 if (!dry_run && !read_batch)
ec8290c8 471 write_sum_head(f_out, NULL);
ea42541f 472 } else if (verbose > 1) {
e7d13fe5
WD
473 rsyserr(FERROR, stat_errno,
474 "recv_generator: failed to stat %s",
d62bcc17 475 full_fname(fname));
2f03f956
AT
476 }
477 return;
478 }
479
2cda2560 480 if (opt_ignore_existing && fnamecmp == fname) {
3d6feada 481 if (verbose > 1)
ecc81fce 482 rprintf(FINFO, "%s exists\n", safe_fname(fname));
3d6feada 483 return;
2cda2560 484 }
3d6feada 485
d3a4375f
WD
486 if (update_only && fnamecmp == fname
487 && cmp_modtime(st.st_mtime, file->modtime) > 0) {
2f03f956 488 if (verbose > 1)
ecc81fce 489 rprintf(FINFO, "%s is newer\n", safe_fname(fname));
2f03f956
AT
490 return;
491 }
492
065a6052 493 if (skip_file(fnamecmp, file, &st)) {
bd4ed7f7 494 if (fnamecmp == fname)
c41b52c4 495 set_perms(fname, file, &st, PERMS_REPORT);
2f03f956
AT
496 return;
497 }
498
89f7eff3 499prepare_to_open:
727b35f6 500 if (dry_run || read_batch) {
2f03f956
AT
501 write_int(f_out,i);
502 return;
503 }
504
f38bd4a0 505 if (whole_file > 0) {
2f03f956 506 write_int(f_out,i);
fc0257c9 507 write_sum_head(f_out, NULL);
2f03f956
AT
508 return;
509 }
510
89f7eff3
WD
511 if (partialptr) {
512 st = partial_st;
513 fnamecmp = partialptr;
a7260c40
WD
514 }
515
2cda2560 516 /* open the file */
8c9fd200 517 fd = do_open(fnamecmp, O_RDONLY, 0);
2f03f956
AT
518
519 if (fd == -1) {
d62bcc17
WD
520 rsyserr(FERROR, errno, "failed to open %s, continuing",
521 full_fname(fnamecmp));
cd6aa5b5 522 pretend_missing:
60be6acf 523 /* pretend the file didn't exist */
6dff5992
WD
524 if (preserve_hard_links && hard_link_check(file, HL_SKIP))
525 return;
60be6acf 526 write_int(f_out,i);
fc0257c9 527 write_sum_head(f_out, NULL);
2f03f956
AT
528 return;
529 }
530
cd6aa5b5
WD
531 if (inplace && make_backups) {
532 if (!(backupptr = get_backup_name(fname))) {
533 close(fd);
534 return;
535 }
536 if (!(back_file = make_file(fname, NULL, NO_EXCLUDES))) {
537 close(fd);
538 goto pretend_missing;
539 }
540 if (robust_unlink(backupptr) && errno != ENOENT) {
541 rsyserr(FERROR, errno, "unlink %s",
542 full_fname(backupptr));
543 free(back_file);
544 close(fd);
545 return;
546 }
547 if ((f_copy = do_open(backupptr,
548 O_WRONLY | O_CREAT | O_TRUNC | O_EXCL, 0600)) < 0) {
549 rsyserr(FERROR, errno, "open %s",
550 full_fname(backupptr));
551 free(back_file);
552 close(fd);
553 return;
554 }
555 } else {
556 backupptr = NULL;
557 back_file = NULL;
558 f_copy = -1;
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
AT
568
569 write_int(f_out,i);
cd6aa5b5
WD
570 generate_and_send_sums(fd, st.st_size, f_out, f_copy);
571
572 if (f_copy >= 0) {
573 close(f_copy);
574 set_perms(backupptr, back_file, NULL, 0);
575 free(back_file);
576 }
2f03f956
AT
577
578 close(fd);
2f03f956
AT
579}
580
581
7daccb8e 582void generate_files(int f_out, struct file_list *flist, char *local_name)
2f03f956
AT
583{
584 int i;
e1f67417 585 int phase = 0;
968c8030 586 char fbuf[MAXPATHLEN];
2f03f956 587
45e08edb
WD
588 if (verbose > 2) {
589 rprintf(FINFO, "generator starting pid=%ld count=%d\n",
590 (long)getpid(), flist->count);
591 }
2f03f956 592
3e7053ac
MP
593 if (verbose >= 2) {
594 rprintf(FINFO,
f38bd4a0 595 whole_file > 0
3e7053ac
MP
596 ? "delta-transmission disabled for local transfer or --whole-file\n"
597 : "delta transmission enabled\n");
598 }
2cda2560 599
a57873b7
AT
600 /* we expect to just sit around now, so don't exit on a
601 timeout. If we really get a timeout then the other process should
602 exit */
603 io_timeout = 0;
604
2f03f956
AT
605 for (i = 0; i < flist->count; i++) {
606 struct file_struct *file = flist->files[i];
dfd5ba6a 607 struct file_struct copy;
2f03f956 608
dfd5ba6a
WD
609 if (!file->basename)
610 continue;
2f03f956
AT
611 /* we need to ensure that any directories we create have writeable
612 permissions initially so that we can create the files within
613 them. This is then fixed after the files are transferred */
dfd5ba6a
WD
614 if (!am_root && S_ISDIR(file->mode) && !(file->mode & S_IWUSR)) {
615 copy = *file;
2cda2560
WD
616 /* XXX: Could this be causing a problem on SCO? Perhaps their
617 * handling of permissions is strange? */
dfd5ba6a
WD
618 copy.mode |= S_IWUSR; /* user write */
619 file = &copy;
2f03f956
AT
620 }
621
3fef5364 622 recv_generator(local_name ? local_name : f_name_to(file, fbuf),
7daccb8e 623 file, i, f_out);
2f03f956
AT
624 }
625
626 phase++;
627 csum_length = SUM_LENGTH;
e1f67417 628 ignore_times = 1;
2f03f956
AT
629
630 if (verbose > 2)
631 rprintf(FINFO,"generate_files phase=%d\n",phase);
632
7daccb8e 633 write_int(f_out, -1);
2f03f956 634
bc63ae3f
S
635 /* files can cycle through the system more than once
636 * to catch initial checksum errors */
b9b15fb1 637 while ((i = get_redo_num()) != -1) {
bc63ae3f 638 struct file_struct *file = flist->files[i];
3fef5364 639 recv_generator(local_name ? local_name : f_name_to(file, fbuf),
7daccb8e 640 file, i, f_out);
bc63ae3f 641 }
2f03f956 642
bc63ae3f
S
643 phase++;
644 if (verbose > 2)
645 rprintf(FINFO,"generate_files phase=%d\n",phase);
2f03f956 646
7daccb8e 647 write_int(f_out, -1);
6dff5992
WD
648
649 if (preserve_hard_links)
650 do_hard_links();
651
652 /* now we need to fix any directory permissions that were
653 * modified during the transfer */
654 for (i = 0; i < flist->count; i++) {
655 struct file_struct *file = flist->files[i];
ec8290c8
WD
656 if (!file->basename || !S_ISDIR(file->mode))
657 continue;
6dff5992
WD
658 recv_generator(local_name ? local_name : f_name(file),
659 file, i, -1);
660 }
661
662 if (verbose > 2)
663 rprintf(FINFO,"generate_files finished\n");
2f03f956 664}