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