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