- Integrated the latest version from samba.
[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;
6c3862fa
WD
28extern int log_format_has_i;
29extern int log_format_has_o_or_i;
30extern int daemon_log_format_has_i;
31extern int am_root;
32extern int am_server;
33extern int am_daemon;
2f03f956 34extern int relative_paths;
716e73d4 35extern int keep_dirlinks;
2f03f956 36extern int preserve_links;
2f03f956
AT
37extern int preserve_devices;
38extern int preserve_hard_links;
6744b62d
WD
39extern int preserve_perms;
40extern int preserve_uid;
41extern int preserve_gid;
3ea9bbd6
WD
42extern int preserve_times;
43extern int omit_dir_times;
fa13f396 44extern int delete_during;
fe960187 45extern int remove_sent_files;
2f03f956 46extern int update_only;
3d6feada 47extern int opt_ignore_existing;
cd6aa5b5
WD
48extern int inplace;
49extern int make_backups;
2f03f956
AT
50extern int csum_length;
51extern int ignore_times;
f83f0548 52extern int size_only;
7d1bfaf7 53extern OFF_T max_size;
2f03f956 54extern int io_timeout;
d04e9c51 55extern int protocol_version;
8e85be0a 56extern int fuzzy_basis;
2f03f956 57extern int always_checksum;
a7260c40 58extern char *partial_dir;
b7e8628c 59extern char *basis_dir[];
2be2fb3e 60extern int compare_dest;
59c95e42 61extern int link_dest;
5774786f
WD
62extern int whole_file;
63extern int local_server;
5774786f 64extern int list_only;
b9f592fb 65extern int read_batch;
5774786f
WD
66extern int only_existing;
67extern int orig_umask;
68extern int safe_symlinks;
a255c592 69extern long block_size; /* "long" because popt can't set an int32. */
6c3862fa 70extern struct stats stats;
2f03f956 71
7842418b 72extern struct filter_list_struct server_filter_list;
97f9dcae 73
b7e8628c 74static int unchanged_attrs(struct file_struct *file, STRUCT_STAT *st)
2f03f956 75{
b7e8628c
WD
76 if (preserve_perms
77 && (st->st_mode & CHMOD_BITS) != (file->mode & CHMOD_BITS))
84acca07 78 return 0;
bb24028f 79
b7e8628c
WD
80 if (am_root && preserve_uid && st->st_uid != file->uid)
81 return 0;
bb24028f 82
b7e8628c
WD
83 if (preserve_gid && file->gid != GID_NONE && st->st_gid != file->gid)
84 return 0;
85
86 return 1;
87}
88
06a1dbad 89
c557eb8c
WD
90#define SID_UPDATING ITEM_UPDATING
91#define SID_REPORT_CHECKSUM ITEM_REPORT_CHECKSUM
92#define SID_NO_DEST_AND_NO_UPDATE (1<<16)
06a1dbad 93
c557eb8c
WD
94static void itemize(struct file_struct *file, int statret, STRUCT_STAT *st,
95 int32 sflags, int f_out, int ndx)
06a1dbad 96{
c557eb8c 97 int iflags = sflags & (SID_UPDATING | SID_REPORT_CHECKSUM);
06a1dbad 98
c557eb8c
WD
99 if (statret >= 0) {
100 if (S_ISREG(file->mode) && file->length != st->st_size)
101 iflags |= ITEM_REPORT_SIZE;
88b218fa
WD
102 if (!(sflags & SID_NO_DEST_AND_NO_UPDATE)) {
103 int keep_time = !preserve_times ? 0
104 : S_ISDIR(file->mode) ? !omit_dir_times
105 : !S_ISLNK(file->mode);
106
107 if ((iflags & ITEM_UPDATING && !keep_time)
108 || (keep_time && file->modtime != st->st_mtime))
109 iflags |= ITEM_REPORT_TIME;
110 if (preserve_perms && file->mode != st->st_mode)
111 iflags |= ITEM_REPORT_PERMS;
112 if (preserve_uid && am_root && file->uid != st->st_uid)
113 iflags |= ITEM_REPORT_OWNER;
114 if (preserve_gid && file->gid != GID_NONE
115 && st->st_gid != file->gid)
116 iflags |= ITEM_REPORT_GROUP;
117 }
c557eb8c 118 } else
88b218fa 119 iflags |= ITEM_IS_NEW | ITEM_UPDATING;
c557eb8c 120
8a8356b7 121 if ((iflags || verbose > 1) && !read_batch) {
6c3862fa
WD
122 if (protocol_version >= 29) {
123 if (ndx >= 0)
124 write_int(f_out, ndx);
125 write_shortint(f_out, iflags);
126 } else if (ndx >= 0)
127 log_recv(file, &stats, iflags);
06a1dbad
WD
128 }
129}
130
131
b7e8628c
WD
132/* Perform our quick-check heuristic for determining if a file is unchanged. */
133static int unchanged_file(char *fn, struct file_struct *file, STRUCT_STAT *st)
134{
135 if (st->st_size != file->length)
136 return 0;
59c95e42 137
2cda2560 138 /* if always checksum is set then we use the checksum instead
2f03f956
AT
139 of the file time to determine whether to sync */
140 if (always_checksum && S_ISREG(st->st_mode)) {
141 char sum[MD4_SUM_LENGTH];
b7e8628c 142 file_checksum(fn, sum, st->st_size);
728d0922 143 return memcmp(sum, file->u.sum, protocol_version < 21 ? 2
84acca07 144 : MD4_SUM_LENGTH) == 0;
2f03f956
AT
145 }
146
cc1e997d 147 if (size_only)
84acca07 148 return 1;
2f03f956 149
cc1e997d 150 if (ignore_times)
84acca07 151 return 0;
cc1e997d 152
84acca07 153 return cmp_modtime(st->st_mtime, file->modtime) == 0;
2f03f956
AT
154}
155
156
ec8290c8 157/*
195bd906 158 * set (initialize) the size entries in the per-file sum_struct
ec8290c8 159 * calculating dynamic block and checksum sizes.
195bd906 160 *
ec8290c8 161 * This is only called from generate_and_send_sums() but is a separate
195bd906
S
162 * function to encapsulate the logic.
163 *
164 * The block size is a rounded square root of file length.
165 *
166 * The checksum size is determined according to:
167 * blocksum_bits = BLOCKSUM_EXP + 2*log2(file_len) - log2(block_len)
168 * provided by Donovan Baarda which gives a probability of rsync
169 * algorithm corrupting data and falling back using the whole md4
170 * checksums.
171 *
172 * This might be made one of several selectable heuristics.
173 */
1490812a 174static void sum_sizes_sqroot(struct sum_struct *sum, int64 len)
195bd906 175{
a255c592 176 int32 blength;
da9d12f5 177 int s2length;
195bd906 178
a255c592 179 if (block_size)
195bd906 180 blength = block_size;
a255c592 181 else if (len <= BLOCK_SIZE * BLOCK_SIZE)
195bd906 182 blength = BLOCK_SIZE;
a255c592
WD
183 else {
184 int32 c;
1490812a 185 int64 l;
eae7165c
WD
186 int cnt;
187 for (c = 1, l = len, cnt = 0; l >>= 2; c <<= 1, cnt++) {}
188 if (cnt >= 31 || c >= MAX_BLOCK_SIZE)
189 blength = MAX_BLOCK_SIZE;
190 else {
191 blength = 0;
192 do {
193 blength |= c;
1490812a 194 if (len < (int64)blength * blength)
eae7165c
WD
195 blength &= ~c;
196 c >>= 1;
197 } while (c >= 8); /* round to multiple of 8 */
198 blength = MAX(blength, BLOCK_SIZE);
195bd906 199 }
195bd906
S
200 }
201
d04e9c51 202 if (protocol_version < 27) {
195bd906
S
203 s2length = csum_length;
204 } else if (csum_length == SUM_LENGTH) {
205 s2length = SUM_LENGTH;
206 } else {
a255c592 207 int32 c;
1490812a 208 int64 l;
da9d12f5 209 int b = BLOCKSUM_BIAS;
a255c592
WD
210 for (l = len; l >>= 1; b += 2) {}
211 for (c = blength; c >>= 1 && b; b--) {}
212 /* add a bit, subtract rollsum, round up. */
213 s2length = (b + 1 - 32 + 7) / 8; /* --optimize in compiler-- */
195bd906
S
214 s2length = MAX(s2length, csum_length);
215 s2length = MIN(s2length, SUM_LENGTH);
216 }
217
218 sum->flength = len;
219 sum->blength = blength;
220 sum->s2length = s2length;
221 sum->count = (len + (blength - 1)) / blength;
222 sum->remainder = (len % blength);
223
224 if (sum->count && verbose > 2) {
a255c592
WD
225 rprintf(FINFO,
226 "count=%.0f rem=%ld blength=%ld s2length=%d flength=%.0f\n",
227 (double)sum->count, (long)sum->remainder, (long)sum->blength,
da9d12f5 228 sum->s2length, (double)sum->flength);
195bd906
S
229 }
230}
80605142 231
bceec82f 232
80605142
WD
233/*
234 * Generate and send a stream of signatures/checksums that describe a buffer
e66dfd18 235 *
80605142
WD
236 * Generate approximately one checksum every block_len bytes.
237 */
cd6aa5b5 238static void generate_and_send_sums(int fd, OFF_T len, int f_out, int f_copy)
2f03f956 239{
a1cbe76e 240 int32 i;
6e45e1dd 241 struct map_struct *mapbuf;
80605142 242 struct sum_struct sum;
2f03f956
AT
243 OFF_T offset = 0;
244
423dba8e 245 sum_sizes_sqroot(&sum, len);
e66dfd18 246
6e45e1dd 247 if (len > 0)
96d910c7 248 mapbuf = map_file(fd, len, MAX_MAP_SIZE, sum.blength);
6e45e1dd
WD
249 else
250 mapbuf = NULL;
251
fc0257c9 252 write_sum_head(f_out, &sum);
2f03f956 253
80605142 254 for (i = 0; i < sum.count; i++) {
a255c592 255 int32 n1 = (int32)MIN(len, (OFF_T)sum.blength);
6e45e1dd 256 char *map = map_ptr(mapbuf, offset, n1);
80605142
WD
257 uint32 sum1 = get_checksum1(map, n1);
258 char sum2[SUM_LENGTH];
2f03f956 259
cd6aa5b5
WD
260 if (f_copy >= 0)
261 full_write(f_copy, map, n1);
262
80605142 263 get_checksum2(map, n1, sum2);
2f03f956 264
80605142 265 if (verbose > 3) {
e66dfd18 266 rprintf(FINFO,
a255c592
WD
267 "chunk[%.0f] offset=%.0f len=%ld sum1=%08lx\n",
268 (double)i, (double)offset, (long)n1,
0e36d9da 269 (unsigned long)sum1);
80605142
WD
270 }
271 write_int(f_out, sum1);
fc0257c9 272 write_buf(f_out, sum2, sum.s2length);
2f03f956
AT
273 len -= n1;
274 offset += n1;
275 }
6e45e1dd
WD
276
277 if (mapbuf)
278 unmap_file(mapbuf);
2f03f956
AT
279}
280
06a1dbad 281
8e85be0a
WD
282/* Try to find a filename in the same dir as "fname" with a similar name. */
283static int find_fuzzy(struct file_struct *file, struct file_list *dirlist)
284{
285 int fname_len, fname_suf_len;
286 const char *fname_suf, *fname = file->basename;
287 uint32 lowest_dist = 0x7FFFFFFF;
288 int j, lowest_j = -1;
289
290 fname_len = strlen(fname);
291 fname_suf = find_filename_suffix(fname, fname_len, &fname_suf_len);
292
293 for (j = 0; j < dirlist->count; j++) {
294 struct file_struct *fp = dirlist->files[j];
295 const char *suf, *name;
296 int len, suf_len;
297 uint32 dist;
298
299 if (!S_ISREG(fp->mode) || !fp->length
300 || fp->flags & FLAG_NO_FUZZY)
301 continue;
302
303 name = fp->basename;
304
305 if (fp->length == file->length
306 && fp->modtime == file->modtime) {
307 if (verbose > 4) {
308 rprintf(FINFO,
309 "fuzzy size/modtime match for %s\n",
310 name);
311 }
312 return j;
313 }
314
315 len = strlen(name);
316 suf = find_filename_suffix(name, len, &suf_len);
317
318 dist = fuzzy_distance(name, len, fname, fname_len);
319 /* Add some extra weight to how well the suffixes match. */
320 dist += fuzzy_distance(suf, suf_len, fname_suf, fname_suf_len)
321 * 10;
322 if (verbose > 4) {
323 rprintf(FINFO, "fuzzy distance for %s = %d.%05d\n",
324 name, (int)(dist>>16), (int)(dist&0xFFFF));
325 }
326 if (dist <= lowest_dist) {
327 lowest_dist = dist;
328 lowest_j = j;
329 }
330 }
331
332 return lowest_j;
333}
334
2f03f956 335
0492fdfb
WD
336/* Acts on flist->file's ndx'th item, whose name is fname. If a directory,
337 * make sure it exists, and has the right permissions/timestamp info. For
338 * all other non-regular files (symlinks, etc.) we create them here. For
339 * regular files that have changed, we try to find a basis file and then
340 * start sending checksums.
ef1aa910 341 *
0492fdfb
WD
342 * Note that f_out is set to -1 when doing final directory-permission and
343 * modification-time repair. */
fa13f396 344static void recv_generator(char *fname, struct file_list *flist,
0492fdfb 345 struct file_struct *file, int ndx,
41cfde6b 346 int f_out, int f_out_name)
2cda2560 347{
8174bc35 348 static int missing_below = -1, excluded_below = -1;
8e85be0a
WD
349 static char *fuzzy_dirname = NULL;
350 static struct file_list *fuzzy_dirlist = NULL;
351 struct file_struct *fuzzy_file = NULL;
41cfde6b 352 int fd = -1, f_copy = -1;
89f7eff3 353 STRUCT_STAT st, partial_st;
41cfde6b 354 struct file_struct *back_file = NULL;
e7d13fe5 355 int statret, stat_errno;
41cfde6b 356 char *fnamecmp, *partialptr, *backupptr = NULL;
375a4556 357 char fnamecmpbuf[MAXPATHLEN];
8e3ead09 358 int itemizing, maybe_PERMS_REPORT;
41cfde6b 359 uchar fnamecmp_type;
6c3862fa 360 enum logcode code;
f7632fc6 361
dfd5ba6a
WD
362 if (list_only)
363 return;
2f03f956 364
6c3862fa
WD
365 if (protocol_version >= 29) {
366 itemizing = 1;
367 code = daemon_log_format_has_i ? 0 : FLOG;
6c3862fa
WD
368 maybe_PERMS_REPORT = log_format_has_i ? 0 : PERMS_REPORT;
369 } else if (am_daemon) {
370 itemizing = daemon_log_format_has_i && !dry_run;
371 code = itemizing || dry_run ? FCLIENT : FINFO;
6c3862fa
WD
372 maybe_PERMS_REPORT = PERMS_REPORT;
373 } else if (!am_server) {
374 itemizing = log_format_has_i;
375 code = itemizing ? 0 : FINFO;
6c3862fa
WD
376 maybe_PERMS_REPORT = log_format_has_i ? 0 : PERMS_REPORT;
377 } else {
378 itemizing = 0;
379 code = FINFO;
6c3862fa
WD
380 maybe_PERMS_REPORT = PERMS_REPORT;
381 }
382
8e85be0a
WD
383 if (!fname) {
384 if (fuzzy_dirlist) {
385 flist_free(fuzzy_dirlist);
386 fuzzy_dirlist = NULL;
387 fuzzy_dirname = NULL;
388 }
389 if (missing_below >= 0) {
390 dry_run--;
391 missing_below = -1;
392 }
393 return;
394 }
395
4875d6b6
WD
396 if (verbose > 2) {
397 rprintf(FINFO, "recv_generator(%s,%d)\n",
398 safe_fname(fname), ndx);
399 }
2f03f956 400
8174bc35
WD
401 if (server_filter_list.head) {
402 if (excluded_below >= 0) {
403 if (file->dir.depth > excluded_below)
404 goto skipping;
405 excluded_below = -1;
406 }
407 if (check_filter(&server_filter_list, fname,
408 S_ISDIR(file->mode)) < 0) {
409 if (S_ISDIR(file->mode))
410 excluded_below = file->dir.depth;
411 skipping:
412 if (verbose) {
413 rprintf(FINFO,
414 "skipping server-excluded file \"%s\"\n",
415 safe_fname(fname));
416 }
417 return;
3e35c34b 418 }
3e35c34b 419 }
97f9dcae 420
8e85be0a 421 if (missing_below >= 0 && file->dir.depth <= missing_below) {
df337831
WD
422 dry_run--;
423 missing_below = -1;
424 }
73f7af0e
WD
425 if (dry_run > 1) {
426 statret = -1;
427 stat_errno = ENOENT;
428 } else {
8e85be0a
WD
429 if (fuzzy_basis && S_ISREG(file->mode)) {
430 char *dn = file->dirname ? file->dirname : ".";
431 /* Yes, identical dirnames are guaranteed to have
432 * identical pointers at this point. */
433 if (fuzzy_dirname != dn) {
434 if (fuzzy_dirlist)
435 flist_free(fuzzy_dirlist);
436 fuzzy_dirname = dn;
437 fuzzy_dirlist = get_dirlist(fuzzy_dirname, 1);
438 }
439 }
440
73f7af0e
WD
441 statret = link_stat(fname, &st,
442 keep_dirlinks && S_ISDIR(file->mode));
443 stat_errno = errno;
444 }
63787382 445
a7260c40 446 if (only_existing && statret == -1 && stat_errno == ENOENT) {
1347d512 447 /* we only want to update existing files */
ecc81fce
WD
448 if (verbose > 1) {
449 rprintf(FINFO, "not creating new file \"%s\"\n",
450 safe_fname(fname));
451 }
1347d512
AT
452 return;
453 }
454
d9b4d267
WD
455 if (statret == 0 && !preserve_perms
456 && S_ISDIR(st.st_mode) == S_ISDIR(file->mode)) {
4df9f368 457 /* if the file exists already and we aren't perserving
2cda2560
WD
458 * permissions then act as though the remote end sent
459 * us the file permissions we already have */
67e78a82
WD
460 file->mode = (file->mode & ~CHMOD_BITS)
461 | (st.st_mode & CHMOD_BITS);
4df9f368
AT
462 }
463
2f03f956 464 if (S_ISDIR(file->mode)) {
2cda2560
WD
465 /* The file to be received is a directory, so we need
466 * to prepare appropriately. If there is already a
467 * file of that name and it is *not* a directory, then
468 * we need to delete it. If it doesn't exist, then
027428eb 469 * (perhaps recursively) create it. */
2f03f956 470 if (statret == 0 && !S_ISDIR(st.st_mode)) {
8e3ead09 471 delete_file(fname, st.st_mode, DEL_TERSE);
2f03f956
AT
472 statret = -1;
473 }
df337831
WD
474 if (dry_run && statret != 0 && missing_below < 0) {
475 missing_below = file->dir.depth;
476 dry_run++;
477 }
6c3862fa 478 if (itemizing && f_out != -1)
c557eb8c 479 itemize(file, statret, &st, 0, f_out, ndx);
2f03f956 480 if (statret != 0 && do_mkdir(fname,file->mode) != 0 && errno != EEXIST) {
027428eb
WD
481 if (!relative_paths || errno != ENOENT
482 || create_directory_path(fname, orig_umask) < 0
483 || do_mkdir(fname, file->mode) < 0) {
d62bcc17
WD
484 rsyserr(FERROR, errno,
485 "recv_generator: mkdir %s failed",
486 full_fname(fname));
2f03f956
AT
487 }
488 }
716e73d4 489 if (set_perms(fname, file, statret ? NULL : &st, 0)
6c3862fa
WD
490 && verbose && code && f_out != -1)
491 rprintf(code, "%s/\n", safe_fname(fname));
c93fad5e 492 if (delete_during && f_out != -1 && csum_length != SUM_LENGTH
31937d36
WD
493 && (file->flags & FLAG_DEL_HERE))
494 delete_in_dir(flist, fname, file);
2f03f956 495 return;
06a1dbad 496 }
6c3862fa 497
06a1dbad 498 if (max_size && file->length > max_size) {
4875d6b6
WD
499 if (verbose > 1) {
500 rprintf(FINFO, "%s is over max-size\n",
501 safe_fname(fname));
502 }
7d1bfaf7 503 return;
2f03f956
AT
504 }
505
506 if (preserve_links && S_ISLNK(file->mode)) {
4f5b0756 507#ifdef SUPPORT_LINKS
728d0922 508 if (safe_symlinks && unsafe_symlink(file->u.link, fname)) {
2f03f956 509 if (verbose) {
4875d6b6
WD
510 rprintf(FINFO,
511 "ignoring unsafe symlink %s -> \"%s\"\n",
512 full_fname(fname),
513 safe_fname(file->u.link));
2f03f956
AT
514 }
515 return;
516 }
517 if (statret == 0) {
7e38410e
WD
518 char lnk[MAXPATHLEN];
519 int len;
520
8a8356b7 521 if (!S_ISDIR(st.st_mode)
7e38410e
WD
522 && (len = readlink(fname, lnk, MAXPATHLEN-1)) > 0) {
523 lnk[len] = 0;
85d4d142
MP
524 /* A link already pointing to the
525 * right place -- no further action
526 * required. */
7e38410e 527 if (strcmp(lnk, file->u.link) == 0) {
6c3862fa 528 if (itemizing) {
c557eb8c
WD
529 itemize(file, 0, &st, 0,
530 f_out, ndx);
531 }
c41b52c4 532 set_perms(fname, file, &st,
8a8356b7 533 maybe_PERMS_REPORT);
2f03f956
AT
534 return;
535 }
2cda2560 536 }
7e38410e
WD
537 /* Not the right symlink (or not a symlink), so
538 * delete it. */
88b218fa 539 if (S_ISLNK(st.st_mode))
8a8356b7 540 delete_file(fname, st.st_mode, DEL_TERSE);
88b218fa 541 else {
8e3ead09 542 delete_file(fname, st.st_mode, DEL_TERSE);
88b218fa
WD
543 statret = -1;
544 }
2f03f956 545 }
728d0922 546 if (do_symlink(file->u.link,fname) != 0) {
d62bcc17 547 rsyserr(FERROR, errno, "symlink %s -> \"%s\" failed",
ecc81fce 548 full_fname(fname), safe_fname(file->u.link));
2f03f956
AT
549 } else {
550 set_perms(fname,file,NULL,0);
6c3862fa 551 if (itemizing) {
c557eb8c
WD
552 itemize(file, statret, &st, SID_UPDATING,
553 f_out, ndx);
6c3862fa
WD
554 }
555 if (code && verbose) {
556 rprintf(code, "%s -> %s\n", safe_fname(fname),
c557eb8c 557 safe_fname(file->u.link));
2f03f956 558 }
fe960187
WD
559 if (remove_sent_files && !dry_run) {
560 char numbuf[4];
561 SIVAL(numbuf, 0, ndx);
562 send_msg(MSG_SUCCESS, numbuf, 4);
563 }
2f03f956
AT
564 }
565#endif
566 return;
567 }
568
2f03f956 569 if (am_root && preserve_devices && IS_DEVICE(file->mode)) {
2cda2560 570 if (statret != 0 ||
2f03f956 571 st.st_mode != file->mode ||
3915fd75 572 st.st_rdev != file->u.rdev) {
88b218fa 573 if (IS_DEVICE(st.st_mode))
8a8356b7 574 delete_file(fname, st.st_mode, DEL_TERSE);
88b218fa 575 else {
8e3ead09 576 delete_file(fname, st.st_mode, DEL_TERSE);
88b218fa 577 statret = -1;
c557eb8c 578 }
d62bcc17 579 if (verbose > 2) {
2f03f956 580 rprintf(FINFO,"mknod(%s,0%o,0x%x)\n",
ecc81fce
WD
581 safe_fname(fname),
582 (int)file->mode, (int)file->u.rdev);
d62bcc17 583 }
728d0922 584 if (do_mknod(fname,file->mode,file->u.rdev) != 0) {
d62bcc17
WD
585 rsyserr(FERROR, errno, "mknod %s failed",
586 full_fname(fname));
2f03f956
AT
587 } else {
588 set_perms(fname,file,NULL,0);
6c3862fa 589 if (itemizing) {
88b218fa
WD
590 itemize(file, statret, &st, SID_UPDATING,
591 f_out, ndx);
6c3862fa
WD
592 }
593 if (code && verbose) {
594 rprintf(code, "%s\n",
ecc81fce
WD
595 safe_fname(fname));
596 }
2f03f956
AT
597 }
598 } else {
6c3862fa 599 if (itemizing) {
c557eb8c
WD
600 itemize(file, statret, &st, 0,
601 f_out, ndx);
602 }
8a8356b7 603 set_perms(fname, file, &st, maybe_PERMS_REPORT);
2f03f956
AT
604 }
605 return;
606 }
2f03f956 607
6dff5992 608 if (preserve_hard_links && hard_link_check(file, HL_CHECK_MASTER))
2f03f956 609 return;
2f03f956
AT
610
611 if (!S_ISREG(file->mode)) {
ecc81fce
WD
612 rprintf(FINFO, "skipping non-regular file \"%s\"\n",
613 safe_fname(fname));
2f03f956
AT
614 return;
615 }
616
375a4556 617 fnamecmp = fname;
41cfde6b 618 fnamecmp_type = FNAMECMP_FNAME;
375a4556 619
06a1dbad 620 if (statret != 0 && basis_dir[0] != NULL) {
b7e8628c
WD
621 int fallback_match = -1;
622 int match_level = 0;
623 int i = 0;
624 do {
625 pathjoin(fnamecmpbuf, sizeof fnamecmpbuf,
626 basis_dir[i], fname);
627 if (link_stat(fnamecmpbuf, &st, 0) == 0
628 && S_ISREG(st.st_mode)) {
629 statret = 0;
630 if (link_dest) {
631 if (!match_level) {
632 fallback_match = i;
633 match_level = 1;
634 } else if (match_level == 2
635 && !unchanged_attrs(file, &st))
636 continue;
637 if (!unchanged_file(fnamecmpbuf, file, &st))
638 continue;
639 fallback_match = i;
640 match_level = 2;
641 if (!unchanged_attrs(file, &st))
642 continue;
643 }
644 match_level = 3;
645 break;
646 }
647 } while (basis_dir[++i] != NULL);
648 if (statret == 0) {
649 if (match_level < 3) {
650 i = fallback_match;
651 pathjoin(fnamecmpbuf, sizeof fnamecmpbuf,
652 basis_dir[i], fname);
653 }
4f5b0756 654#ifdef HAVE_LINK
b7e8628c 655 if (link_dest && match_level == 3 && !dry_run) {
e7d13fe5
WD
656 if (do_link(fnamecmpbuf, fname) < 0) {
657 if (verbose) {
658 rsyserr(FINFO, errno,
659 "link %s => %s",
4875d6b6 660 full_fname(fnamecmpbuf),
e7d13fe5
WD
661 safe_fname(fname));
662 }
663 fnamecmp = fnamecmpbuf;
2be2fb3e 664 fnamecmp_type = i;
e7bc9b64 665 }
e7d13fe5 666 } else
59c95e42 667#endif
41cfde6b 668 {
e7d13fe5 669 fnamecmp = fnamecmpbuf;
2be2fb3e 670 fnamecmp_type = i;
41cfde6b 671 }
e7d13fe5
WD
672 }
673 }
674
675 if (statret == 0 && !S_ISREG(st.st_mode)) {
8e3ead09 676 if (delete_file(fname, st.st_mode, DEL_TERSE) != 0)
e7d13fe5
WD
677 return;
678 statret = -1;
679 stat_errno = ENOENT;
375a4556
DD
680 }
681
9d954dca 682 if (partial_dir && (partialptr = partial_dir_fname(fname)) != NULL
72c19bb3
WD
683 && link_stat(partialptr, &partial_st, 0) == 0
684 && S_ISREG(partial_st.st_mode)) {
06a1dbad 685 if (statret != 0)
72c19bb3
WD
686 goto prepare_to_open;
687 } else
688 partialptr = NULL;
89f7eff3 689
06a1dbad 690 if (statret != 0 && fuzzy_basis && dry_run <= 1) {
8e85be0a
WD
691 int j = find_fuzzy(file, fuzzy_dirlist);
692 if (j >= 0) {
693 fuzzy_file = fuzzy_dirlist->files[j];
694 f_name_to(fuzzy_file, fnamecmpbuf);
695 if (verbose > 2) {
696 rprintf(FINFO, "fuzzy basis selected for %s: %s\n",
697 safe_fname(fname), safe_fname(fnamecmpbuf));
698 }
699 st.st_mode = fuzzy_file->mode;
700 st.st_size = fuzzy_file->length;
701 st.st_mtime = fuzzy_file->modtime;
702 statret = 0;
703 fnamecmp = fnamecmpbuf;
704 fnamecmp_type = FNAMECMP_FUZZY;
705 }
706 }
707
06a1dbad 708 if (statret != 0) {
6dff5992
WD
709 if (preserve_hard_links && hard_link_check(file, HL_SKIP))
710 return;
41cfde6b
WD
711 if (stat_errno == ENOENT)
712 goto notify_others;
713 if (verbose > 1) {
e7d13fe5
WD
714 rsyserr(FERROR, stat_errno,
715 "recv_generator: failed to stat %s",
d62bcc17 716 full_fname(fname));
2f03f956
AT
717 }
718 return;
719 }
720
41cfde6b 721 if (opt_ignore_existing && fnamecmp_type == FNAMECMP_FNAME) {
3d6feada 722 if (verbose > 1)
ecc81fce 723 rprintf(FINFO, "%s exists\n", safe_fname(fname));
3d6feada 724 return;
2cda2560 725 }
3d6feada 726
41cfde6b 727 if (update_only && fnamecmp_type == FNAMECMP_FNAME
d3a4375f 728 && cmp_modtime(st.st_mtime, file->modtime) > 0) {
2f03f956 729 if (verbose > 1)
ecc81fce 730 rprintf(FINFO, "%s is newer\n", safe_fname(fname));
2f03f956
AT
731 return;
732 }
733
2be2fb3e 734 if (!compare_dest && fnamecmp_type <= FNAMECMP_BASIS_DIR_HIGH)
b7e8628c 735 ;
8e85be0a
WD
736 else if (fnamecmp_type == FNAMECMP_FUZZY)
737 ;
b7e8628c 738 else if (unchanged_file(fnamecmp, file, &st)) {
6c3862fa 739 if (itemizing) {
c557eb8c
WD
740 itemize(file, statret, &st,
741 fnamecmp_type == FNAMECMP_FNAME
742 ? 0 : SID_NO_DEST_AND_NO_UPDATE,
743 f_out, ndx);
06a1dbad 744 }
41cfde6b 745 if (fnamecmp_type == FNAMECMP_FNAME)
8a8356b7 746 set_perms(fname, file, &st, maybe_PERMS_REPORT);
2f03f956
AT
747 return;
748 }
749
89f7eff3 750prepare_to_open:
9d954dca
WD
751 if (partialptr) {
752 st = partial_st;
753 fnamecmp = partialptr;
754 fnamecmp_type = FNAMECMP_PARTIAL_DIR;
755 statret = 0;
756 }
757
3841a04e
WD
758 if (dry_run || read_batch)
759 goto notify_others;
760 if (whole_file > 0) {
06a1dbad
WD
761 if (statret == 0)
762 statret = 1;
41cfde6b 763 goto notify_others;
2f03f956
AT
764 }
765
8e85be0a
WD
766 if (fuzzy_basis) {
767 int j = flist_find(fuzzy_dirlist, file);
768 if (j >= 0) /* don't use changing file as future fuzzy basis */
769 fuzzy_dirlist->files[j]->flags |= FLAG_NO_FUZZY;
770 }
771
2cda2560 772 /* open the file */
8c9fd200 773 fd = do_open(fnamecmp, O_RDONLY, 0);
2f03f956
AT
774
775 if (fd == -1) {
d62bcc17
WD
776 rsyserr(FERROR, errno, "failed to open %s, continuing",
777 full_fname(fnamecmp));
cd6aa5b5 778 pretend_missing:
60be6acf 779 /* pretend the file didn't exist */
6dff5992
WD
780 if (preserve_hard_links && hard_link_check(file, HL_SKIP))
781 return;
41cfde6b
WD
782 statret = -1;
783 goto notify_others;
2f03f956
AT
784 }
785
cd6aa5b5
WD
786 if (inplace && make_backups) {
787 if (!(backupptr = get_backup_name(fname))) {
788 close(fd);
789 return;
790 }
7842418b 791 if (!(back_file = make_file(fname, NULL, NO_FILTERS))) {
cd6aa5b5
WD
792 close(fd);
793 goto pretend_missing;
794 }
795 if (robust_unlink(backupptr) && errno != ENOENT) {
796 rsyserr(FERROR, errno, "unlink %s",
797 full_fname(backupptr));
798 free(back_file);
799 close(fd);
800 return;
801 }
802 if ((f_copy = do_open(backupptr,
803 O_WRONLY | O_CREAT | O_TRUNC | O_EXCL, 0600)) < 0) {
804 rsyserr(FERROR, errno, "open %s",
805 full_fname(backupptr));
806 free(back_file);
807 close(fd);
808 return;
809 }
41cfde6b 810 fnamecmp_type = FNAMECMP_BACKUP;
cd6aa5b5
WD
811 }
812
dfd5ba6a 813 if (verbose > 3) {
ecc81fce
WD
814 rprintf(FINFO, "gen mapped %s of size %.0f\n",
815 safe_fname(fnamecmp), (double)st.st_size);
dfd5ba6a 816 }
2f03f956 817
2f03f956 818 if (verbose > 2)
0492fdfb 819 rprintf(FINFO, "generating and sending sums for %d\n", ndx);
2f03f956 820
41cfde6b 821notify_others:
0492fdfb 822 write_int(f_out, ndx);
6c3862fa 823 if (itemizing) {
e3bcd893
WD
824 itemize(file, statret, &st, SID_UPDATING
825 | (always_checksum ? SID_REPORT_CHECKSUM : 0),
826 f_out, -1);
827 if (inplace && !read_batch)
828 write_byte(f_out, fnamecmp_type);
829 }
8e85be0a 830 if (f_out_name >= 0) {
41cfde6b 831 write_byte(f_out_name, fnamecmp_type);
8e85be0a
WD
832 if (fnamecmp_type == FNAMECMP_FUZZY) {
833 uchar lenbuf[3], *lb = lenbuf;
834 int len = strlen(fuzzy_file->basename);
835 if (len > 0x7F) {
836#if MAXPATHLEN > 0x7FFF
837 *lb++ = len / 0x10000 + 0x80;
838 *lb++ = len / 0x100;
839#else
840 *lb++ = len / 0x100 + 0x80;
841#endif
842 }
843 *lb = len;
ee03617b 844 write_buf(f_out_name, (char*)lenbuf, lb - lenbuf + 1);
8e85be0a
WD
845 write_buf(f_out_name, fuzzy_file->basename, len);
846 }
847 }
cd6aa5b5 848
41cfde6b
WD
849 if (dry_run || read_batch)
850 return;
851
852 if (statret == 0) {
853 generate_and_send_sums(fd, st.st_size, f_out, f_copy);
2f03f956 854
41cfde6b
WD
855 if (f_copy >= 0) {
856 close(f_copy);
857 set_perms(backupptr, back_file, NULL, 0);
858 if (verbose > 1) {
859 rprintf(FINFO, "backed up %s to %s\n",
4875d6b6 860 safe_fname(fname), safe_fname(backupptr));
41cfde6b
WD
861 }
862 free(back_file);
863 }
864
865 close(fd);
866 } else
867 write_sum_head(f_out, NULL);
2f03f956
AT
868}
869
870
41cfde6b
WD
871void generate_files(int f_out, struct file_list *flist, char *local_name,
872 int f_out_name)
2f03f956
AT
873{
874 int i;
e1f67417 875 int phase = 0;
968c8030 876 char fbuf[MAXPATHLEN];
3ea9bbd6
WD
877 int need_retouch_dir_times = preserve_times && !omit_dir_times;
878 int need_retouch_dir_perms = 0;
0492fdfb
WD
879 int save_only_existing = only_existing;
880 int save_opt_ignore_existing = opt_ignore_existing;
2f03f956 881
45e08edb
WD
882 if (verbose > 2) {
883 rprintf(FINFO, "generator starting pid=%ld count=%d\n",
884 (long)getpid(), flist->count);
885 }
2f03f956 886
3e7053ac
MP
887 if (verbose >= 2) {
888 rprintf(FINFO,
f38bd4a0 889 whole_file > 0
3e7053ac
MP
890 ? "delta-transmission disabled for local transfer or --whole-file\n"
891 : "delta transmission enabled\n");
892 }
2cda2560 893
0492fdfb
WD
894 /* We expect to just sit around now, so don't exit on a timeout.
895 * If we really get a timeout then the other process should exit. */
a57873b7
AT
896 io_timeout = 0;
897
2f03f956
AT
898 for (i = 0; i < flist->count; i++) {
899 struct file_struct *file = flist->files[i];
dfd5ba6a 900 struct file_struct copy;
2f03f956 901
dfd5ba6a
WD
902 if (!file->basename)
903 continue;
0492fdfb
WD
904
905 /* We need to ensure that any dirs we create have writeable
906 * permissions during the time we are putting files within
907 * them. This is then fixed after the transfer is done. */
dfd5ba6a
WD
908 if (!am_root && S_ISDIR(file->mode) && !(file->mode & S_IWUSR)) {
909 copy = *file;
dfd5ba6a
WD
910 copy.mode |= S_IWUSR; /* user write */
911 file = &copy;
3ea9bbd6 912 need_retouch_dir_perms = 1;
2f03f956
AT
913 }
914
3fef5364 915 recv_generator(local_name ? local_name : f_name_to(file, fbuf),
fa13f396 916 flist, file, i, f_out, f_out_name);
2f03f956 917 }
8e85be0a 918 recv_generator(NULL, NULL, NULL, 0, -1, -1);
c93fad5e 919 if (delete_during)
31937d36 920 delete_in_dir(NULL, NULL, NULL);
2f03f956
AT
921
922 phase++;
923 csum_length = SUM_LENGTH;
0492fdfb
WD
924 only_existing = max_size = opt_ignore_existing = 0;
925 update_only = always_checksum = size_only = 0;
e1f67417 926 ignore_times = 1;
2f03f956
AT
927
928 if (verbose > 2)
929 rprintf(FINFO,"generate_files phase=%d\n",phase);
930
7daccb8e 931 write_int(f_out, -1);
2f03f956 932
bc63ae3f
S
933 /* files can cycle through the system more than once
934 * to catch initial checksum errors */
b9b15fb1 935 while ((i = get_redo_num()) != -1) {
bc63ae3f 936 struct file_struct *file = flist->files[i];
3fef5364 937 recv_generator(local_name ? local_name : f_name_to(file, fbuf),
fa13f396 938 flist, file, i, f_out, f_out_name);
bc63ae3f 939 }
2f03f956 940
bc63ae3f 941 phase++;
0492fdfb
WD
942 only_existing = save_only_existing;
943 opt_ignore_existing = save_opt_ignore_existing;
944
bc63ae3f
S
945 if (verbose > 2)
946 rprintf(FINFO,"generate_files phase=%d\n",phase);
2f03f956 947
7daccb8e 948 write_int(f_out, -1);
6dff5992 949
b0da4b23
WD
950 /* Read post-redo-phase MSG_DONE and any prior messages. */
951 get_redo_num();
952
6dff5992
WD
953 if (preserve_hard_links)
954 do_hard_links();
955
0492fdfb
WD
956 if ((need_retouch_dir_perms || need_retouch_dir_times)
957 && !list_only && !local_name && !dry_run) {
3ea9bbd6
WD
958 /* Now we need to fix any directory permissions that were
959 * modified during the transfer and/or re-set any tweaked
960 * modified-time values. */
961 for (i = 0; i < flist->count; i++) {
962 struct file_struct *file = flist->files[i];
963 if (!file->basename || !S_ISDIR(file->mode))
964 continue;
965 if (!need_retouch_dir_times && file->mode & S_IWUSR)
966 continue;
967 recv_generator(local_name ? local_name : f_name(file),
968 flist, file, i, -1, -1);
969 }
6dff5992 970 }
8e85be0a 971 recv_generator(NULL, NULL, NULL, 0, -1, -1);
6dff5992
WD
972
973 if (verbose > 2)
974 rprintf(FINFO,"generate_files finished\n");
2f03f956 975}