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