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