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