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