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