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