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