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