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