Added ITEM_NO_DEST_AND_NO_UPDATE for use by the generator's
[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;
6c3862fa
WD
28extern int log_format_has_i;
29extern int log_format_has_o_or_i;
30extern int daemon_log_format_has_i;
31extern int am_root;
32extern int am_server;
33extern int am_daemon;
59faec8b 34extern int recurse;
2f03f956 35extern int relative_paths;
716e73d4 36extern int keep_dirlinks;
2f03f956 37extern int preserve_links;
2f03f956
AT
38extern int preserve_devices;
39extern int preserve_hard_links;
6744b62d
WD
40extern int preserve_perms;
41extern int preserve_uid;
42extern int preserve_gid;
3ea9bbd6
WD
43extern int preserve_times;
44extern int omit_dir_times;
59faec8b 45extern int delete_before;
fa13f396 46extern int delete_during;
59faec8b
WD
47extern int delete_after;
48extern int module_id;
49extern int ignore_errors;
fe960187 50extern int remove_sent_files;
2f03f956 51extern int update_only;
3d6feada 52extern int opt_ignore_existing;
cd6aa5b5
WD
53extern int inplace;
54extern int make_backups;
2f03f956
AT
55extern int csum_length;
56extern int ignore_times;
f83f0548 57extern int size_only;
7d1bfaf7 58extern OFF_T max_size;
2f03f956 59extern int io_timeout;
59faec8b 60extern int io_error;
9ac2395b 61extern int ignore_timeout;
d04e9c51 62extern int protocol_version;
8e85be0a 63extern int fuzzy_basis;
2f03f956 64extern int always_checksum;
a7260c40 65extern char *partial_dir;
b7e8628c 66extern char *basis_dir[];
2be2fb3e 67extern int compare_dest;
59c95e42 68extern int link_dest;
5774786f
WD
69extern int whole_file;
70extern int local_server;
5774786f 71extern int list_only;
b9f592fb 72extern int read_batch;
5774786f
WD
73extern int only_existing;
74extern int orig_umask;
75extern int safe_symlinks;
a255c592 76extern long block_size; /* "long" because popt can't set an int32. */
59faec8b
WD
77extern int max_delete;
78extern int force_delete;
79extern int one_file_system;
6c3862fa 80extern struct stats stats;
59faec8b
WD
81extern dev_t filesystem_dev;
82extern char *backup_dir;
83extern char *backup_suffix;
84extern int backup_suffix_len;
2f03f956 85
7842418b 86extern struct filter_list_struct server_filter_list;
97f9dcae 87
59faec8b
WD
88static int deletion_count = 0; /* used to implement --max-delete */
89
90
91static int is_backup_file(char *fn)
92{
93 int k = strlen(fn) - backup_suffix_len;
94 return k > 0 && strcmp(fn+k, backup_suffix) == 0;
95}
96
97
98/* Delete a file or directory. If DEL_FORCE_RECURSE is set in the flags, or if
99 * force_delete is set, this will delete recursively as long as DEL_NO_RECURSE
100 * is not set in the flags. */
101static int delete_item(char *fname, int mode, int flags)
102{
103 struct file_list *dirlist;
104 char buf[MAXPATHLEN];
105 int j, dlen, zap_dir, ok;
106 void *save_filters;
107
108 if (max_delete && deletion_count >= max_delete)
109 return -1;
110
111 if (!S_ISDIR(mode)) {
112 if (make_backups && (backup_dir || !is_backup_file(fname)))
113 ok = make_backup(fname);
114 else
115 ok = robust_unlink(fname) == 0;
116 if (ok) {
117 if (!(flags & DEL_TERSE))
118 log_delete(fname, mode);
119 deletion_count++;
120 return 0;
121 }
122 if (errno == ENOENT)
123 return 0;
124 rsyserr(FERROR, errno, "delete_file: unlink %s failed",
125 full_fname(fname));
126 return -1;
127 }
128
129 zap_dir = (flags & DEL_FORCE_RECURSE || (force_delete && recurse))
130 && !(flags & DEL_NO_RECURSE);
131 if (dry_run && zap_dir) {
132 ok = 0;
133 errno = ENOTEMPTY;
134 } else if (make_backups && !backup_dir && !is_backup_file(fname)
135 && !(flags & DEL_FORCE_RECURSE))
136 ok = make_backup(fname);
137 else
138 ok = do_rmdir(fname) == 0;
139 if (ok) {
140 if (!(flags & DEL_TERSE))
141 log_delete(fname, mode);
142 deletion_count++;
143 return 0;
144 }
145 if (errno == ENOENT)
146 return 0;
147 if (!zap_dir || (errno != ENOTEMPTY && errno != EEXIST)) {
148 rsyserr(FERROR, errno, "delete_file: rmdir %s failed",
149 full_fname(fname));
150 return -1;
151 }
f62eaa24 152 flags |= DEL_FORCE_RECURSE; /* mark subdir dels as not "in the way" */
59faec8b
WD
153
154 dlen = strlcpy(buf, fname, MAXPATHLEN);
155 save_filters = push_local_filters(buf, dlen);
156
157 dirlist = get_dirlist(buf, dlen, 0);
158 for (j = dirlist->count; j--; ) {
159 struct file_struct *fp = dirlist->files[j];
160
161 if (fp->flags & FLAG_MOUNT_POINT)
162 continue;
163
164 f_name_to(fp, buf);
165 if (delete_item(buf, fp->mode, flags & ~DEL_TERSE) != 0) {
166 flist_free(dirlist);
167 return -1;
168 }
169 }
170 flist_free(dirlist);
171
172 pop_local_filters(save_filters);
173
174 if (max_delete && deletion_count >= max_delete)
175 return -1;
176
177 if (do_rmdir(fname) == 0) {
178 if (!(flags & DEL_TERSE))
179 log_delete(fname, mode);
180 deletion_count++;
181 } else if (errno != ENOTEMPTY && errno != ENOENT) {
182 rsyserr(FERROR, errno, "delete_file: rmdir %s failed",
183 full_fname(fname));
184 return -1;
185 }
186
187 return 0;
188}
189
190
191/* This function is used to implement per-directory deletion, and is used by
192 * all the --delete-WHEN options. Note that the fbuf pointer must point to a
193 * MAXPATHLEN buffer with the name of the directory in it (the functions we
194 * call will append names onto the end, but the old dir value will be restored
195 * on exit). */
196static void delete_in_dir(struct file_list *flist, char *fbuf,
197 struct file_struct *file, int allowed_lull)
198{
199 static int min_depth = MAXPATHLEN, cur_depth = -1;
200 static void *filt_array[MAXPATHLEN/2+1];
201 struct file_list *dirlist;
202 char delbuf[MAXPATHLEN];
203 STRUCT_STAT st;
204 int dlen, i;
205
206 if (!flist) {
207 while (cur_depth >= min_depth)
208 pop_local_filters(filt_array[cur_depth--]);
209 min_depth = MAXPATHLEN;
210 cur_depth = -1;
211 return;
212 }
213
214 if (verbose > 2)
215 rprintf(FINFO, "delete_in_dir(%s)\n", safe_fname(fbuf));
216
217 if (allowed_lull)
218 maybe_send_keepalive(allowed_lull, flist->count);
219
220 if (file->dir.depth >= MAXPATHLEN/2+1)
221 return; /* Impossible... */
222
223 if (max_delete && deletion_count >= max_delete)
224 return;
225
226 if (io_error && !(lp_ignore_errors(module_id) || ignore_errors)) {
227 rprintf(FINFO,
228 "IO error encountered -- skipping file deletion\n");
229 max_delete = -1; /* avoid duplicating the above warning */
230 return;
231 }
232
233 while (cur_depth >= file->dir.depth && cur_depth >= min_depth)
234 pop_local_filters(filt_array[cur_depth--]);
235 cur_depth = file->dir.depth;
236 if (min_depth > cur_depth)
237 min_depth = cur_depth;
238 dlen = strlen(fbuf);
239 filt_array[cur_depth] = push_local_filters(fbuf, dlen);
240
241 if (link_stat(fbuf, &st, keep_dirlinks) < 0)
242 return;
243
244 if (one_file_system && file->flags & FLAG_TOP_DIR)
245 filesystem_dev = st.st_dev;
246
247 dirlist = get_dirlist(fbuf, dlen, 0);
248
249 /* If an item in dirlist is not found in flist, delete it
250 * from the filesystem. */
251 for (i = dirlist->count; i--; ) {
252 if (!dirlist->files[i]->basename)
253 continue;
254 if (flist_find(flist, dirlist->files[i]) < 0) {
59faec8b 255 int mode = dirlist->files[i]->mode;
251f22b5 256 f_name_to(dirlist->files[i], delbuf);
59faec8b
WD
257 if (delete_item(delbuf, mode, DEL_FORCE_RECURSE) < 0)
258 break;
259 }
260 }
261
262 flist_free(dirlist);
263}
264
265/* This deletes any files on the receiving side that are not present on the
266 * sending side. This is used by --delete-before and --delete-after. */
267static void do_delete_pass(struct file_list *flist, int allowed_lull)
268{
269 char fbuf[MAXPATHLEN];
270 int j;
271
272 for (j = 0; j < flist->count; j++) {
273 struct file_struct *file = flist->files[j];
274
275 if (!(file->flags & FLAG_DEL_HERE))
276 continue;
277
278 f_name_to(file, fbuf);
279 if (verbose > 1 && file->flags & FLAG_TOP_DIR)
280 rprintf(FINFO, "deleting in %s\n", safe_fname(fbuf));
281
282 delete_in_dir(flist, fbuf, file, allowed_lull);
283 }
284}
285
b7e8628c 286static int unchanged_attrs(struct file_struct *file, STRUCT_STAT *st)
2f03f956 287{
b7e8628c
WD
288 if (preserve_perms
289 && (st->st_mode & CHMOD_BITS) != (file->mode & CHMOD_BITS))
84acca07 290 return 0;
bb24028f 291
b7e8628c
WD
292 if (am_root && preserve_uid && st->st_uid != file->uid)
293 return 0;
bb24028f 294
b7e8628c
WD
295 if (preserve_gid && file->gid != GID_NONE && st->st_gid != file->gid)
296 return 0;
297
298 return 1;
299}
300
06a1dbad 301
c557eb8c
WD
302#define SID_UPDATING ITEM_UPDATING
303#define SID_REPORT_CHECKSUM ITEM_REPORT_CHECKSUM
8237f930
WD
304#define SID_USING_ALT_BASIS ITEM_USING_ALT_BASIS
305/* This flag doesn't get sent, so it must be outside 0xffff. */
c557eb8c 306#define SID_NO_DEST_AND_NO_UPDATE (1<<16)
06a1dbad 307
c557eb8c
WD
308static void itemize(struct file_struct *file, int statret, STRUCT_STAT *st,
309 int32 sflags, int f_out, int ndx)
06a1dbad 310{
8237f930 311 int iflags = sflags & 0xffff;
06a1dbad 312
c557eb8c
WD
313 if (statret >= 0) {
314 if (S_ISREG(file->mode) && file->length != st->st_size)
315 iflags |= ITEM_REPORT_SIZE;
88b218fa
WD
316 if (!(sflags & SID_NO_DEST_AND_NO_UPDATE)) {
317 int keep_time = !preserve_times ? 0
318 : S_ISDIR(file->mode) ? !omit_dir_times
319 : !S_ISLNK(file->mode);
320
321 if ((iflags & ITEM_UPDATING && !keep_time)
322 || (keep_time && file->modtime != st->st_mtime))
323 iflags |= ITEM_REPORT_TIME;
324 if (preserve_perms && file->mode != st->st_mode)
325 iflags |= ITEM_REPORT_PERMS;
326 if (preserve_uid && am_root && file->uid != st->st_uid)
327 iflags |= ITEM_REPORT_OWNER;
328 if (preserve_gid && file->gid != GID_NONE
329 && st->st_gid != file->gid)
330 iflags |= ITEM_REPORT_GROUP;
331 }
c557eb8c 332 } else
88b218fa 333 iflags |= ITEM_IS_NEW | ITEM_UPDATING;
c557eb8c 334
8a8356b7 335 if ((iflags || verbose > 1) && !read_batch) {
6c3862fa
WD
336 if (protocol_version >= 29) {
337 if (ndx >= 0)
338 write_int(f_out, ndx);
339 write_shortint(f_out, iflags);
340 } else if (ndx >= 0)
341 log_recv(file, &stats, iflags);
06a1dbad
WD
342 }
343}
344
345
b7e8628c
WD
346/* Perform our quick-check heuristic for determining if a file is unchanged. */
347static int unchanged_file(char *fn, struct file_struct *file, STRUCT_STAT *st)
348{
349 if (st->st_size != file->length)
350 return 0;
59c95e42 351
2cda2560 352 /* if always checksum is set then we use the checksum instead
2f03f956
AT
353 of the file time to determine whether to sync */
354 if (always_checksum && S_ISREG(st->st_mode)) {
355 char sum[MD4_SUM_LENGTH];
b7e8628c 356 file_checksum(fn, sum, st->st_size);
728d0922 357 return memcmp(sum, file->u.sum, protocol_version < 21 ? 2
84acca07 358 : MD4_SUM_LENGTH) == 0;
2f03f956
AT
359 }
360
cc1e997d 361 if (size_only)
84acca07 362 return 1;
2f03f956 363
cc1e997d 364 if (ignore_times)
84acca07 365 return 0;
cc1e997d 366
84acca07 367 return cmp_modtime(st->st_mtime, file->modtime) == 0;
2f03f956
AT
368}
369
370
ec8290c8 371/*
195bd906 372 * set (initialize) the size entries in the per-file sum_struct
ec8290c8 373 * calculating dynamic block and checksum sizes.
195bd906 374 *
ec8290c8 375 * This is only called from generate_and_send_sums() but is a separate
195bd906
S
376 * function to encapsulate the logic.
377 *
378 * The block size is a rounded square root of file length.
379 *
380 * The checksum size is determined according to:
381 * blocksum_bits = BLOCKSUM_EXP + 2*log2(file_len) - log2(block_len)
382 * provided by Donovan Baarda which gives a probability of rsync
383 * algorithm corrupting data and falling back using the whole md4
384 * checksums.
385 *
386 * This might be made one of several selectable heuristics.
387 */
1490812a 388static void sum_sizes_sqroot(struct sum_struct *sum, int64 len)
195bd906 389{
a255c592 390 int32 blength;
da9d12f5 391 int s2length;
195bd906 392
a255c592 393 if (block_size)
195bd906 394 blength = block_size;
a255c592 395 else if (len <= BLOCK_SIZE * BLOCK_SIZE)
195bd906 396 blength = BLOCK_SIZE;
a255c592
WD
397 else {
398 int32 c;
1490812a 399 int64 l;
eae7165c
WD
400 int cnt;
401 for (c = 1, l = len, cnt = 0; l >>= 2; c <<= 1, cnt++) {}
402 if (cnt >= 31 || c >= MAX_BLOCK_SIZE)
403 blength = MAX_BLOCK_SIZE;
404 else {
405 blength = 0;
406 do {
407 blength |= c;
1490812a 408 if (len < (int64)blength * blength)
eae7165c
WD
409 blength &= ~c;
410 c >>= 1;
411 } while (c >= 8); /* round to multiple of 8 */
412 blength = MAX(blength, BLOCK_SIZE);
195bd906 413 }
195bd906
S
414 }
415
d04e9c51 416 if (protocol_version < 27) {
195bd906
S
417 s2length = csum_length;
418 } else if (csum_length == SUM_LENGTH) {
419 s2length = SUM_LENGTH;
420 } else {
a255c592 421 int32 c;
1490812a 422 int64 l;
da9d12f5 423 int b = BLOCKSUM_BIAS;
a255c592
WD
424 for (l = len; l >>= 1; b += 2) {}
425 for (c = blength; c >>= 1 && b; b--) {}
426 /* add a bit, subtract rollsum, round up. */
427 s2length = (b + 1 - 32 + 7) / 8; /* --optimize in compiler-- */
195bd906
S
428 s2length = MAX(s2length, csum_length);
429 s2length = MIN(s2length, SUM_LENGTH);
430 }
431
432 sum->flength = len;
433 sum->blength = blength;
434 sum->s2length = s2length;
435 sum->count = (len + (blength - 1)) / blength;
436 sum->remainder = (len % blength);
437
438 if (sum->count && verbose > 2) {
a255c592
WD
439 rprintf(FINFO,
440 "count=%.0f rem=%ld blength=%ld s2length=%d flength=%.0f\n",
441 (double)sum->count, (long)sum->remainder, (long)sum->blength,
da9d12f5 442 sum->s2length, (double)sum->flength);
195bd906
S
443 }
444}
80605142 445
bceec82f 446
80605142
WD
447/*
448 * Generate and send a stream of signatures/checksums that describe a buffer
e66dfd18 449 *
80605142
WD
450 * Generate approximately one checksum every block_len bytes.
451 */
cd6aa5b5 452static void generate_and_send_sums(int fd, OFF_T len, int f_out, int f_copy)
2f03f956 453{
a1cbe76e 454 int32 i;
6e45e1dd 455 struct map_struct *mapbuf;
80605142 456 struct sum_struct sum;
2f03f956
AT
457 OFF_T offset = 0;
458
423dba8e 459 sum_sizes_sqroot(&sum, len);
e66dfd18 460
6e45e1dd 461 if (len > 0)
96d910c7 462 mapbuf = map_file(fd, len, MAX_MAP_SIZE, sum.blength);
6e45e1dd
WD
463 else
464 mapbuf = NULL;
465
fc0257c9 466 write_sum_head(f_out, &sum);
2f03f956 467
80605142 468 for (i = 0; i < sum.count; i++) {
a255c592 469 int32 n1 = (int32)MIN(len, (OFF_T)sum.blength);
6e45e1dd 470 char *map = map_ptr(mapbuf, offset, n1);
80605142
WD
471 uint32 sum1 = get_checksum1(map, n1);
472 char sum2[SUM_LENGTH];
2f03f956 473
cd6aa5b5
WD
474 if (f_copy >= 0)
475 full_write(f_copy, map, n1);
476
80605142 477 get_checksum2(map, n1, sum2);
2f03f956 478
80605142 479 if (verbose > 3) {
e66dfd18 480 rprintf(FINFO,
a255c592
WD
481 "chunk[%.0f] offset=%.0f len=%ld sum1=%08lx\n",
482 (double)i, (double)offset, (long)n1,
0e36d9da 483 (unsigned long)sum1);
80605142
WD
484 }
485 write_int(f_out, sum1);
fc0257c9 486 write_buf(f_out, sum2, sum.s2length);
2f03f956
AT
487 len -= n1;
488 offset += n1;
489 }
6e45e1dd
WD
490
491 if (mapbuf)
492 unmap_file(mapbuf);
2f03f956
AT
493}
494
06a1dbad 495
8e85be0a
WD
496/* Try to find a filename in the same dir as "fname" with a similar name. */
497static int find_fuzzy(struct file_struct *file, struct file_list *dirlist)
498{
499 int fname_len, fname_suf_len;
500 const char *fname_suf, *fname = file->basename;
501 uint32 lowest_dist = 0x7FFFFFFF;
502 int j, lowest_j = -1;
503
504 fname_len = strlen(fname);
505 fname_suf = find_filename_suffix(fname, fname_len, &fname_suf_len);
506
507 for (j = 0; j < dirlist->count; j++) {
508 struct file_struct *fp = dirlist->files[j];
509 const char *suf, *name;
510 int len, suf_len;
511 uint32 dist;
512
513 if (!S_ISREG(fp->mode) || !fp->length
514 || fp->flags & FLAG_NO_FUZZY)
515 continue;
516
517 name = fp->basename;
518
519 if (fp->length == file->length
520 && fp->modtime == file->modtime) {
521 if (verbose > 4) {
522 rprintf(FINFO,
523 "fuzzy size/modtime match for %s\n",
524 name);
525 }
526 return j;
527 }
528
529 len = strlen(name);
530 suf = find_filename_suffix(name, len, &suf_len);
531
532 dist = fuzzy_distance(name, len, fname, fname_len);
533 /* Add some extra weight to how well the suffixes match. */
534 dist += fuzzy_distance(suf, suf_len, fname_suf, fname_suf_len)
535 * 10;
536 if (verbose > 4) {
537 rprintf(FINFO, "fuzzy distance for %s = %d.%05d\n",
538 name, (int)(dist>>16), (int)(dist&0xFFFF));
539 }
540 if (dist <= lowest_dist) {
541 lowest_dist = dist;
542 lowest_j = j;
543 }
544 }
545
546 return lowest_j;
547}
548
2f03f956 549
0492fdfb
WD
550/* Acts on flist->file's ndx'th item, whose name is fname. If a directory,
551 * make sure it exists, and has the right permissions/timestamp info. For
552 * all other non-regular files (symlinks, etc.) we create them here. For
553 * regular files that have changed, we try to find a basis file and then
554 * start sending checksums.
ef1aa910 555 *
0492fdfb
WD
556 * Note that f_out is set to -1 when doing final directory-permission and
557 * modification-time repair. */
fa13f396 558static void recv_generator(char *fname, struct file_list *flist,
0492fdfb 559 struct file_struct *file, int ndx,
7433d73a 560 int itemizing, int maybe_PERMS_REPORT,
59faec8b 561 enum logcode code, int allowed_lull,
41cfde6b 562 int f_out, int f_out_name)
2cda2560 563{
8174bc35 564 static int missing_below = -1, excluded_below = -1;
8e85be0a
WD
565 static char *fuzzy_dirname = NULL;
566 static struct file_list *fuzzy_dirlist = NULL;
567 struct file_struct *fuzzy_file = NULL;
41cfde6b 568 int fd = -1, f_copy = -1;
89f7eff3 569 STRUCT_STAT st, partial_st;
41cfde6b 570 struct file_struct *back_file = NULL;
e7d13fe5 571 int statret, stat_errno;
41cfde6b 572 char *fnamecmp, *partialptr, *backupptr = NULL;
375a4556 573 char fnamecmpbuf[MAXPATHLEN];
41cfde6b 574 uchar fnamecmp_type;
f7632fc6 575
dfd5ba6a
WD
576 if (list_only)
577 return;
2f03f956 578
8e85be0a
WD
579 if (!fname) {
580 if (fuzzy_dirlist) {
581 flist_free(fuzzy_dirlist);
582 fuzzy_dirlist = NULL;
583 fuzzy_dirname = NULL;
584 }
585 if (missing_below >= 0) {
586 dry_run--;
587 missing_below = -1;
588 }
589 return;
590 }
591
4875d6b6
WD
592 if (verbose > 2) {
593 rprintf(FINFO, "recv_generator(%s,%d)\n",
594 safe_fname(fname), ndx);
595 }
2f03f956 596
8174bc35
WD
597 if (server_filter_list.head) {
598 if (excluded_below >= 0) {
599 if (file->dir.depth > excluded_below)
600 goto skipping;
601 excluded_below = -1;
602 }
603 if (check_filter(&server_filter_list, fname,
604 S_ISDIR(file->mode)) < 0) {
605 if (S_ISDIR(file->mode))
606 excluded_below = file->dir.depth;
607 skipping:
608 if (verbose) {
609 rprintf(FINFO,
610 "skipping server-excluded file \"%s\"\n",
611 safe_fname(fname));
612 }
613 return;
3e35c34b 614 }
3e35c34b 615 }
97f9dcae 616
8e85be0a 617 if (missing_below >= 0 && file->dir.depth <= missing_below) {
df337831
WD
618 dry_run--;
619 missing_below = -1;
620 }
73f7af0e
WD
621 if (dry_run > 1) {
622 statret = -1;
623 stat_errno = ENOENT;
624 } else {
8e85be0a
WD
625 if (fuzzy_basis && S_ISREG(file->mode)) {
626 char *dn = file->dirname ? file->dirname : ".";
627 /* Yes, identical dirnames are guaranteed to have
628 * identical pointers at this point. */
629 if (fuzzy_dirname != dn) {
630 if (fuzzy_dirlist)
631 flist_free(fuzzy_dirlist);
632 fuzzy_dirname = dn;
59faec8b
WD
633 fuzzy_dirlist = get_dirlist(fuzzy_dirname, -1,
634 1);
8e85be0a
WD
635 }
636 }
637
73f7af0e
WD
638 statret = link_stat(fname, &st,
639 keep_dirlinks && S_ISDIR(file->mode));
640 stat_errno = errno;
641 }
63787382 642
a7260c40 643 if (only_existing && statret == -1 && stat_errno == ENOENT) {
1347d512 644 /* we only want to update existing files */
ecc81fce
WD
645 if (verbose > 1) {
646 rprintf(FINFO, "not creating new file \"%s\"\n",
647 safe_fname(fname));
648 }
1347d512
AT
649 return;
650 }
651
d9b4d267
WD
652 if (statret == 0 && !preserve_perms
653 && S_ISDIR(st.st_mode) == S_ISDIR(file->mode)) {
4df9f368 654 /* if the file exists already and we aren't perserving
2cda2560
WD
655 * permissions then act as though the remote end sent
656 * us the file permissions we already have */
67e78a82
WD
657 file->mode = (file->mode & ~CHMOD_BITS)
658 | (st.st_mode & CHMOD_BITS);
4df9f368
AT
659 }
660
2f03f956 661 if (S_ISDIR(file->mode)) {
2cda2560
WD
662 /* The file to be received is a directory, so we need
663 * to prepare appropriately. If there is already a
664 * file of that name and it is *not* a directory, then
665 * we need to delete it. If it doesn't exist, then
027428eb 666 * (perhaps recursively) create it. */
2f03f956 667 if (statret == 0 && !S_ISDIR(st.st_mode)) {
59faec8b 668 delete_item(fname, st.st_mode, DEL_TERSE);
2f03f956
AT
669 statret = -1;
670 }
df337831
WD
671 if (dry_run && statret != 0 && missing_below < 0) {
672 missing_below = file->dir.depth;
673 dry_run++;
674 }
6c3862fa 675 if (itemizing && f_out != -1)
c557eb8c 676 itemize(file, statret, &st, 0, f_out, ndx);
2f03f956 677 if (statret != 0 && do_mkdir(fname,file->mode) != 0 && errno != EEXIST) {
027428eb
WD
678 if (!relative_paths || errno != ENOENT
679 || create_directory_path(fname, orig_umask) < 0
680 || do_mkdir(fname, file->mode) < 0) {
d62bcc17
WD
681 rsyserr(FERROR, errno,
682 "recv_generator: mkdir %s failed",
683 full_fname(fname));
2f03f956
AT
684 }
685 }
716e73d4 686 if (set_perms(fname, file, statret ? NULL : &st, 0)
6c3862fa
WD
687 && verbose && code && f_out != -1)
688 rprintf(code, "%s/\n", safe_fname(fname));
c93fad5e 689 if (delete_during && f_out != -1 && csum_length != SUM_LENGTH
31937d36 690 && (file->flags & FLAG_DEL_HERE))
59faec8b 691 delete_in_dir(flist, fname, file, allowed_lull);
2f03f956 692 return;
06a1dbad 693 }
6c3862fa 694
06a1dbad 695 if (max_size && file->length > max_size) {
4875d6b6
WD
696 if (verbose > 1) {
697 rprintf(FINFO, "%s is over max-size\n",
698 safe_fname(fname));
699 }
7d1bfaf7 700 return;
2f03f956
AT
701 }
702
703 if (preserve_links && S_ISLNK(file->mode)) {
4f5b0756 704#ifdef SUPPORT_LINKS
728d0922 705 if (safe_symlinks && unsafe_symlink(file->u.link, fname)) {
2f03f956 706 if (verbose) {
4875d6b6
WD
707 rprintf(FINFO,
708 "ignoring unsafe symlink %s -> \"%s\"\n",
709 full_fname(fname),
710 safe_fname(file->u.link));
2f03f956
AT
711 }
712 return;
713 }
714 if (statret == 0) {
7e38410e
WD
715 char lnk[MAXPATHLEN];
716 int len;
717
8a8356b7 718 if (!S_ISDIR(st.st_mode)
7e38410e
WD
719 && (len = readlink(fname, lnk, MAXPATHLEN-1)) > 0) {
720 lnk[len] = 0;
85d4d142
MP
721 /* A link already pointing to the
722 * right place -- no further action
723 * required. */
7e38410e 724 if (strcmp(lnk, file->u.link) == 0) {
6c3862fa 725 if (itemizing) {
c557eb8c
WD
726 itemize(file, 0, &st, 0,
727 f_out, ndx);
728 }
c41b52c4 729 set_perms(fname, file, &st,
8a8356b7 730 maybe_PERMS_REPORT);
2f03f956
AT
731 return;
732 }
2cda2560 733 }
7e38410e
WD
734 /* Not the right symlink (or not a symlink), so
735 * delete it. */
88b218fa 736 if (S_ISLNK(st.st_mode))
59faec8b 737 delete_item(fname, st.st_mode, DEL_TERSE);
88b218fa 738 else {
59faec8b 739 delete_item(fname, st.st_mode, DEL_TERSE);
88b218fa
WD
740 statret = -1;
741 }
2f03f956 742 }
728d0922 743 if (do_symlink(file->u.link,fname) != 0) {
d62bcc17 744 rsyserr(FERROR, errno, "symlink %s -> \"%s\" failed",
ecc81fce 745 full_fname(fname), safe_fname(file->u.link));
2f03f956
AT
746 } else {
747 set_perms(fname,file,NULL,0);
6c3862fa 748 if (itemizing) {
c557eb8c
WD
749 itemize(file, statret, &st, SID_UPDATING,
750 f_out, ndx);
6c3862fa
WD
751 }
752 if (code && verbose) {
753 rprintf(code, "%s -> %s\n", safe_fname(fname),
c557eb8c 754 safe_fname(file->u.link));
2f03f956 755 }
fe960187
WD
756 if (remove_sent_files && !dry_run) {
757 char numbuf[4];
758 SIVAL(numbuf, 0, ndx);
759 send_msg(MSG_SUCCESS, numbuf, 4);
760 }
2f03f956
AT
761 }
762#endif
763 return;
764 }
765
2f03f956 766 if (am_root && preserve_devices && IS_DEVICE(file->mode)) {
2cda2560 767 if (statret != 0 ||
2f03f956 768 st.st_mode != file->mode ||
3915fd75 769 st.st_rdev != file->u.rdev) {
59faec8b
WD
770 delete_item(fname, st.st_mode, DEL_TERSE);
771 if (!IS_DEVICE(st.st_mode))
88b218fa 772 statret = -1;
d62bcc17 773 if (verbose > 2) {
2f03f956 774 rprintf(FINFO,"mknod(%s,0%o,0x%x)\n",
ecc81fce
WD
775 safe_fname(fname),
776 (int)file->mode, (int)file->u.rdev);
d62bcc17 777 }
728d0922 778 if (do_mknod(fname,file->mode,file->u.rdev) != 0) {
d62bcc17
WD
779 rsyserr(FERROR, errno, "mknod %s failed",
780 full_fname(fname));
2f03f956
AT
781 } else {
782 set_perms(fname,file,NULL,0);
6c3862fa 783 if (itemizing) {
88b218fa
WD
784 itemize(file, statret, &st, SID_UPDATING,
785 f_out, ndx);
6c3862fa
WD
786 }
787 if (code && verbose) {
788 rprintf(code, "%s\n",
ecc81fce
WD
789 safe_fname(fname));
790 }
2f03f956
AT
791 }
792 } else {
6c3862fa 793 if (itemizing) {
c557eb8c
WD
794 itemize(file, statret, &st, 0,
795 f_out, ndx);
796 }
8a8356b7 797 set_perms(fname, file, &st, maybe_PERMS_REPORT);
2f03f956
AT
798 }
799 return;
800 }
2f03f956 801
6dff5992 802 if (preserve_hard_links && hard_link_check(file, HL_CHECK_MASTER))
2f03f956 803 return;
2f03f956
AT
804
805 if (!S_ISREG(file->mode)) {
ecc81fce
WD
806 rprintf(FINFO, "skipping non-regular file \"%s\"\n",
807 safe_fname(fname));
2f03f956
AT
808 return;
809 }
810
375a4556 811 fnamecmp = fname;
41cfde6b 812 fnamecmp_type = FNAMECMP_FNAME;
375a4556 813
06a1dbad 814 if (statret != 0 && basis_dir[0] != NULL) {
aef98825 815 int best_match = -1;
b7e8628c
WD
816 int match_level = 0;
817 int i = 0;
818 do {
819 pathjoin(fnamecmpbuf, sizeof fnamecmpbuf,
820 basis_dir[i], fname);
aef98825
WD
821 if (link_stat(fnamecmpbuf, &st, 0) < 0
822 || !S_ISREG(st.st_mode))
823 continue;
824 switch (match_level) {
825 case 0:
826 best_match = i;
827 match_level = 1;
aef98825
WD
828 /* FALL THROUGH */
829 case 1:
830 if (!unchanged_file(fnamecmpbuf, file, &st))
831 continue;
832 best_match = i;
833 match_level = 2;
834 /* FALL THROUGH */
835 case 2:
836 if (!unchanged_attrs(file, &st))
837 continue;
838 best_match = i;
b7e8628c
WD
839 match_level = 3;
840 break;
841 }
aef98825 842 break;
b7e8628c 843 } while (basis_dir[++i] != NULL);
aef98825 844 if (match_level) {
9ba46343 845 statret = 0;
aef98825
WD
846 if (i != best_match) {
847 i = best_match;
b7e8628c
WD
848 pathjoin(fnamecmpbuf, sizeof fnamecmpbuf,
849 basis_dir[i], fname);
9ba46343
WD
850 if (link_stat(fnamecmpbuf, &st, 0) < 0) {
851 match_level = 0;
852 statret = -1;
853 }
b7e8628c 854 }
4f5b0756 855#ifdef HAVE_LINK
70b54e4e
WD
856 if (link_dest && match_level == 3
857 && do_link(fnamecmpbuf, fname) < 0) {
858 if (verbose) {
859 rsyserr(FINFO, errno, "link %s => %s",
860 full_fname(fnamecmpbuf),
861 safe_fname(fname));
e7bc9b64 862 }
e2243317 863 match_level = 2;
70b54e4e 864 }
59c95e42 865#endif
e2243317 866 if (compare_dest || (match_level && match_level < 3)) {
e7d13fe5 867 fnamecmp = fnamecmpbuf;
2be2fb3e 868 fnamecmp_type = i;
41cfde6b 869 }
e7d13fe5
WD
870 }
871 }
872
873 if (statret == 0 && !S_ISREG(st.st_mode)) {
59faec8b 874 if (delete_item(fname, st.st_mode, DEL_TERSE) != 0)
e7d13fe5
WD
875 return;
876 statret = -1;
877 stat_errno = ENOENT;
375a4556
DD
878 }
879
9d954dca 880 if (partial_dir && (partialptr = partial_dir_fname(fname)) != NULL
72c19bb3
WD
881 && link_stat(partialptr, &partial_st, 0) == 0
882 && S_ISREG(partial_st.st_mode)) {
06a1dbad 883 if (statret != 0)
72c19bb3
WD
884 goto prepare_to_open;
885 } else
886 partialptr = NULL;
89f7eff3 887
06a1dbad 888 if (statret != 0 && fuzzy_basis && dry_run <= 1) {
8e85be0a
WD
889 int j = find_fuzzy(file, fuzzy_dirlist);
890 if (j >= 0) {
891 fuzzy_file = fuzzy_dirlist->files[j];
892 f_name_to(fuzzy_file, fnamecmpbuf);
893 if (verbose > 2) {
894 rprintf(FINFO, "fuzzy basis selected for %s: %s\n",
895 safe_fname(fname), safe_fname(fnamecmpbuf));
896 }
897 st.st_mode = fuzzy_file->mode;
898 st.st_size = fuzzy_file->length;
899 st.st_mtime = fuzzy_file->modtime;
900 statret = 0;
901 fnamecmp = fnamecmpbuf;
902 fnamecmp_type = FNAMECMP_FUZZY;
903 }
904 }
905
06a1dbad 906 if (statret != 0) {
6dff5992
WD
907 if (preserve_hard_links && hard_link_check(file, HL_SKIP))
908 return;
41cfde6b
WD
909 if (stat_errno == ENOENT)
910 goto notify_others;
911 if (verbose > 1) {
e7d13fe5
WD
912 rsyserr(FERROR, stat_errno,
913 "recv_generator: failed to stat %s",
d62bcc17 914 full_fname(fname));
2f03f956
AT
915 }
916 return;
917 }
918
41cfde6b 919 if (opt_ignore_existing && fnamecmp_type == FNAMECMP_FNAME) {
3d6feada 920 if (verbose > 1)
ecc81fce 921 rprintf(FINFO, "%s exists\n", safe_fname(fname));
3d6feada 922 return;
2cda2560 923 }
3d6feada 924
41cfde6b 925 if (update_only && fnamecmp_type == FNAMECMP_FNAME
d3a4375f 926 && cmp_modtime(st.st_mtime, file->modtime) > 0) {
2f03f956 927 if (verbose > 1)
ecc81fce 928 rprintf(FINFO, "%s is newer\n", safe_fname(fname));
2f03f956
AT
929 return;
930 }
931
2be2fb3e 932 if (!compare_dest && fnamecmp_type <= FNAMECMP_BASIS_DIR_HIGH)
b7e8628c 933 ;
8e85be0a
WD
934 else if (fnamecmp_type == FNAMECMP_FUZZY)
935 ;
b7e8628c 936 else if (unchanged_file(fnamecmp, file, &st)) {
6c3862fa 937 if (itemizing) {
c557eb8c
WD
938 itemize(file, statret, &st,
939 fnamecmp_type == FNAMECMP_FNAME
940 ? 0 : SID_NO_DEST_AND_NO_UPDATE,
941 f_out, ndx);
06a1dbad 942 }
41cfde6b 943 if (fnamecmp_type == FNAMECMP_FNAME)
8a8356b7 944 set_perms(fname, file, &st, maybe_PERMS_REPORT);
2f03f956
AT
945 return;
946 }
947
89f7eff3 948prepare_to_open:
9d954dca
WD
949 if (partialptr) {
950 st = partial_st;
951 fnamecmp = partialptr;
952 fnamecmp_type = FNAMECMP_PARTIAL_DIR;
953 statret = 0;
954 }
955
3841a04e
WD
956 if (dry_run || read_batch)
957 goto notify_others;
958 if (whole_file > 0) {
06a1dbad
WD
959 if (statret == 0)
960 statret = 1;
41cfde6b 961 goto notify_others;
2f03f956
AT
962 }
963
8e85be0a
WD
964 if (fuzzy_basis) {
965 int j = flist_find(fuzzy_dirlist, file);
966 if (j >= 0) /* don't use changing file as future fuzzy basis */
967 fuzzy_dirlist->files[j]->flags |= FLAG_NO_FUZZY;
968 }
969
2cda2560 970 /* open the file */
8c9fd200 971 fd = do_open(fnamecmp, O_RDONLY, 0);
2f03f956
AT
972
973 if (fd == -1) {
d62bcc17
WD
974 rsyserr(FERROR, errno, "failed to open %s, continuing",
975 full_fname(fnamecmp));
cd6aa5b5 976 pretend_missing:
60be6acf 977 /* pretend the file didn't exist */
6dff5992
WD
978 if (preserve_hard_links && hard_link_check(file, HL_SKIP))
979 return;
41cfde6b
WD
980 statret = -1;
981 goto notify_others;
2f03f956
AT
982 }
983
cd6aa5b5
WD
984 if (inplace && make_backups) {
985 if (!(backupptr = get_backup_name(fname))) {
986 close(fd);
987 return;
988 }
7842418b 989 if (!(back_file = make_file(fname, NULL, NO_FILTERS))) {
cd6aa5b5
WD
990 close(fd);
991 goto pretend_missing;
992 }
993 if (robust_unlink(backupptr) && errno != ENOENT) {
994 rsyserr(FERROR, errno, "unlink %s",
995 full_fname(backupptr));
996 free(back_file);
997 close(fd);
998 return;
999 }
1000 if ((f_copy = do_open(backupptr,
1001 O_WRONLY | O_CREAT | O_TRUNC | O_EXCL, 0600)) < 0) {
1002 rsyserr(FERROR, errno, "open %s",
1003 full_fname(backupptr));
1004 free(back_file);
1005 close(fd);
1006 return;
1007 }
41cfde6b 1008 fnamecmp_type = FNAMECMP_BACKUP;
cd6aa5b5
WD
1009 }
1010
dfd5ba6a 1011 if (verbose > 3) {
ecc81fce
WD
1012 rprintf(FINFO, "gen mapped %s of size %.0f\n",
1013 safe_fname(fnamecmp), (double)st.st_size);
dfd5ba6a 1014 }
2f03f956 1015
2f03f956 1016 if (verbose > 2)
0492fdfb 1017 rprintf(FINFO, "generating and sending sums for %d\n", ndx);
2f03f956 1018
41cfde6b 1019notify_others:
0492fdfb 1020 write_int(f_out, ndx);
6c3862fa 1021 if (itemizing) {
8237f930
WD
1022 int iflags = SID_UPDATING;
1023 if (always_checksum)
1024 iflags |= SID_REPORT_CHECKSUM;
352963dd 1025 if (fnamecmp_type != FNAMECMP_FNAME)
8237f930
WD
1026 iflags |= SID_USING_ALT_BASIS;
1027 itemize(file, statret, &st, iflags, f_out, -1);
e3bcd893 1028 }
8e85be0a 1029 if (f_out_name >= 0) {
41cfde6b 1030 write_byte(f_out_name, fnamecmp_type);
8e85be0a
WD
1031 if (fnamecmp_type == FNAMECMP_FUZZY) {
1032 uchar lenbuf[3], *lb = lenbuf;
1033 int len = strlen(fuzzy_file->basename);
1034 if (len > 0x7F) {
1035#if MAXPATHLEN > 0x7FFF
1036 *lb++ = len / 0x10000 + 0x80;
1037 *lb++ = len / 0x100;
1038#else
1039 *lb++ = len / 0x100 + 0x80;
1040#endif
1041 }
1042 *lb = len;
ee03617b 1043 write_buf(f_out_name, (char*)lenbuf, lb - lenbuf + 1);
8e85be0a
WD
1044 write_buf(f_out_name, fuzzy_file->basename, len);
1045 }
1046 }
cd6aa5b5 1047
41cfde6b
WD
1048 if (dry_run || read_batch)
1049 return;
1050
1051 if (statret == 0) {
1052 generate_and_send_sums(fd, st.st_size, f_out, f_copy);
2f03f956 1053
41cfde6b
WD
1054 if (f_copy >= 0) {
1055 close(f_copy);
1056 set_perms(backupptr, back_file, NULL, 0);
1057 if (verbose > 1) {
1058 rprintf(FINFO, "backed up %s to %s\n",
4875d6b6 1059 safe_fname(fname), safe_fname(backupptr));
41cfde6b
WD
1060 }
1061 free(back_file);
1062 }
1063
1064 close(fd);
1065 } else
1066 write_sum_head(f_out, NULL);
2f03f956
AT
1067}
1068
1069
41cfde6b
WD
1070void generate_files(int f_out, struct file_list *flist, char *local_name,
1071 int f_out_name)
2f03f956
AT
1072{
1073 int i;
e1f67417 1074 int phase = 0;
968c8030 1075 char fbuf[MAXPATHLEN];
7433d73a
WD
1076 int itemizing, maybe_PERMS_REPORT;
1077 enum logcode code;
3ea9bbd6
WD
1078 int need_retouch_dir_times = preserve_times && !omit_dir_times;
1079 int need_retouch_dir_perms = 0;
0492fdfb
WD
1080 int save_only_existing = only_existing;
1081 int save_opt_ignore_existing = opt_ignore_existing;
662bdcd4 1082 int allowed_lull = read_batch ? 0 : (io_timeout + 1) / 2;
18a11cfd 1083 int lull_mod = allowed_lull * 5;
7433d73a
WD
1084
1085 if (protocol_version >= 29) {
1086 itemizing = 1;
1087 maybe_PERMS_REPORT = log_format_has_i ? 0 : PERMS_REPORT;
1088 code = daemon_log_format_has_i ? 0 : FLOG;
1089 } else if (am_daemon) {
1090 itemizing = daemon_log_format_has_i && !dry_run;
1091 maybe_PERMS_REPORT = PERMS_REPORT;
1092 code = itemizing || dry_run ? FCLIENT : FINFO;
1093 } else if (!am_server) {
1094 itemizing = log_format_has_i;
1095 maybe_PERMS_REPORT = log_format_has_i ? 0 : PERMS_REPORT;
1096 code = itemizing ? 0 : FINFO;
1097 } else {
1098 itemizing = 0;
1099 maybe_PERMS_REPORT = PERMS_REPORT;
1100 code = FINFO;
1101 }
2f03f956 1102
45e08edb
WD
1103 if (verbose > 2) {
1104 rprintf(FINFO, "generator starting pid=%ld count=%d\n",
1105 (long)getpid(), flist->count);
1106 }
2f03f956 1107
59faec8b
WD
1108 if (delete_before && !local_name && flist->count > 0)
1109 do_delete_pass(flist, allowed_lull);
1110
3e7053ac 1111 if (verbose >= 2) {
1b1fef20 1112 rprintf(FINFO, "delta-transmission %s\n",
f38bd4a0 1113 whole_file > 0
1b1fef20
WD
1114 ? "disabled for local transfer or --whole-file"
1115 : "enabled");
3e7053ac 1116 }
2cda2560 1117
9ac2395b 1118 if (protocol_version < 29)
7433d73a 1119 ignore_timeout = 1;
a57873b7 1120
2f03f956
AT
1121 for (i = 0; i < flist->count; i++) {
1122 struct file_struct *file = flist->files[i];
dfd5ba6a 1123 struct file_struct copy;
2f03f956 1124
dfd5ba6a
WD
1125 if (!file->basename)
1126 continue;
0492fdfb
WD
1127
1128 /* We need to ensure that any dirs we create have writeable
1129 * permissions during the time we are putting files within
1130 * them. This is then fixed after the transfer is done. */
dfd5ba6a
WD
1131 if (!am_root && S_ISDIR(file->mode) && !(file->mode & S_IWUSR)) {
1132 copy = *file;
dfd5ba6a
WD
1133 copy.mode |= S_IWUSR; /* user write */
1134 file = &copy;
3ea9bbd6 1135 need_retouch_dir_perms = 1;
2f03f956
AT
1136 }
1137
3fef5364 1138 recv_generator(local_name ? local_name : f_name_to(file, fbuf),
7433d73a 1139 flist, file, i, itemizing, maybe_PERMS_REPORT,
59faec8b 1140 code, allowed_lull, f_out, f_out_name);
9ac2395b 1141
18a11cfd 1142 if (allowed_lull && !(i % lull_mod))
9ac2395b 1143 maybe_send_keepalive(allowed_lull, flist->count);
2f03f956 1144 }
59faec8b 1145 recv_generator(NULL, NULL, NULL, 0, 0, 0, code, 0, -1, -1);
c93fad5e 1146 if (delete_during)
59faec8b 1147 delete_in_dir(NULL, NULL, NULL, 0);
2f03f956
AT
1148
1149 phase++;
1150 csum_length = SUM_LENGTH;
0492fdfb
WD
1151 only_existing = max_size = opt_ignore_existing = 0;
1152 update_only = always_checksum = size_only = 0;
e1f67417 1153 ignore_times = 1;
e6bc6f42 1154 make_backups = 0; /* avoid a duplicate backup for inplace processing */
2f03f956 1155
9ac2395b
WD
1156 /* We expect to just sit around now, so don't exit on a timeout.
1157 * If we really get a timeout then the other process should exit. */
1158 ignore_timeout = 1;
1159
2f03f956
AT
1160 if (verbose > 2)
1161 rprintf(FINFO,"generate_files phase=%d\n",phase);
1162
7daccb8e 1163 write_int(f_out, -1);
2f03f956 1164
bc63ae3f
S
1165 /* files can cycle through the system more than once
1166 * to catch initial checksum errors */
b9b15fb1 1167 while ((i = get_redo_num()) != -1) {
bc63ae3f 1168 struct file_struct *file = flist->files[i];
3fef5364 1169 recv_generator(local_name ? local_name : f_name_to(file, fbuf),
7433d73a 1170 flist, file, i, itemizing, maybe_PERMS_REPORT,
59faec8b 1171 code, allowed_lull, f_out, f_out_name);
bc63ae3f 1172 }
2f03f956 1173
bc63ae3f 1174 phase++;
0492fdfb
WD
1175 only_existing = save_only_existing;
1176 opt_ignore_existing = save_opt_ignore_existing;
1177
bc63ae3f
S
1178 if (verbose > 2)
1179 rprintf(FINFO,"generate_files phase=%d\n",phase);
2f03f956 1180
7daccb8e 1181 write_int(f_out, -1);
6dff5992 1182
b0da4b23
WD
1183 /* Read post-redo-phase MSG_DONE and any prior messages. */
1184 get_redo_num();
1185
6dff5992 1186 if (preserve_hard_links)
18a11cfd 1187 do_hard_links(allowed_lull, flist->count);
6dff5992 1188
59faec8b
WD
1189 if (delete_after && !local_name && flist->count > 0)
1190 do_delete_pass(flist, allowed_lull);
1191
0492fdfb
WD
1192 if ((need_retouch_dir_perms || need_retouch_dir_times)
1193 && !list_only && !local_name && !dry_run) {
18a11cfd 1194 int j = 0;
3ea9bbd6
WD
1195 /* Now we need to fix any directory permissions that were
1196 * modified during the transfer and/or re-set any tweaked
1197 * modified-time values. */
1198 for (i = 0; i < flist->count; i++) {
1199 struct file_struct *file = flist->files[i];
1200 if (!file->basename || !S_ISDIR(file->mode))
1201 continue;
1202 if (!need_retouch_dir_times && file->mode & S_IWUSR)
1203 continue;
1204 recv_generator(local_name ? local_name : f_name(file),
7433d73a 1205 flist, file, i, itemizing,
59faec8b
WD
1206 maybe_PERMS_REPORT, code, allowed_lull,
1207 -1, -1);
18a11cfd 1208 if (allowed_lull && !(j++ % lull_mod))
b5587288 1209 maybe_send_keepalive(allowed_lull, flist->count);
3ea9bbd6 1210 }
6dff5992 1211 }
59faec8b 1212 recv_generator(NULL, NULL, NULL, 0, 0, 0, code, 0, -1, -1);
6dff5992
WD
1213
1214 if (verbose > 2)
1215 rprintf(FINFO,"generate_files finished\n");
2f03f956 1216}