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