Added testing of the --itemize-changes output for devices.
[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
AT
40extern int preserve_devices;
41extern int preserve_hard_links;
6744b62d
WD
42extern int preserve_perms;
43extern int preserve_uid;
44extern int preserve_gid;
3ea9bbd6
WD
45extern int preserve_times;
46extern int omit_dir_times;
59faec8b 47extern int delete_before;
fa13f396 48extern int delete_during;
59faec8b
WD
49extern int delete_after;
50extern int module_id;
51extern int ignore_errors;
fe960187 52extern int remove_sent_files;
70352269 53extern int delay_updates;
2f03f956 54extern int update_only;
e90aab49
WD
55extern int ignore_existing;
56extern int ignore_non_existing;
cd6aa5b5 57extern int inplace;
6cc11982 58extern int append_mode;
cd6aa5b5 59extern int make_backups;
2f03f956
AT
60extern int csum_length;
61extern int ignore_times;
f83f0548 62extern int size_only;
7d1bfaf7 63extern OFF_T max_size;
02b5cb23 64extern OFF_T min_size;
59faec8b 65extern int io_error;
ac40b747 66extern int allowed_lull;
ee1d11c4 67extern int sock_f_out;
9ac2395b 68extern int ignore_timeout;
d04e9c51 69extern int protocol_version;
8e85be0a 70extern int fuzzy_basis;
2f03f956 71extern int always_checksum;
cfe39780 72extern int checksum_len;
a7260c40 73extern char *partial_dir;
b7e8628c 74extern char *basis_dir[];
2be2fb3e 75extern int compare_dest;
967866d4 76extern int copy_dest;
59c95e42 77extern int link_dest;
5774786f 78extern int whole_file;
5774786f 79extern int list_only;
b9f592fb 80extern int read_batch;
5774786f
WD
81extern int orig_umask;
82extern int safe_symlinks;
a255c592 83extern long block_size; /* "long" because popt can't set an int32. */
59faec8b
WD
84extern int max_delete;
85extern int force_delete;
0e82af2d 86extern int one_file_system;
6c3862fa 87extern struct stats stats;
0e82af2d 88extern dev_t filesystem_dev;
59faec8b
WD
89extern char *backup_dir;
90extern char *backup_suffix;
91extern int backup_suffix_len;
ee1d11c4 92extern struct file_list *the_file_list;
7842418b 93extern struct filter_list_struct server_filter_list;
97f9dcae 94
59faec8b 95static int deletion_count = 0; /* used to implement --max-delete */
48224e4c
WD
96static int can_link_symlinks = 1; /* start out optimistic */
97static int can_link_devices = 1;
59faec8b 98
d71dad3b
WD
99/* For calling delete_file() */
100#define DEL_FORCE_RECURSE (1<<1) /* recurse even w/o --force */
101#define DEL_TERSE (1<<3)
102
59faec8b
WD
103
104static int is_backup_file(char *fn)
105{
106 int k = strlen(fn) - backup_suffix_len;
107 return k > 0 && strcmp(fn+k, backup_suffix) == 0;
108}
109
110
111/* Delete a file or directory. If DEL_FORCE_RECURSE is set in the flags, or if
d71dad3b 112 * force_delete is set, this will delete recursively.
0e5665d3
WD
113 *
114 * Note that fname must point to a MAXPATHLEN buffer if the mode indicates it's
115 * a directory! (The buffer is used for recursion, but returned unchanged.)
116 */
59faec8b
WD
117static int delete_item(char *fname, int mode, int flags)
118{
119 struct file_list *dirlist;
59faec8b 120 int j, dlen, zap_dir, ok;
0e5665d3 121 unsigned remainder;
59faec8b 122 void *save_filters;
0e5665d3 123 char *p;
59faec8b 124
59faec8b 125 if (!S_ISDIR(mode)) {
f75a53e7
WD
126 if (max_delete && ++deletion_count > max_delete)
127 return 0;
59faec8b
WD
128 if (make_backups && (backup_dir || !is_backup_file(fname)))
129 ok = make_backup(fname);
130 else
131 ok = robust_unlink(fname) == 0;
132 if (ok) {
133 if (!(flags & DEL_TERSE))
134 log_delete(fname, mode);
59faec8b
WD
135 return 0;
136 }
f75a53e7
WD
137 if (errno == ENOENT) {
138 deletion_count--;
59faec8b 139 return 0;
f75a53e7 140 }
59faec8b
WD
141 rsyserr(FERROR, errno, "delete_file: unlink %s failed",
142 full_fname(fname));
143 return -1;
144 }
145
d71dad3b 146 zap_dir = flags & DEL_FORCE_RECURSE || (force_delete && recurse);
f75a53e7
WD
147 if ((max_delete && ++deletion_count > max_delete)
148 || (dry_run && zap_dir)) {
59faec8b
WD
149 ok = 0;
150 errno = ENOTEMPTY;
151 } else if (make_backups && !backup_dir && !is_backup_file(fname)
152 && !(flags & DEL_FORCE_RECURSE))
153 ok = make_backup(fname);
154 else
155 ok = do_rmdir(fname) == 0;
156 if (ok) {
157 if (!(flags & DEL_TERSE))
158 log_delete(fname, mode);
59faec8b
WD
159 return 0;
160 }
f75a53e7
WD
161 if (errno == ENOENT) {
162 deletion_count--;
59faec8b 163 return 0;
f75a53e7 164 }
26beb786 165 if (!zap_dir) {
59faec8b
WD
166 rsyserr(FERROR, errno, "delete_file: rmdir %s failed",
167 full_fname(fname));
168 return -1;
169 }
f62eaa24 170 flags |= DEL_FORCE_RECURSE; /* mark subdir dels as not "in the way" */
f75a53e7 171 deletion_count--;
59faec8b 172
0e5665d3
WD
173 dlen = strlen(fname);
174 save_filters = push_local_filters(fname, dlen);
175
176 dirlist = get_dirlist(fname, dlen, 0);
177
178 p = fname + dlen;
179 if (dlen != 1 || *fname != '/')
180 *p++ = '/';
181 remainder = MAXPATHLEN - (p - fname);
59faec8b 182
59faec8b
WD
183 for (j = dirlist->count; j--; ) {
184 struct file_struct *fp = dirlist->files[j];
185
186 if (fp->flags & FLAG_MOUNT_POINT)
187 continue;
188
0e5665d3
WD
189 strlcpy(p, fp->basename, remainder);
190 delete_item(fname, fp->mode, flags & ~DEL_TERSE);
59faec8b
WD
191 }
192 flist_free(dirlist);
193
0e5665d3
WD
194 fname[dlen] = '\0';
195
59faec8b
WD
196 pop_local_filters(save_filters);
197
f75a53e7
WD
198 if (max_delete && ++deletion_count > max_delete)
199 return 0;
59faec8b
WD
200
201 if (do_rmdir(fname) == 0) {
202 if (!(flags & DEL_TERSE))
203 log_delete(fname, mode);
4d474ad5 204 } else if (errno != ENOTEMPTY && errno != EEXIST && errno != ENOENT) {
59faec8b
WD
205 rsyserr(FERROR, errno, "delete_file: rmdir %s failed",
206 full_fname(fname));
207 return -1;
208 }
209
210 return 0;
211}
212
213
214/* This function is used to implement per-directory deletion, and is used by
215 * all the --delete-WHEN options. Note that the fbuf pointer must point to a
216 * MAXPATHLEN buffer with the name of the directory in it (the functions we
217 * call will append names onto the end, but the old dir value will be restored
218 * on exit). */
219static void delete_in_dir(struct file_list *flist, char *fbuf,
0e82af2d 220 struct file_struct *file, STRUCT_STAT *stp)
59faec8b
WD
221{
222 static int min_depth = MAXPATHLEN, cur_depth = -1;
223 static void *filt_array[MAXPATHLEN/2+1];
717b0430 224 static int already_warned = 0;
59faec8b
WD
225 struct file_list *dirlist;
226 char delbuf[MAXPATHLEN];
468d7668 227 int dlen, i;
59faec8b
WD
228
229 if (!flist) {
230 while (cur_depth >= min_depth)
231 pop_local_filters(filt_array[cur_depth--]);
232 min_depth = MAXPATHLEN;
233 cur_depth = -1;
234 return;
235 }
236
237 if (verbose > 2)
45c49b52 238 rprintf(FINFO, "delete_in_dir(%s)\n", fbuf);
59faec8b
WD
239
240 if (allowed_lull)
ee1d11c4 241 maybe_send_keepalive();
59faec8b
WD
242
243 if (file->dir.depth >= MAXPATHLEN/2+1)
244 return; /* Impossible... */
245
59faec8b 246 if (io_error && !(lp_ignore_errors(module_id) || ignore_errors)) {
717b0430 247 if (already_warned)
f75a53e7 248 return;
59faec8b
WD
249 rprintf(FINFO,
250 "IO error encountered -- skipping file deletion\n");
717b0430 251 already_warned = 1;
59faec8b
WD
252 return;
253 }
254
255 while (cur_depth >= file->dir.depth && cur_depth >= min_depth)
256 pop_local_filters(filt_array[cur_depth--]);
257 cur_depth = file->dir.depth;
258 if (min_depth > cur_depth)
259 min_depth = cur_depth;
260 dlen = strlen(fbuf);
261 filt_array[cur_depth] = push_local_filters(fbuf, dlen);
262
0e82af2d
WD
263 if (one_file_system) {
264 if (file->flags & FLAG_TOP_DIR)
265 filesystem_dev = stp->st_dev;
266 else if (filesystem_dev != stp->st_dev)
267 return;
268 }
59faec8b 269
59faec8b
WD
270 dirlist = get_dirlist(fbuf, dlen, 0);
271
272 /* If an item in dirlist is not found in flist, delete it
273 * from the filesystem. */
274 for (i = dirlist->count; i--; ) {
f3ab64d3 275 struct file_struct *fp = dirlist->files[i];
0e82af2d 276 if (!fp->basename || fp->flags & FLAG_MOUNT_POINT)
bb0d8edf 277 continue;
468d7668 278 if (flist_find(flist, fp) < 0) {
f3ab64d3 279 int mode = fp->mode;
6cbde57d 280 f_name(fp, delbuf);
26beb786 281 delete_item(delbuf, mode, DEL_FORCE_RECURSE);
468d7668 282 }
59faec8b
WD
283 }
284
285 flist_free(dirlist);
286}
287
288/* This deletes any files on the receiving side that are not present on the
289 * sending side. This is used by --delete-before and --delete-after. */
ee1d11c4 290static void do_delete_pass(struct file_list *flist)
59faec8b
WD
291{
292 char fbuf[MAXPATHLEN];
bb0d8edf 293 STRUCT_STAT st;
59faec8b
WD
294 int j;
295
b225b089
WD
296 if (dry_run > 1 /* destination doesn't exist yet */
297 || list_only)
f75a53e7
WD
298 return;
299
59faec8b
WD
300 for (j = 0; j < flist->count; j++) {
301 struct file_struct *file = flist->files[j];
302
303 if (!(file->flags & FLAG_DEL_HERE))
304 continue;
305
6cbde57d 306 f_name(file, fbuf);
59faec8b 307 if (verbose > 1 && file->flags & FLAG_TOP_DIR)
45c49b52 308 rprintf(FINFO, "deleting in %s\n", fbuf);
59faec8b 309
bb0d8edf
WD
310 if (link_stat(fbuf, &st, keep_dirlinks) < 0
311 || !S_ISDIR(st.st_mode))
312 continue;
313
0e82af2d 314 delete_in_dir(flist, fbuf, file, &st);
59faec8b 315 }
0e82af2d 316 delete_in_dir(NULL, NULL, NULL, NULL);
0e5665d3 317
a06e2b7c
WD
318 if (do_progress && !am_server)
319 rprintf(FINFO, " \r");
59faec8b
WD
320}
321
48224e4c 322int unchanged_attrs(struct file_struct *file, STRUCT_STAT *st)
2f03f956 323{
b7e8628c
WD
324 if (preserve_perms
325 && (st->st_mode & CHMOD_BITS) != (file->mode & CHMOD_BITS))
84acca07 326 return 0;
bb24028f 327
5e58e3f9 328 if (am_root && preserve_uid && st->st_uid != file->ids->uid)
b7e8628c 329 return 0;
bb24028f 330
5e58e3f9 331 if (preserve_gid && file->ids->gid != GID_NONE && st->st_gid != file->ids->gid)
b7e8628c
WD
332 return 0;
333
334 return 1;
335}
336
ee1d11c4 337void itemize(struct file_struct *file, int ndx, int statret, STRUCT_STAT *st,
ef20efcb 338 int32 iflags, uchar fnamecmp_type, char *xname)
06a1dbad 339{
48224e4c
WD
340 if (statret >= 0) { /* A from-dest-dir statret can == 1! */
341 int keep_time = !preserve_times ? 0
342 : S_ISDIR(file->mode) ? !omit_dir_times
343 : !S_ISLNK(file->mode);
344
c557eb8c
WD
345 if (S_ISREG(file->mode) && file->length != st->st_size)
346 iflags |= ITEM_REPORT_SIZE;
48224e4c
WD
347 if ((iflags & (ITEM_TRANSFER|ITEM_LOCAL_CHANGE) && !keep_time
348 && (!(iflags & ITEM_XNAME_FOLLOWS) || *xname))
349 || (keep_time && cmp_modtime(file->modtime, st->st_mtime) != 0))
350 iflags |= ITEM_REPORT_TIME;
351 if (preserve_perms
352 && (file->mode & CHMOD_BITS) != (st->st_mode & CHMOD_BITS))
353 iflags |= ITEM_REPORT_PERMS;
5e58e3f9 354 if (preserve_uid && am_root && file->ids->uid != st->st_uid)
48224e4c 355 iflags |= ITEM_REPORT_OWNER;
5e58e3f9
WD
356 if (preserve_gid && file->ids->gid != GID_NONE
357 && st->st_gid != file->ids->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,
610 int maybe_PERMS_REPORT, enum logcode code)
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);
666 if (verbose > 1 && maybe_PERMS_REPORT) {
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);
48224e4c
WD
686 set_perms(fname, file, NULL, 0);
687 if (maybe_PERMS_REPORT
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,
3447d610 707 int maybe_PERMS_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 }
745 if (verbose > 1 && maybe_PERMS_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,
7433d73a 769 int itemizing, int maybe_PERMS_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;
f7632fc6 783
dfd5ba6a
WD
784 if (list_only)
785 return;
2f03f956 786
8e85be0a
WD
787 if (!fname) {
788 if (fuzzy_dirlist) {
789 flist_free(fuzzy_dirlist);
790 fuzzy_dirlist = NULL;
7e9059d6 791 fuzzy_dirname = "";
8e85be0a
WD
792 }
793 if (missing_below >= 0) {
794 dry_run--;
795 missing_below = -1;
796 }
797 return;
798 }
799
45c49b52
WD
800 if (verbose > 2)
801 rprintf(FINFO, "recv_generator(%s,%d)\n", fname, ndx);
2f03f956 802
8174bc35
WD
803 if (server_filter_list.head) {
804 if (excluded_below >= 0) {
805 if (file->dir.depth > excluded_below)
806 goto skipping;
807 excluded_below = -1;
808 }
809 if (check_filter(&server_filter_list, fname,
810 S_ISDIR(file->mode)) < 0) {
811 if (S_ISDIR(file->mode))
812 excluded_below = file->dir.depth;
b2e7c913 813 skipping:
8174bc35
WD
814 if (verbose) {
815 rprintf(FINFO,
816 "skipping server-excluded file \"%s\"\n",
45c49b52 817 fname);
8174bc35
WD
818 }
819 return;
3e35c34b 820 }
3e35c34b 821 }
97f9dcae 822
8e85be0a 823 if (missing_below >= 0 && file->dir.depth <= missing_below) {
df337831
WD
824 dry_run--;
825 missing_below = -1;
826 }
73f7af0e
WD
827 if (dry_run > 1) {
828 statret = -1;
829 stat_errno = ENOENT;
830 } else {
8e85be0a
WD
831 if (fuzzy_basis && S_ISREG(file->mode)) {
832 char *dn = file->dirname ? file->dirname : ".";
ccc51c83
WD
833 if (fuzzy_dirname != dn
834 && strcmp(fuzzy_dirname, dn) != 0) {
8e85be0a
WD
835 if (fuzzy_dirlist)
836 flist_free(fuzzy_dirlist);
ccc51c83 837 fuzzy_dirlist = get_dirlist(dn, -1, 1);
8e85be0a 838 }
ccc51c83 839 fuzzy_dirname = dn;
8e85be0a
WD
840 }
841
73f7af0e
WD
842 statret = link_stat(fname, &st,
843 keep_dirlinks && S_ISDIR(file->mode));
844 stat_errno = errno;
845 }
63787382 846
e90aab49 847 if (ignore_non_existing && statret == -1 && stat_errno == ENOENT) {
ecc81fce 848 if (verbose > 1) {
15164c0a
WD
849 rprintf(FINFO, "not creating new %s \"%s\"\n",
850 S_ISDIR(file->mode) ? "directory" : "file",
45c49b52 851 fname);
ecc81fce 852 }
1347d512
AT
853 return;
854 }
855
d9b4d267
WD
856 if (statret == 0 && !preserve_perms
857 && S_ISDIR(st.st_mode) == S_ISDIR(file->mode)) {
4df9f368 858 /* if the file exists already and we aren't perserving
2cda2560
WD
859 * permissions then act as though the remote end sent
860 * us the file permissions we already have */
67e78a82
WD
861 file->mode = (file->mode & ~CHMOD_BITS)
862 | (st.st_mode & CHMOD_BITS);
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)) {
1f1d368a
WD
872 if (delete_item(fname, st.st_mode, DEL_TERSE) < 0)
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 }
716e73d4 893 if (set_perms(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 }
c41b52c4 934 set_perms(fname, file, &st,
8a8356b7 935 maybe_PERMS_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. */
1f1d368a
WD
947 if (delete_item(fname, st.st_mode, DEL_TERSE) < 0)
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,
3447d610 954 maybe_PERMS_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
AT
967 } else {
968 set_perms(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
2f03f956 989 if (am_root && preserve_devices && IS_DEVICE(file->mode)) {
48224e4c
WD
990 if (statret != 0
991 && (basis_dir[0] != NULL && can_link_devices)) {
992 if (try_dests_non(file, fname, ndx, itemizing,
993 &can_link_devices,
3447d610 994 maybe_PERMS_REPORT, code) == -2) {
48224e4c
WD
995 if (!copy_dest)
996 return;
997 itemizing = code = 0;
998 }
999 }
15cf186b
WD
1000 if (statret != 0
1001 || (st.st_mode & ~CHMOD_BITS) != (file->mode & ~CHMOD_BITS)
1002 || st.st_rdev != file->u.rdev) {
0fdb1aa8
WD
1003 if (statret == 0
1004 && delete_item(fname, st.st_mode, DEL_TERSE) < 0)
1f1d368a 1005 return;
273a7ed5
WD
1006 if (preserve_hard_links && file->link_u.links
1007 && hard_link_check(file, ndx, fname, -1, &st,
1008 itemizing, code, HL_SKIP))
1009 return;
59faec8b 1010 if (!IS_DEVICE(st.st_mode))
88b218fa 1011 statret = -1;
d62bcc17 1012 if (verbose > 2) {
2f03f956 1013 rprintf(FINFO,"mknod(%s,0%o,0x%x)\n",
45c49b52 1014 fname,
ecc81fce 1015 (int)file->mode, (int)file->u.rdev);
d62bcc17 1016 }
00b96184 1017 if (do_mknod(fname,file->mode,file->u.rdev) < 0) {
d62bcc17
WD
1018 rsyserr(FERROR, errno, "mknod %s failed",
1019 full_fname(fname));
2f03f956
AT
1020 } else {
1021 set_perms(fname,file,NULL,0);
6c3862fa 1022 if (itemizing) {
ee1d11c4 1023 itemize(file, ndx, statret, &st,
ef20efcb 1024 ITEM_LOCAL_CHANGE, 0, NULL);
6c3862fa 1025 }
45c49b52
WD
1026 if (code && verbose)
1027 rprintf(code, "%s\n", fname);
273a7ed5
WD
1028 if (preserve_hard_links && file->link_u.links) {
1029 hard_link_cluster(file, ndx,
1030 itemizing, code);
1031 }
2f03f956
AT
1032 }
1033 } else {
ee1d11c4 1034 if (itemizing)
ef20efcb 1035 itemize(file, ndx, statret, &st, 0, 0, NULL);
8a8356b7 1036 set_perms(fname, file, &st, maybe_PERMS_REPORT);
273a7ed5
WD
1037 if (preserve_hard_links && file->link_u.links)
1038 hard_link_cluster(file, ndx, itemizing, code);
2f03f956
AT
1039 }
1040 return;
1041 }
2f03f956 1042
2f03f956 1043 if (!S_ISREG(file->mode)) {
2a5d5a8c 1044 if (the_file_list->count == 1)
6cbde57d 1045 fname = f_name(file, NULL);
45c49b52 1046 rprintf(FINFO, "skipping non-regular file \"%s\"\n", fname);
2f03f956
AT
1047 return;
1048 }
1049
289a3216
WD
1050 if (max_size && file->length > max_size) {
1051 if (verbose > 1) {
1052 if (the_file_list->count == 1)
6cbde57d 1053 fname = f_name(file, NULL);
45c49b52 1054 rprintf(FINFO, "%s is over max-size\n", fname);
289a3216
WD
1055 }
1056 return;
1057 }
02b5cb23
WD
1058 if (min_size && file->length < min_size) {
1059 if (verbose > 1) {
1060 if (the_file_list->count == 1)
6cbde57d 1061 fname = f_name(file, NULL);
45c49b52 1062 rprintf(FINFO, "%s is under min-size\n", fname);
02b5cb23
WD
1063 }
1064 return;
1065 }
289a3216 1066
e90aab49 1067 if (ignore_existing && statret == 0) {
c3cbcfb8 1068 if (verbose > 1)
45c49b52 1069 rprintf(FINFO, "%s exists\n", fname);
c3cbcfb8
WD
1070 return;
1071 }
1072
1073 if (update_only && statret == 0
1074 && cmp_modtime(st.st_mtime, file->modtime) > 0) {
1075 if (verbose > 1)
45c49b52 1076 rprintf(FINFO, "%s is newer\n", fname);
c3cbcfb8
WD
1077 return;
1078 }
1079
375a4556 1080 fnamecmp = fname;
41cfde6b 1081 fnamecmp_type = FNAMECMP_FNAME;
375a4556 1082
1f1d368a
WD
1083 if (statret == 0 && !S_ISREG(st.st_mode)) {
1084 if (delete_item(fname, st.st_mode, DEL_TERSE) != 0)
1085 return;
1086 statret = -1;
1087 stat_errno = ENOENT;
1088 }
1089
06a1dbad 1090 if (statret != 0 && basis_dir[0] != NULL) {
48224e4c
WD
1091 int j = try_dests_reg(file, fname, ndx, fnamecmpbuf, &st,
1092 itemizing, maybe_PERMS_REPORT, code);
1093 if (j == -2)
1094 return;
1095 if (j != -1) {
1096 fnamecmp = fnamecmpbuf;
1097 fnamecmp_type = j;
9ba46343 1098 statret = 0;
e7d13fe5
WD
1099 }
1100 }
1101
1f1d368a
WD
1102 real_ret = statret;
1103 real_st = st;
375a4556 1104
9d954dca 1105 if (partial_dir && (partialptr = partial_dir_fname(fname)) != NULL
72c19bb3
WD
1106 && link_stat(partialptr, &partial_st, 0) == 0
1107 && S_ISREG(partial_st.st_mode)) {
06a1dbad 1108 if (statret != 0)
72c19bb3
WD
1109 goto prepare_to_open;
1110 } else
1111 partialptr = NULL;
89f7eff3 1112
06a1dbad 1113 if (statret != 0 && fuzzy_basis && dry_run <= 1) {
8e85be0a
WD
1114 int j = find_fuzzy(file, fuzzy_dirlist);
1115 if (j >= 0) {
1116 fuzzy_file = fuzzy_dirlist->files[j];
6cbde57d 1117 f_name(fuzzy_file, fnamecmpbuf);
8e85be0a
WD
1118 if (verbose > 2) {
1119 rprintf(FINFO, "fuzzy basis selected for %s: %s\n",
45c49b52 1120 fname, fnamecmpbuf);
8e85be0a 1121 }
8e85be0a 1122 st.st_size = fuzzy_file->length;
8e85be0a
WD
1123 statret = 0;
1124 fnamecmp = fnamecmpbuf;
1125 fnamecmp_type = FNAMECMP_FUZZY;
1126 }
1127 }
1128
06a1dbad 1129 if (statret != 0) {
273a7ed5 1130 if (preserve_hard_links && file->link_u.links
d8169e6f
WD
1131 && hard_link_check(file, ndx, fname, statret, &st,
1132 itemizing, code, HL_SKIP))
6dff5992 1133 return;
41cfde6b
WD
1134 if (stat_errno == ENOENT)
1135 goto notify_others;
991daf00
WD
1136 rsyserr(FERROR, stat_errno, "recv_generator: failed to stat %s",
1137 full_fname(fname));
2f03f956
AT
1138 return;
1139 }
1140
6cc11982
WD
1141 if (append_mode && st.st_size > file->length)
1142 return;
1143
48224e4c 1144 if (fnamecmp_type <= FNAMECMP_BASIS_DIR_HIGH)
b7e8628c 1145 ;
8e85be0a
WD
1146 else if (fnamecmp_type == FNAMECMP_FUZZY)
1147 ;
b7e8628c 1148 else if (unchanged_file(fnamecmp, file, &st)) {
d8b108c2
WD
1149 if (partialptr) {
1150 do_unlink(partialptr);
1151 handle_partial_dir(partialptr, PDIR_DELETE);
1152 }
48224e4c
WD
1153 if (itemizing) {
1154 itemize(file, ndx, real_ret, &real_st,
1155 0, 0, NULL);
a1d23b53 1156 }
48224e4c
WD
1157 set_perms(fname, file, &st, maybe_PERMS_REPORT);
1158 if (preserve_hard_links && file->link_u.links)
1159 hard_link_cluster(file, ndx, itemizing, code);
967866d4 1160 return;
2f03f956
AT
1161 }
1162
b2e7c913 1163 prepare_to_open:
9d954dca
WD
1164 if (partialptr) {
1165 st = partial_st;
1166 fnamecmp = partialptr;
1167 fnamecmp_type = FNAMECMP_PARTIAL_DIR;
1168 statret = 0;
1169 }
1170
beb51aa0 1171 if (!do_xfers || read_batch || whole_file)
3841a04e 1172 goto notify_others;
2f03f956 1173
8e85be0a
WD
1174 if (fuzzy_basis) {
1175 int j = flist_find(fuzzy_dirlist, file);
1176 if (j >= 0) /* don't use changing file as future fuzzy basis */
1177 fuzzy_dirlist->files[j]->flags |= FLAG_NO_FUZZY;
1178 }
1179
2cda2560 1180 /* open the file */
8c9fd200 1181 fd = do_open(fnamecmp, O_RDONLY, 0);
2f03f956
AT
1182
1183 if (fd == -1) {
d62bcc17
WD
1184 rsyserr(FERROR, errno, "failed to open %s, continuing",
1185 full_fname(fnamecmp));
b2e7c913 1186 pretend_missing:
60be6acf 1187 /* pretend the file didn't exist */
273a7ed5 1188 if (preserve_hard_links && file->link_u.links
d8169e6f
WD
1189 && hard_link_check(file, ndx, fname, statret, &st,
1190 itemizing, code, HL_SKIP))
6dff5992 1191 return;
1f1d368a 1192 statret = real_ret = -1;
41cfde6b 1193 goto notify_others;
2f03f956
AT
1194 }
1195
ef20efcb 1196 if (inplace && make_backups && fnamecmp_type == FNAMECMP_FNAME) {
cd6aa5b5
WD
1197 if (!(backupptr = get_backup_name(fname))) {
1198 close(fd);
1199 return;
1200 }
3de73827 1201 if (!(back_file = make_file(fname, NULL, NULL, 0, NO_FILTERS))) {
cd6aa5b5
WD
1202 close(fd);
1203 goto pretend_missing;
1204 }
1205 if (robust_unlink(backupptr) && errno != ENOENT) {
1206 rsyserr(FERROR, errno, "unlink %s",
1207 full_fname(backupptr));
1208 free(back_file);
1209 close(fd);
1210 return;
1211 }
1212 if ((f_copy = do_open(backupptr,
1213 O_WRONLY | O_CREAT | O_TRUNC | O_EXCL, 0600)) < 0) {
1214 rsyserr(FERROR, errno, "open %s",
1215 full_fname(backupptr));
1216 free(back_file);
1217 close(fd);
1218 return;
1219 }
41cfde6b 1220 fnamecmp_type = FNAMECMP_BACKUP;
cd6aa5b5
WD
1221 }
1222
dfd5ba6a 1223 if (verbose > 3) {
ecc81fce 1224 rprintf(FINFO, "gen mapped %s of size %.0f\n",
45c49b52 1225 fnamecmp, (double)st.st_size);
dfd5ba6a 1226 }
2f03f956 1227
2f03f956 1228 if (verbose > 2)
0492fdfb 1229 rprintf(FINFO, "generating and sending sums for %d\n", ndx);
2f03f956 1230
b2e7c913 1231 notify_others:
0492fdfb 1232 write_int(f_out, ndx);
6c3862fa 1233 if (itemizing) {
ee1d11c4 1234 int iflags = ITEM_TRANSFER;
8237f930 1235 if (always_checksum)
a1d23b53 1236 iflags |= ITEM_REPORT_CHECKSUM;
352963dd 1237 if (fnamecmp_type != FNAMECMP_FNAME)
ef20efcb
WD
1238 iflags |= ITEM_BASIS_TYPE_FOLLOWS;
1239 if (fnamecmp_type == FNAMECMP_FUZZY)
1240 iflags |= ITEM_XNAME_FOLLOWS;
1f1d368a 1241 itemize(file, -1, real_ret, &real_st, iflags, fnamecmp_type,
ef20efcb 1242 fuzzy_file ? fuzzy_file->basename : NULL);
8e85be0a 1243 }
cd6aa5b5 1244
beb51aa0 1245 if (!do_xfers) {
ee1d11c4
WD
1246 if (preserve_hard_links && file->link_u.links)
1247 hard_link_cluster(file, ndx, itemizing, code);
1248 return;
1249 }
1250 if (read_batch)
41cfde6b
WD
1251 return;
1252
33ab4ad8 1253 if (statret != 0 || whole_file) {
e86ae6bc
WD
1254 write_sum_head(f_out, NULL);
1255 return;
1256 }
1257
1258 generate_and_send_sums(fd, st.st_size, f_out, f_copy);
1259
1260 if (f_copy >= 0) {
1261 close(f_copy);
1262 set_perms(backupptr, back_file, NULL, 0);
1263 if (verbose > 1) {
1264 rprintf(FINFO, "backed up %s to %s\n",
45c49b52 1265 fname, backupptr);
41cfde6b 1266 }
e86ae6bc
WD
1267 free(back_file);
1268 }
41cfde6b 1269
e86ae6bc 1270 close(fd);
2f03f956
AT
1271}
1272
ef20efcb 1273void generate_files(int f_out, struct file_list *flist, char *local_name)
2f03f956 1274{
ac40b747 1275 int i;
968c8030 1276 char fbuf[MAXPATHLEN];
7433d73a
WD
1277 int itemizing, maybe_PERMS_REPORT;
1278 enum logcode code;
ac40b747 1279 int lull_mod = allowed_lull * 5;
3ea9bbd6
WD
1280 int need_retouch_dir_times = preserve_times && !omit_dir_times;
1281 int need_retouch_dir_perms = 0;
e90aab49
WD
1282 int save_ignore_existing = ignore_existing;
1283 int save_ignore_non_existing = ignore_non_existing;
083acd49 1284 int save_do_progress = do_progress;
cd908ef4 1285 int save_make_backups = make_backups;
ee1d11c4 1286
7433d73a
WD
1287 if (protocol_version >= 29) {
1288 itemizing = 1;
1289 maybe_PERMS_REPORT = log_format_has_i ? 0 : PERMS_REPORT;
1290 code = daemon_log_format_has_i ? 0 : FLOG;
1291 } else if (am_daemon) {
beb51aa0 1292 itemizing = daemon_log_format_has_i && do_xfers;
7433d73a 1293 maybe_PERMS_REPORT = PERMS_REPORT;
beb51aa0 1294 code = itemizing || !do_xfers ? FCLIENT : FINFO;
7433d73a
WD
1295 } else if (!am_server) {
1296 itemizing = log_format_has_i;
1297 maybe_PERMS_REPORT = log_format_has_i ? 0 : PERMS_REPORT;
1298 code = itemizing ? 0 : FINFO;
1299 } else {
1300 itemizing = 0;
1301 maybe_PERMS_REPORT = PERMS_REPORT;
1302 code = FINFO;
1303 }
2f03f956 1304
45e08edb
WD
1305 if (verbose > 2) {
1306 rprintf(FINFO, "generator starting pid=%ld count=%d\n",
1307 (long)getpid(), flist->count);
1308 }
2f03f956 1309
59faec8b 1310 if (delete_before && !local_name && flist->count > 0)
ee1d11c4 1311 do_delete_pass(flist);
083acd49 1312 do_progress = 0;
59faec8b 1313
6cc11982 1314 if (append_mode || whole_file < 0)
33ab4ad8 1315 whole_file = 0;
3e7053ac 1316 if (verbose >= 2) {
1b1fef20 1317 rprintf(FINFO, "delta-transmission %s\n",
33ab4ad8 1318 whole_file
1b1fef20
WD
1319 ? "disabled for local transfer or --whole-file"
1320 : "enabled");
3e7053ac 1321 }
2cda2560 1322
513fd04d
WD
1323 /* Since we often fill up the outgoing socket and then just sit around
1324 * waiting for the other 2 processes to do their thing, we don't want
1325 * to exit on a timeout. If the data stops flowing, the receiver will
1326 * notice that and let us know via the redo pipe (or its closing). */
1327 ignore_timeout = 1;
a57873b7 1328
2f03f956
AT
1329 for (i = 0; i < flist->count; i++) {
1330 struct file_struct *file = flist->files[i];
2f03f956 1331
dfd5ba6a
WD
1332 if (!file->basename)
1333 continue;
0492fdfb 1334
0e5665d3
WD
1335 if (local_name)
1336 strlcpy(fbuf, local_name, sizeof fbuf);
1337 else
6cbde57d 1338 f_name(file, fbuf);
0e5665d3
WD
1339 recv_generator(fbuf, file, i, itemizing, maybe_PERMS_REPORT,
1340 code, f_out);
1f7e29b9 1341
0492fdfb
WD
1342 /* We need to ensure that any dirs we create have writeable
1343 * permissions during the time we are putting files within
1344 * them. This is then fixed after the transfer is done. */
00b96184 1345#ifdef HAVE_CHMOD
41b84ce0
WD
1346 if (!am_root && S_ISDIR(file->mode) && !(file->mode & S_IWUSR)
1347 && !list_only) {
1f7e29b9
WD
1348 int mode = file->mode | S_IWUSR; /* user write */
1349 char *fname = local_name ? local_name : fbuf;
00b96184 1350 if (do_chmod(fname, mode) < 0) {
1f7e29b9
WD
1351 rsyserr(FERROR, errno,
1352 "failed to modify permissions on %s",
1353 full_fname(fname));
1354 }
3ea9bbd6 1355 need_retouch_dir_perms = 1;
2f03f956 1356 }
00b96184 1357#endif
2f03f956 1358
ee1d11c4
WD
1359 if (preserve_hard_links)
1360 check_for_finished_hlinks(itemizing, code);
9ac2395b 1361
18a11cfd 1362 if (allowed_lull && !(i % lull_mod))
ee1d11c4 1363 maybe_send_keepalive();
c2523a05 1364 else if (!(i % 200))
417099fa 1365 maybe_flush_socket();
2f03f956 1366 }
ef20efcb 1367 recv_generator(NULL, NULL, 0, 0, 0, code, -1);
c93fad5e 1368 if (delete_during)
0e82af2d 1369 delete_in_dir(NULL, NULL, NULL, NULL);
2f03f956
AT
1370
1371 phase++;
1372 csum_length = SUM_LENGTH;
02b5cb23 1373 max_size = min_size = ignore_existing = ignore_non_existing = 0;
0492fdfb 1374 update_only = always_checksum = size_only = 0;
e1f67417 1375 ignore_times = 1;
6cc11982
WD
1376 if (append_mode) /* resend w/o append mode */
1377 append_mode = -1; /* ... but only longer files */
e6bc6f42 1378 make_backups = 0; /* avoid a duplicate backup for inplace processing */
2f03f956
AT
1379
1380 if (verbose > 2)
1381 rprintf(FINFO,"generate_files phase=%d\n",phase);
1382
7daccb8e 1383 write_int(f_out, -1);
2f03f956 1384
bc63ae3f
S
1385 /* files can cycle through the system more than once
1386 * to catch initial checksum errors */
ee1d11c4 1387 while ((i = get_redo_num(itemizing, code)) != -1) {
bc63ae3f 1388 struct file_struct *file = flist->files[i];
0e5665d3
WD
1389 if (local_name)
1390 strlcpy(fbuf, local_name, sizeof fbuf);
1391 else
6cbde57d 1392 f_name(file, fbuf);
0e5665d3
WD
1393 recv_generator(fbuf, file, i, itemizing, maybe_PERMS_REPORT,
1394 code, f_out);
bc63ae3f 1395 }
2f03f956 1396
bc63ae3f 1397 phase++;
e90aab49
WD
1398 ignore_non_existing = save_ignore_non_existing;
1399 ignore_existing = save_ignore_existing;
cd908ef4 1400 make_backups = save_make_backups;
0492fdfb 1401
bc63ae3f
S
1402 if (verbose > 2)
1403 rprintf(FINFO,"generate_files phase=%d\n",phase);
2f03f956 1404
7daccb8e 1405 write_int(f_out, -1);
70352269
WD
1406 /* Reduce round-trip lag-time for a useless delay-updates phase. */
1407 if (protocol_version >= 29 && !delay_updates)
1408 write_int(f_out, -1);
6dff5992 1409
0438f100 1410 /* Read MSG_DONE for the redo phase (and any prior messages). */
ee1d11c4 1411 get_redo_num(itemizing, code);
6dff5992 1412
0438f100
WD
1413 if (protocol_version >= 29) {
1414 phase++;
1415 if (verbose > 2)
1416 rprintf(FINFO, "generate_files phase=%d\n", phase);
70352269
WD
1417 if (delay_updates)
1418 write_int(f_out, -1);
1419 /* Read MSG_DONE for delay-updates phase & prior messages. */
0438f100
WD
1420 get_redo_num(itemizing, code);
1421 }
1422
083acd49 1423 do_progress = save_do_progress;
59faec8b 1424 if (delete_after && !local_name && flist->count > 0)
ee1d11c4 1425 do_delete_pass(flist);
59faec8b 1426
0492fdfb
WD
1427 if ((need_retouch_dir_perms || need_retouch_dir_times)
1428 && !list_only && !local_name && !dry_run) {
18a11cfd 1429 int j = 0;
3ea9bbd6
WD
1430 /* Now we need to fix any directory permissions that were
1431 * modified during the transfer and/or re-set any tweaked
1432 * modified-time values. */
1433 for (i = 0; i < flist->count; i++) {
1434 struct file_struct *file = flist->files[i];
b435d717 1435
3ea9bbd6
WD
1436 if (!file->basename || !S_ISDIR(file->mode))
1437 continue;
1438 if (!need_retouch_dir_times && file->mode & S_IWUSR)
1439 continue;
6cbde57d 1440 recv_generator(f_name(file, NULL), file, i, itemizing,
62f9573f 1441 maybe_PERMS_REPORT, code, -1);
417099fa 1442 if (allowed_lull && !(++j % lull_mod))
ee1d11c4 1443 maybe_send_keepalive();
c2523a05 1444 else if (!(j % 200))
417099fa 1445 maybe_flush_socket();
3ea9bbd6 1446 }
6dff5992 1447 }
ef20efcb 1448 recv_generator(NULL, NULL, 0, 0, 0, code, -1);
6dff5992 1449
f75a53e7
WD
1450 if (max_delete > 0 && deletion_count > max_delete) {
1451 rprintf(FINFO,
1452 "Deletions stopped due to --max-delete limit (%d skipped)\n",
1453 deletion_count - max_delete);
1454 io_error |= IOERR_DEL_LIMIT;
1455 }
1456
6dff5992
WD
1457 if (verbose > 2)
1458 rprintf(FINFO,"generate_files finished\n");
2f03f956 1459}