The device-handling code is no longer omitted based on HAVE_MKNOD
[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
2f03f956 388 if (am_root && preserve_devices && IS_DEVICE(file->mode)) {
2cda2560 389 if (statret != 0 ||
2f03f956 390 st.st_mode != file->mode ||
3915fd75 391 st.st_rdev != file->u.rdev) {
2f03f956 392 delete_file(fname);
d62bcc17 393 if (verbose > 2) {
2f03f956 394 rprintf(FINFO,"mknod(%s,0%o,0x%x)\n",
ecc81fce
WD
395 safe_fname(fname),
396 (int)file->mode, (int)file->u.rdev);
d62bcc17 397 }
728d0922 398 if (do_mknod(fname,file->mode,file->u.rdev) != 0) {
d62bcc17
WD
399 rsyserr(FERROR, errno, "mknod %s failed",
400 full_fname(fname));
2f03f956
AT
401 } else {
402 set_perms(fname,file,NULL,0);
ecc81fce
WD
403 if (verbose) {
404 rprintf(FINFO, "%s\n",
405 safe_fname(fname));
406 }
2f03f956
AT
407 }
408 } else {
c41b52c4 409 set_perms(fname, file, &st, PERMS_REPORT);
2f03f956
AT
410 }
411 return;
412 }
2f03f956 413
6dff5992 414 if (preserve_hard_links && hard_link_check(file, HL_CHECK_MASTER))
2f03f956 415 return;
2f03f956
AT
416
417 if (!S_ISREG(file->mode)) {
ecc81fce
WD
418 rprintf(FINFO, "skipping non-regular file \"%s\"\n",
419 safe_fname(fname));
2f03f956
AT
420 return;
421 }
422
375a4556
DD
423 fnamecmp = fname;
424
c338460d 425 if (statret == -1 && compare_dest != NULL) {
375a4556 426 /* try the file at compare_dest instead */
248ed45f 427 pathjoin(fnamecmpbuf, sizeof fnamecmpbuf, compare_dest, fname);
e7d13fe5
WD
428 if (link_stat(fnamecmpbuf, &st, 0) == 0
429 && S_ISREG(st.st_mode)) {
59c95e42 430#if HAVE_LINK
e7d13fe5
WD
431 if (link_dest && !dry_run) {
432 if (do_link(fnamecmpbuf, fname) < 0) {
433 if (verbose) {
434 rsyserr(FINFO, errno,
435 "link %s => %s",
436 fnamecmpbuf,
437 safe_fname(fname));
438 }
439 fnamecmp = fnamecmpbuf;
e7bc9b64 440 }
e7d13fe5 441 } else
59c95e42 442#endif
e7d13fe5
WD
443 fnamecmp = fnamecmpbuf;
444 statret = 0;
445 }
446 }
447
448 if (statret == 0 && !S_ISREG(st.st_mode)) {
449 if (delete_file(fname) != 0)
450 return;
451 statret = -1;
452 stat_errno = ENOENT;
375a4556
DD
453 }
454
72c19bb3
WD
455 if (partial_dir && (partialptr = partial_dir_fname(fname))
456 && link_stat(partialptr, &partial_st, 0) == 0
457 && S_ISREG(partial_st.st_mode)) {
458 if (statret == -1)
459 goto prepare_to_open;
460 } else
461 partialptr = NULL;
89f7eff3 462
2f03f956 463 if (statret == -1) {
6dff5992
WD
464 if (preserve_hard_links && hard_link_check(file, HL_SKIP))
465 return;
e7d13fe5 466 if (stat_errno == ENOENT) {
2f03f956 467 write_int(f_out,i);
727b35f6 468 if (!dry_run && !read_batch)
ec8290c8 469 write_sum_head(f_out, NULL);
ea42541f 470 } else if (verbose > 1) {
e7d13fe5
WD
471 rsyserr(FERROR, stat_errno,
472 "recv_generator: failed to stat %s",
d62bcc17 473 full_fname(fname));
2f03f956
AT
474 }
475 return;
476 }
477
2cda2560 478 if (opt_ignore_existing && fnamecmp == fname) {
3d6feada 479 if (verbose > 1)
ecc81fce 480 rprintf(FINFO, "%s exists\n", safe_fname(fname));
3d6feada 481 return;
2cda2560 482 }
3d6feada 483
d3a4375f
WD
484 if (update_only && fnamecmp == fname
485 && cmp_modtime(st.st_mtime, file->modtime) > 0) {
2f03f956 486 if (verbose > 1)
ecc81fce 487 rprintf(FINFO, "%s is newer\n", safe_fname(fname));
2f03f956
AT
488 return;
489 }
490
065a6052 491 if (skip_file(fnamecmp, file, &st)) {
bd4ed7f7 492 if (fnamecmp == fname)
c41b52c4 493 set_perms(fname, file, &st, PERMS_REPORT);
2f03f956
AT
494 return;
495 }
496
89f7eff3 497prepare_to_open:
727b35f6 498 if (dry_run || read_batch) {
2f03f956
AT
499 write_int(f_out,i);
500 return;
501 }
502
f38bd4a0 503 if (whole_file > 0) {
2f03f956 504 write_int(f_out,i);
fc0257c9 505 write_sum_head(f_out, NULL);
2f03f956
AT
506 return;
507 }
508
89f7eff3
WD
509 if (partialptr) {
510 st = partial_st;
511 fnamecmp = partialptr;
a7260c40
WD
512 }
513
2cda2560 514 /* open the file */
8c9fd200 515 fd = do_open(fnamecmp, O_RDONLY, 0);
2f03f956
AT
516
517 if (fd == -1) {
d62bcc17
WD
518 rsyserr(FERROR, errno, "failed to open %s, continuing",
519 full_fname(fnamecmp));
cd6aa5b5 520 pretend_missing:
60be6acf 521 /* pretend the file didn't exist */
6dff5992
WD
522 if (preserve_hard_links && hard_link_check(file, HL_SKIP))
523 return;
60be6acf 524 write_int(f_out,i);
fc0257c9 525 write_sum_head(f_out, NULL);
2f03f956
AT
526 return;
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 }
553 } else {
554 backupptr = NULL;
555 back_file = NULL;
556 f_copy = -1;
557 }
558
dfd5ba6a 559 if (verbose > 3) {
ecc81fce
WD
560 rprintf(FINFO, "gen mapped %s of size %.0f\n",
561 safe_fname(fnamecmp), (double)st.st_size);
dfd5ba6a 562 }
2f03f956 563
2f03f956 564 if (verbose > 2)
80605142 565 rprintf(FINFO, "generating and sending sums for %d\n", i);
2f03f956
AT
566
567 write_int(f_out,i);
cd6aa5b5
WD
568 generate_and_send_sums(fd, st.st_size, f_out, f_copy);
569
570 if (f_copy >= 0) {
571 close(f_copy);
572 set_perms(backupptr, back_file, NULL, 0);
89389a29
WD
573 if (verbose > 1)
574 rprintf(FINFO, "backed up %s to %s\n", fname, backupptr);
cd6aa5b5
WD
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}