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