1: /*
2: * Routines that are exclusive to the generator process.
3: *
4: * Copyright (C) 1996-2000 Andrew Tridgell
5: * Copyright (C) 1996 Paul Mackerras
6: * Copyright (C) 2002 Martin Pool <mbp@samba.org>
7: * Copyright (C) 2003-2015 Wayne Davison
8: *
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 3 of the License, or
12: * (at your option) any later version.
13: *
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.
18: *
19: * You should have received a copy of the GNU General Public License along
20: * with this program; if not, visit the http://fsf.org website.
21: */
22:
23: #include "rsync.h"
24: #include "inums.h"
25: #include "ifuncs.h"
26:
27: extern int dry_run;
28: extern int do_xfers;
29: extern int stdout_format_has_i;
30: extern int logfile_format_has_i;
31: extern int am_root;
32: extern int am_server;
33: extern int am_daemon;
34: extern int inc_recurse;
35: extern int relative_paths;
36: extern int implied_dirs;
37: extern int keep_dirlinks;
38: extern int preserve_acls;
39: extern int preserve_xattrs;
40: extern int preserve_links;
41: extern int preserve_devices;
42: extern int preserve_specials;
43: extern int preserve_hard_links;
44: extern int preserve_executability;
45: extern int preserve_perms;
46: extern int preserve_times;
47: extern int delete_mode;
48: extern int delete_before;
49: extern int delete_during;
50: extern int delete_after;
51: extern int missing_args;
52: extern int msgdone_cnt;
53: extern int ignore_errors;
54: extern int remove_source_files;
55: extern int delay_updates;
56: extern int update_only;
57: extern int human_readable;
58: extern int ignore_existing;
59: extern int ignore_non_existing;
60: extern int want_xattr_optim;
61: extern int inplace;
62: extern int append_mode;
63: extern int make_backups;
64: extern int csum_length;
65: extern int ignore_times;
66: extern int size_only;
67: extern OFF_T max_size;
68: extern OFF_T min_size;
69: extern int io_error;
70: extern int flist_eof;
71: extern int allowed_lull;
72: extern int sock_f_out;
73: extern int protocol_version;
74: extern int file_total;
75: extern int fuzzy_basis;
76: extern int always_checksum;
77: extern int checksum_len;
78: extern char *partial_dir;
79: extern int compare_dest;
80: extern int copy_dest;
81: extern int link_dest;
82: extern int whole_file;
83: extern int list_only;
84: extern int read_batch;
85: extern int write_batch;
86: extern int safe_symlinks;
87: extern long block_size; /* "long" because popt can't set an int32. */
88: extern int unsort_ndx;
89: extern int max_delete;
90: extern int force_delete;
91: extern int one_file_system;
92: extern int skipped_deletes;
93: extern dev_t filesystem_dev;
94: extern mode_t orig_umask;
95: extern uid_t our_uid;
96: extern char *tmpdir;
97: extern char *basis_dir[MAX_BASIS_DIRS+1];
98: extern struct file_list *cur_flist, *first_flist, *dir_flist;
99: extern filter_rule_list filter_list, daemon_filter_list;
100:
101: int maybe_ATTRS_REPORT = 0;
102:
103: static dev_t dev_zero;
104: static int deldelay_size = 0, deldelay_cnt = 0;
105: static char *deldelay_buf = NULL;
106: static int deldelay_fd = -1;
107: static int loopchk_limit;
108: static int dir_tweaking;
109: static int symlink_timeset_failed_flags;
110: static int need_retouch_dir_times;
111: static int need_retouch_dir_perms;
112: static const char *solo_file = NULL;
113:
114: enum nonregtype {
115: TYPE_DIR, TYPE_SPECIAL, TYPE_DEVICE, TYPE_SYMLINK
116: };
117:
118: /* Forward declarations. */
119: #ifdef SUPPORT_HARD_LINKS
120: static void handle_skipped_hlink(struct file_struct *file, int itemizing,
121: enum logcode code, int f_out);
122: #endif
123:
124: #define EARLY_DELAY_DONE_MSG() (!delay_updates)
125: #define EARLY_DELETE_DONE_MSG() (!(delete_during == 2 || delete_after))
126:
127: static int start_delete_delay_temp(void)
128: {
129: char fnametmp[MAXPATHLEN];
130: int save_dry_run = dry_run;
131:
132: dry_run = 0;
133: if (!get_tmpname(fnametmp, "deldelay", False)
134: || (deldelay_fd = do_mkstemp(fnametmp, 0600)) < 0) {
135: rprintf(FINFO, "NOTE: Unable to create delete-delay temp file%s.\n",
136: inc_recurse ? "" : " -- switching to --delete-after");
137: delete_during = 0;
138: delete_after = !inc_recurse;
139: dry_run = save_dry_run;
140: return 0;
141: }
142: unlink(fnametmp);
143: dry_run = save_dry_run;
144: return 1;
145: }
146:
147: static int flush_delete_delay(void)
148: {
149: if (deldelay_fd < 0 && !start_delete_delay_temp())
150: return 0;
151: if (write(deldelay_fd, deldelay_buf, deldelay_cnt) != deldelay_cnt) {
152: rsyserr(FERROR, errno, "flush of delete-delay buffer");
153: delete_during = 0;
154: delete_after = !inc_recurse;
155: close(deldelay_fd);
156: return 0;
157: }
158: deldelay_cnt = 0;
159: return 1;
160: }
161:
162: static int remember_delete(struct file_struct *file, const char *fname, int flags)
163: {
164: int len;
165:
166: if (deldelay_cnt == deldelay_size && !flush_delete_delay())
167: return 0;
168:
169: if (flags & DEL_NO_UID_WRITE)
170: deldelay_buf[deldelay_cnt++] = '!';
171:
172: while (1) {
173: len = snprintf(deldelay_buf + deldelay_cnt,
174: deldelay_size - deldelay_cnt,
175: "%x %s%c",
176: (int)file->mode, fname, '\0');
177: if ((deldelay_cnt += len) <= deldelay_size)
178: break;
179: deldelay_cnt -= len;
180: if (!flush_delete_delay())
181: return 0;
182: }
183:
184: return 1;
185: }
186:
187: static int read_delay_line(char *buf, int *flags_p)
188: {
189: static int read_pos = 0;
190: int j, len, mode;
191: char *bp, *past_space;
192:
193: while (1) {
194: for (j = read_pos; j < deldelay_cnt && deldelay_buf[j]; j++) {}
195: if (j < deldelay_cnt)
196: break;
197: if (deldelay_fd < 0) {
198: if (j > read_pos)
199: goto invalid_data;
200: return -1;
201: }
202: deldelay_cnt -= read_pos;
203: if (deldelay_cnt == deldelay_size)
204: goto invalid_data;
205: if (deldelay_cnt && read_pos) {
206: memmove(deldelay_buf, deldelay_buf + read_pos,
207: deldelay_cnt);
208: }
209: len = read(deldelay_fd, deldelay_buf + deldelay_cnt,
210: deldelay_size - deldelay_cnt);
211: if (len == 0) {
212: if (deldelay_cnt) {
213: rprintf(FERROR,
214: "ERROR: unexpected EOF in delete-delay file.\n");
215: }
216: return -1;
217: }
218: if (len < 0) {
219: rsyserr(FERROR, errno,
220: "reading delete-delay file");
221: return -1;
222: }
223: deldelay_cnt += len;
224: read_pos = 0;
225: }
226:
227: bp = deldelay_buf + read_pos;
228: if (*bp == '!') {
229: bp++;
230: *flags_p = DEL_NO_UID_WRITE;
231: } else
232: *flags_p = 0;
233:
234: if (sscanf(bp, "%x ", &mode) != 1) {
235: invalid_data:
236: rprintf(FERROR, "ERROR: invalid data in delete-delay file.\n");
237: return -1;
238: }
239: past_space = strchr(bp, ' ') + 1;
240: len = j - read_pos - (past_space - bp) + 1; /* count the '\0' */
241: read_pos = j + 1;
242:
243: if (len > MAXPATHLEN) {
244: rprintf(FERROR, "ERROR: filename too long in delete-delay file.\n");
245: return -1;
246: }
247:
248: /* The caller needs the name in a MAXPATHLEN buffer, so we copy it
249: * instead of returning a pointer to our buffer. */
250: memcpy(buf, past_space, len);
251:
252: return mode;
253: }
254:
255: static void do_delayed_deletions(char *delbuf)
256: {
257: int mode, flags;
258:
259: if (deldelay_fd >= 0) {
260: if (deldelay_cnt && !flush_delete_delay())
261: return;
262: lseek(deldelay_fd, 0, 0);
263: }
264: while ((mode = read_delay_line(delbuf, &flags)) >= 0)
265: delete_item(delbuf, mode, flags | DEL_RECURSE);
266: if (deldelay_fd >= 0)
267: close(deldelay_fd);
268: }
269:
270: /* This function is used to implement per-directory deletion, and is used by
271: * all the --delete-WHEN options. Note that the fbuf pointer must point to a
272: * MAXPATHLEN buffer with the name of the directory in it (the functions we
273: * call will append names onto the end, but the old dir value will be restored
274: * on exit). */
275: static void delete_in_dir(char *fbuf, struct file_struct *file, dev_t *fs_dev)
276: {
277: static int already_warned = 0;
278: struct file_list *dirlist;
279: char delbuf[MAXPATHLEN];
280: int dlen, i;
281:
282: if (!fbuf) {
283: change_local_filter_dir(NULL, 0, 0);
284: return;
285: }
286:
287: if (DEBUG_GTE(DEL, 2))
288: rprintf(FINFO, "delete_in_dir(%s)\n", fbuf);
289:
290: if (allowed_lull)
291: maybe_send_keepalive(time(NULL), MSK_ALLOW_FLUSH);
292:
293: if (io_error & IOERR_GENERAL && !ignore_errors) {
294: if (already_warned)
295: return;
296: rprintf(FINFO,
297: "IO error encountered -- skipping file deletion\n");
298: already_warned = 1;
299: return;
300: }
301:
302: dlen = strlen(fbuf);
303: change_local_filter_dir(fbuf, dlen, F_DEPTH(file));
304:
305: if (one_file_system) {
306: if (file->flags & FLAG_TOP_DIR)
307: filesystem_dev = *fs_dev;
308: else if (filesystem_dev != *fs_dev)
309: return;
310: }
311:
312: dirlist = get_dirlist(fbuf, dlen, 0);
313:
314: /* If an item in dirlist is not found in flist, delete it
315: * from the filesystem. */
316: for (i = dirlist->used; i--; ) {
317: struct file_struct *fp = dirlist->files[i];
318: if (!F_IS_ACTIVE(fp))
319: continue;
320: if (fp->flags & FLAG_MOUNT_DIR && S_ISDIR(fp->mode)) {
321: if (INFO_GTE(MOUNT, 1))
322: rprintf(FINFO, "cannot delete mount point: %s\n",
323: f_name(fp, NULL));
324: continue;
325: }
326: /* Here we want to match regardless of file type. Replacement
327: * of a file with one of another type is handled separately by
328: * a delete_item call with a DEL_MAKE_ROOM flag. */
329: if (flist_find_ignore_dirness(cur_flist, fp) < 0) {
330: int flags = DEL_RECURSE;
331: if (!(fp->mode & S_IWUSR) && !am_root && fp->flags & FLAG_OWNED_BY_US)
332: flags |= DEL_NO_UID_WRITE;
333: f_name(fp, delbuf);
334: if (delete_during == 2) {
335: if (!remember_delete(fp, delbuf, flags))
336: break;
337: } else
338: delete_item(delbuf, fp->mode, flags);
339: }
340: }
341:
342: flist_free(dirlist);
343: }
344:
345: /* This deletes any files on the receiving side that are not present on the
346: * sending side. This is used by --delete-before and --delete-after. */
347: static void do_delete_pass(void)
348: {
349: char fbuf[MAXPATHLEN];
350: STRUCT_STAT st;
351: int j;
352:
353: /* dry_run is incremented when the destination doesn't exist yet. */
354: if (dry_run > 1 || list_only)
355: return;
356:
357: for (j = 0; j < cur_flist->used; j++) {
358: struct file_struct *file = cur_flist->sorted[j];
359:
360: if (!F_IS_ACTIVE(file))
361: continue;
362:
363: f_name(file, fbuf);
364:
365: if (!(file->flags & FLAG_CONTENT_DIR)) {
366: change_local_filter_dir(fbuf, strlen(fbuf), F_DEPTH(file));
367: continue;
368: }
369:
370: if (DEBUG_GTE(DEL, 1) && file->flags & FLAG_TOP_DIR)
371: rprintf(FINFO, "deleting in %s\n", fbuf);
372:
373: if (link_stat(fbuf, &st, keep_dirlinks) < 0
374: || !S_ISDIR(st.st_mode))
375: continue;
376:
377: delete_in_dir(fbuf, file, &st.st_dev);
378: }
379: delete_in_dir(NULL, NULL, &dev_zero);
380:
381: if (INFO_GTE(FLIST, 2) && !am_server)
382: rprintf(FINFO, " \r");
383: }
384:
385: static inline int time_differs(struct file_struct *file, stat_x *sxp)
386: {
387: return cmp_time(sxp->st.st_mtime, file->modtime);
388: }
389:
390: static inline int perms_differ(struct file_struct *file, stat_x *sxp)
391: {
392: if (preserve_perms)
393: return !BITS_EQUAL(sxp->st.st_mode, file->mode, CHMOD_BITS);
394:
395: if (preserve_executability)
396: return (sxp->st.st_mode & 0111 ? 1 : 0) ^ (file->mode & 0111 ? 1 : 0);
397:
398: return 0;
399: }
400:
401: static inline int ownership_differs(struct file_struct *file, stat_x *sxp)
402: {
403: if (am_root && uid_ndx && sxp->st.st_uid != (uid_t)F_OWNER(file))
404: return 1;
405:
406: if (gid_ndx && !(file->flags & FLAG_SKIP_GROUP) && sxp->st.st_gid != (gid_t)F_GROUP(file))
407: return 1;
408:
409: return 0;
410: }
411:
412: #ifdef SUPPORT_ACLS
413: static inline int acls_differ(const char *fname, struct file_struct *file, stat_x *sxp)
414: {
415: if (preserve_acls) {
416: if (!ACL_READY(*sxp))
417: get_acl(fname, sxp);
418: if (set_acl(NULL, file, sxp, file->mode))
419: return 1;
420: }
421:
422: return 0;
423: }
424: #endif
425:
426: #ifdef SUPPORT_XATTRS
427: static inline int xattrs_differ(const char *fname, struct file_struct *file, stat_x *sxp)
428: {
429: if (preserve_xattrs) {
430: if (!XATTR_READY(*sxp))
431: get_xattr(fname, sxp);
432: if (xattr_diff(file, sxp, 0))
433: return 1;
434: }
435:
436: return 0;
437: }
438: #endif
439:
440: int unchanged_attrs(const char *fname, struct file_struct *file, stat_x *sxp)
441: {
442: if (S_ISLNK(file->mode)) {
443: #ifdef CAN_SET_SYMLINK_TIMES
444: if (preserve_times & PRESERVE_LINK_TIMES && time_differs(file, sxp))
445: return 0;
446: #endif
447: #ifdef CAN_CHMOD_SYMLINK
448: if (perms_differ(file, sxp))
449: return 0;
450: #endif
451: #ifdef CAN_CHOWN_SYMLINK
452: if (ownership_differs(file, sxp))
453: return 0;
454: #endif
455: #if defined SUPPORT_ACLS && 0 /* no current symlink-ACL support */
456: if (acls_differ(fname, file, sxp))
457: return 0;
458: #endif
459: #if defined SUPPORT_XATTRS && !defined NO_SYMLINK_XATTRS
460: if (xattrs_differ(fname, file, sxp))
461: return 0;
462: #endif
463: } else {
464: if (preserve_times && time_differs(file, sxp))
465: return 0;
466: if (perms_differ(file, sxp))
467: return 0;
468: if (ownership_differs(file, sxp))
469: return 0;
470: #ifdef SUPPORT_ACLS
471: if (acls_differ(fname, file, sxp))
472: return 0;
473: #endif
474: #ifdef SUPPORT_XATTRS
475: if (xattrs_differ(fname, file, sxp))
476: return 0;
477: #endif
478: }
479:
480: return 1;
481: }
482:
483: void itemize(const char *fnamecmp, struct file_struct *file, int ndx, int statret,
484: stat_x *sxp, int32 iflags, uchar fnamecmp_type,
485: const char *xname)
486: {
487: if (statret >= 0) { /* A from-dest-dir statret can == 1! */
488: int keep_time = !preserve_times ? 0
489: : S_ISDIR(file->mode) ? preserve_times & PRESERVE_DIR_TIMES
490: : S_ISLNK(file->mode) ? preserve_times & PRESERVE_LINK_TIMES
491: : 1;
492:
493: if (S_ISREG(file->mode) && F_LENGTH(file) != sxp->st.st_size)
494: iflags |= ITEM_REPORT_SIZE;
495: if (file->flags & FLAG_TIME_FAILED) { /* symlinks only */
496: if (iflags & ITEM_LOCAL_CHANGE)
497: iflags |= symlink_timeset_failed_flags;
498: } else if (keep_time
499: ? cmp_time(file->modtime, sxp->st.st_mtime) != 0
500: : iflags & (ITEM_TRANSFER|ITEM_LOCAL_CHANGE) && !(iflags & ITEM_MATCHED)
501: && (!(iflags & ITEM_XNAME_FOLLOWS) || *xname))
502: iflags |= ITEM_REPORT_TIME;
503: #if !defined HAVE_LCHMOD && !defined HAVE_SETATTRLIST
504: if (S_ISLNK(file->mode)) {
505: ;
506: } else
507: #endif
508: if (preserve_perms) {
509: if (!BITS_EQUAL(sxp->st.st_mode, file->mode, CHMOD_BITS))
510: iflags |= ITEM_REPORT_PERMS;
511: } else if (preserve_executability
512: && ((sxp->st.st_mode & 0111 ? 1 : 0) ^ (file->mode & 0111 ? 1 : 0)))
513: iflags |= ITEM_REPORT_PERMS;
514: if (uid_ndx && am_root && (uid_t)F_OWNER(file) != sxp->st.st_uid)
515: iflags |= ITEM_REPORT_OWNER;
516: if (gid_ndx && !(file->flags & FLAG_SKIP_GROUP)
517: && sxp->st.st_gid != (gid_t)F_GROUP(file))
518: iflags |= ITEM_REPORT_GROUP;
519: #ifdef SUPPORT_ACLS
520: if (preserve_acls && !S_ISLNK(file->mode)) {
521: if (!ACL_READY(*sxp))
522: get_acl(fnamecmp, sxp);
523: if (set_acl(NULL, file, sxp, file->mode))
524: iflags |= ITEM_REPORT_ACL;
525: }
526: #endif
527: #ifdef SUPPORT_XATTRS
528: if (preserve_xattrs) {
529: if (!XATTR_READY(*sxp))
530: get_xattr(fnamecmp, sxp);
531: if (xattr_diff(file, sxp, 1))
532: iflags |= ITEM_REPORT_XATTR;
533: }
534: #endif
535: } else {
536: #ifdef SUPPORT_XATTRS
537: if (preserve_xattrs && xattr_diff(file, NULL, 1))
538: iflags |= ITEM_REPORT_XATTR;
539: #endif
540: iflags |= ITEM_IS_NEW;
541: }
542:
543: iflags &= 0xffff;
544: if ((iflags & (SIGNIFICANT_ITEM_FLAGS|ITEM_REPORT_XATTR) || INFO_GTE(NAME, 2)
545: || stdout_format_has_i > 1 || (xname && *xname)) && !read_batch) {
546: if (protocol_version >= 29) {
547: if (ndx >= 0)
548: write_ndx(sock_f_out, ndx);
549: write_shortint(sock_f_out, iflags);
550: if (iflags & ITEM_BASIS_TYPE_FOLLOWS)
551: write_byte(sock_f_out, fnamecmp_type);
552: if (iflags & ITEM_XNAME_FOLLOWS)
553: write_vstring(sock_f_out, xname, strlen(xname));
554: #ifdef SUPPORT_XATTRS
555: if (preserve_xattrs && do_xfers
556: && iflags & (ITEM_REPORT_XATTR|ITEM_TRANSFER)) {
557: int fd = iflags & ITEM_REPORT_XATTR
558: && !(want_xattr_optim && BITS_SET(iflags, ITEM_XNAME_FOLLOWS|ITEM_LOCAL_CHANGE))
559: ? sock_f_out : -1;
560: send_xattr_request(NULL, file, fd);
561: }
562: #endif
563: } else if (ndx >= 0) {
564: enum logcode code = logfile_format_has_i ? FINFO : FCLIENT;
565: log_item(code, file, iflags, xname);
566: }
567: }
568: }
569:
570:
571: /* Perform our quick-check heuristic for determining if a file is unchanged. */
572: int unchanged_file(char *fn, struct file_struct *file, STRUCT_STAT *st)
573: {
574: if (st->st_size != F_LENGTH(file))
575: return 0;
576:
577: /* if always checksum is set then we use the checksum instead
578: of the file time to determine whether to sync */
579: if (always_checksum > 0 && S_ISREG(st->st_mode)) {
580: char sum[MAX_DIGEST_LEN];
581: file_checksum(fn, st, sum);
582: return memcmp(sum, F_SUM(file), checksum_len) == 0;
583: }
584:
585: if (size_only > 0)
586: return 1;
587:
588: if (ignore_times)
589: return 0;
590:
591: return cmp_time(st->st_mtime, file->modtime) == 0;
592: }
593:
594:
595: /*
596: * set (initialize) the size entries in the per-file sum_struct
597: * calculating dynamic block and checksum sizes.
598: *
599: * This is only called from generate_and_send_sums() but is a separate
600: * function to encapsulate the logic.
601: *
602: * The block size is a rounded square root of file length.
603: *
604: * The checksum size is determined according to:
605: * blocksum_bits = BLOCKSUM_BIAS + 2*log2(file_len) - log2(block_len)
606: * provided by Donovan Baarda which gives a probability of rsync
607: * algorithm corrupting data and falling back using the whole md4
608: * checksums.
609: *
610: * This might be made one of several selectable heuristics.
611: */
612: static void sum_sizes_sqroot(struct sum_struct *sum, int64 len)
613: {
614: int32 blength;
615: int s2length;
616: int64 l;
617:
618: if (len < 0) {
619: /* The file length overflowed our int64 var, so we can't process this file. */
620: sum->count = -1; /* indicate overflow error */
621: return;
622: }
623:
624: if (block_size)
625: blength = block_size;
626: else if (len <= BLOCK_SIZE * BLOCK_SIZE)
627: blength = BLOCK_SIZE;
628: else {
629: int32 max_blength = protocol_version < 30 ? OLD_MAX_BLOCK_SIZE : MAX_BLOCK_SIZE;
630: int32 c;
631: int cnt;
632: for (c = 1, l = len, cnt = 0; l >>= 2; c <<= 1, cnt++) {}
633: if (c < 0 || c >= max_blength)
634: blength = max_blength;
635: else {
636: blength = 0;
637: do {
638: blength |= c;
639: if (len < (int64)blength * blength)
640: blength &= ~c;
641: c >>= 1;
642: } while (c >= 8); /* round to multiple of 8 */
643: blength = MAX(blength, BLOCK_SIZE);
644: }
645: }
646:
647: if (protocol_version < 27) {
648: s2length = csum_length;
649: } else if (csum_length == SUM_LENGTH) {
650: s2length = SUM_LENGTH;
651: } else {
652: int32 c;
653: int b = BLOCKSUM_BIAS;
654: for (l = len; l >>= 1; b += 2) {}
655: for (c = blength; (c >>= 1) && b; b--) {}
656: /* add a bit, subtract rollsum, round up. */
657: s2length = (b + 1 - 32 + 7) / 8; /* --optimize in compiler-- */
658: s2length = MAX(s2length, csum_length);
659: s2length = MIN(s2length, SUM_LENGTH);
660: }
661:
662: sum->flength = len;
663: sum->blength = blength;
664: sum->s2length = s2length;
665: sum->remainder = (int32)(len % blength);
666: sum->count = (int32)(l = (len / blength) + (sum->remainder != 0));
667:
668: if ((int64)sum->count != l)
669: sum->count = -1;
670:
671: if (sum->count && DEBUG_GTE(DELTASUM, 2)) {
672: rprintf(FINFO,
673: "count=%s rem=%ld blength=%ld s2length=%d flength=%s\n",
674: big_num(sum->count), (long)sum->remainder, (long)sum->blength,
675: sum->s2length, big_num(sum->flength));
676: }
677: }
678:
679:
680: /*
681: * Generate and send a stream of signatures/checksums that describe a buffer
682: *
683: * Generate approximately one checksum every block_len bytes.
684: */
685: static int generate_and_send_sums(int fd, OFF_T len, int f_out, int f_copy)
686: {
687: int32 i;
688: struct map_struct *mapbuf;
689: struct sum_struct sum;
690: OFF_T offset = 0;
691:
692: sum_sizes_sqroot(&sum, len);
693: if (sum.count < 0)
694: return -1;
695: write_sum_head(f_out, &sum);
696:
697: if (append_mode > 0 && f_copy < 0)
698: return 0;
699:
700: if (len > 0)
701: mapbuf = map_file(fd, len, MAX_MAP_SIZE, sum.blength);
702: else
703: mapbuf = NULL;
704:
705: for (i = 0; i < sum.count; i++) {
706: int32 n1 = (int32)MIN(len, (OFF_T)sum.blength);
707: char *map = map_ptr(mapbuf, offset, n1);
708: char sum2[SUM_LENGTH];
709: uint32 sum1;
710:
711: len -= n1;
712: offset += n1;
713:
714: if (f_copy >= 0) {
715: full_write(f_copy, map, n1);
716: if (append_mode > 0)
717: continue;
718: }
719:
720: sum1 = get_checksum1(map, n1);
721: get_checksum2(map, n1, sum2);
722:
723: if (DEBUG_GTE(DELTASUM, 3)) {
724: rprintf(FINFO,
725: "chunk[%s] offset=%s len=%ld sum1=%08lx\n",
726: big_num(i), big_num(offset - n1), (long)n1,
727: (unsigned long)sum1);
728: }
729: write_int(f_out, sum1);
730: write_buf(f_out, sum2, sum.s2length);
731: }
732:
733: if (mapbuf)
734: unmap_file(mapbuf);
735:
736: return 0;
737: }
738:
739:
740: /* Try to find a filename in the same dir as "fname" with a similar name. */
741: static struct file_struct *find_fuzzy(struct file_struct *file, struct file_list *dirlist_array[], uchar *fnamecmp_type_ptr)
742: {
743: int fname_len, fname_suf_len;
744: const char *fname_suf, *fname = file->basename;
745: uint32 lowest_dist = 25 << 16; /* ignore a distance greater than 25 */
746: int i, j;
747: struct file_struct *lowest_fp = NULL;
748:
749: fname_len = strlen(fname);
750: fname_suf = find_filename_suffix(fname, fname_len, &fname_suf_len);
751:
752: /* Try to find an exact size+mtime match first. */
753: for (i = 0; i < fuzzy_basis; i++) {
754: struct file_list *dirlist = dirlist_array[i];
755:
756: if (!dirlist)
757: continue;
758:
759: for (j = 0; j < dirlist->used; j++) {
760: struct file_struct *fp = dirlist->files[j];
761:
762: if (!F_IS_ACTIVE(fp))
763: continue;
764:
765: if (!S_ISREG(fp->mode) || !F_LENGTH(fp) || fp->flags & FLAG_FILE_SENT)
766: continue;
767:
768: if (F_LENGTH(fp) == F_LENGTH(file) && cmp_time(fp->modtime, file->modtime) == 0) {
769: if (DEBUG_GTE(FUZZY, 2))
770: rprintf(FINFO, "fuzzy size/modtime match for %s\n", f_name(fp, NULL));
771: *fnamecmp_type_ptr = FNAMECMP_FUZZY + i;
772: return fp;
773: }
774:
775: }
776: }
777:
778: for (i = 0; i < fuzzy_basis; i++) {
779: struct file_list *dirlist = dirlist_array[i];
780:
781: if (!dirlist)
782: continue;
783:
784: for (j = 0; j < dirlist->used; j++) {
785: struct file_struct *fp = dirlist->files[j];
786: const char *suf, *name;
787: int len, suf_len;
788: uint32 dist;
789:
790: if (!F_IS_ACTIVE(fp))
791: continue;
792:
793: if (!S_ISREG(fp->mode) || !F_LENGTH(fp) || fp->flags & FLAG_FILE_SENT)
794: continue;
795:
796: name = fp->basename;
797: len = strlen(name);
798: suf = find_filename_suffix(name, len, &suf_len);
799:
800: dist = fuzzy_distance(name, len, fname, fname_len);
801: /* Add some extra weight to how well the suffixes match. */
802: dist += fuzzy_distance(suf, suf_len, fname_suf, fname_suf_len) * 10;
803: if (DEBUG_GTE(FUZZY, 2)) {
804: rprintf(FINFO, "fuzzy distance for %s = %d.%05d\n",
805: f_name(fp, NULL), (int)(dist>>16), (int)(dist&0xFFFF));
806: }
807: if (dist <= lowest_dist) {
808: lowest_dist = dist;
809: lowest_fp = fp;
810: *fnamecmp_type_ptr = FNAMECMP_FUZZY + i;
811: }
812: }
813: }
814:
815: return lowest_fp;
816: }
817:
818: /* Copy a file found in our --copy-dest handling. */
819: static int copy_altdest_file(const char *src, const char *dest, struct file_struct *file)
820: {
821: char buf[MAXPATHLEN];
822: const char *copy_to, *partialptr;
823: int save_preserve_xattrs = preserve_xattrs;
824: int ok, fd_w;
825:
826: if (inplace) {
827: /* Let copy_file open the destination in place. */
828: fd_w = -1;
829: copy_to = dest;
830: } else {
831: fd_w = open_tmpfile(buf, dest, file);
832: if (fd_w < 0)
833: return -1;
834: copy_to = buf;
835: }
836: cleanup_set(copy_to, NULL, NULL, -1, -1);
837: if (copy_file(src, copy_to, fd_w, file->mode) < 0) {
838: if (INFO_GTE(COPY, 1)) {
839: rsyserr(FINFO, errno, "copy_file %s => %s",
840: full_fname(src), copy_to);
841: }
842: /* Try to clean up. */
843: unlink(copy_to);
844: cleanup_disable();
845: return -1;
846: }
847: partialptr = partial_dir ? partial_dir_fname(dest) : NULL;
848: preserve_xattrs = 0; /* xattrs were copied with file */
849: ok = finish_transfer(dest, copy_to, src, partialptr, file, 1, 0);
850: preserve_xattrs = save_preserve_xattrs;
851: cleanup_disable();
852: return ok ? 0 : -1;
853: }
854:
855: /* This is only called for regular files. We return -2 if we've finished
856: * handling the file, -1 if no dest-linking occurred, or a non-negative
857: * value if we found an alternate basis file. If we're called with the
858: * find_exact_for_existing flag, the destination file already exists, so
859: * we only try to find an exact alt-dest match. In this case, the returns
860: * are only -2 & -1 (both as above). */
861: static int try_dests_reg(struct file_struct *file, char *fname, int ndx,
862: char *cmpbuf, stat_x *sxp, int find_exact_for_existing,
863: int itemizing, enum logcode code)
864: {
865: STRUCT_STAT real_st = sxp->st;
866: int best_match = -1;
867: int match_level = 0;
868: int j = 0;
869:
870: do {
871: pathjoin(cmpbuf, MAXPATHLEN, basis_dir[j], fname);
872: if (link_stat(cmpbuf, &sxp->st, 0) < 0 || !S_ISREG(sxp->st.st_mode))
873: continue;
874: switch (match_level) {
875: case 0:
876: best_match = j;
877: match_level = 1;
878: /* FALL THROUGH */
879: case 1:
880: if (!unchanged_file(cmpbuf, file, &sxp->st))
881: continue;
882: best_match = j;
883: match_level = 2;
884: /* FALL THROUGH */
885: case 2:
886: if (!unchanged_attrs(cmpbuf, file, sxp)) {
887: free_stat_x(sxp);
888: continue;
889: }
890: best_match = j;
891: match_level = 3;
892: break;
893: }
894: break;
895: } while (basis_dir[++j] != NULL);
896:
897: if (!match_level)
898: goto got_nothing_for_ya;
899:
900: if (j != best_match) {
901: j = best_match;
902: pathjoin(cmpbuf, MAXPATHLEN, basis_dir[j], fname);
903: if (link_stat(cmpbuf, &sxp->st, 0) < 0)
904: goto got_nothing_for_ya;
905: }
906:
907: if (match_level == 3 && !copy_dest) {
908: if (find_exact_for_existing) {
909: if (link_dest && real_st.st_dev == sxp->st.st_dev && real_st.st_ino == sxp->st.st_ino)
910: return -1;
911: if (do_unlink(fname) < 0 && errno != ENOENT)
912: goto got_nothing_for_ya;
913: }
914: #ifdef SUPPORT_HARD_LINKS
915: if (link_dest) {
916: if (!hard_link_one(file, fname, cmpbuf, 1))
917: goto try_a_copy;
918: if (preserve_hard_links && F_IS_HLINKED(file))
919: finish_hard_link(file, fname, ndx, &sxp->st, itemizing, code, j);
920: if (!maybe_ATTRS_REPORT && (INFO_GTE(NAME, 2) || stdout_format_has_i > 1)) {
921: itemize(cmpbuf, file, ndx, 1, sxp,
922: ITEM_LOCAL_CHANGE | ITEM_XNAME_FOLLOWS,
923: 0, "");
924: }
925: } else
926: #endif
927: {
928: if (itemizing)
929: itemize(cmpbuf, file, ndx, 0, sxp, 0, 0, NULL);
930: }
931: if (INFO_GTE(NAME, 2) && maybe_ATTRS_REPORT)
932: rprintf(FCLIENT, "%s is uptodate\n", fname);
933: return -2;
934: }
935:
936: if (find_exact_for_existing)
937: goto got_nothing_for_ya;
938:
939: if (match_level >= 2) {
940: #ifdef SUPPORT_HARD_LINKS
941: try_a_copy: /* Copy the file locally. */
942: #endif
943: if (!dry_run && copy_altdest_file(cmpbuf, fname, file) < 0) {
944: if (find_exact_for_existing) /* Can get here via hard-link failure */
945: goto got_nothing_for_ya;
946: return -1;
947: }
948: if (itemizing)
949: itemize(cmpbuf, file, ndx, 0, sxp, ITEM_LOCAL_CHANGE, 0, NULL);
950: if (maybe_ATTRS_REPORT
951: && ((!itemizing && INFO_GTE(NAME, 1) && match_level == 2)
952: || (INFO_GTE(NAME, 2) && match_level == 3))) {
953: code = match_level == 3 ? FCLIENT : FINFO;
954: rprintf(code, "%s%s\n", fname,
955: match_level == 3 ? " is uptodate" : "");
956: }
957: #ifdef SUPPORT_HARD_LINKS
958: if (preserve_hard_links && F_IS_HLINKED(file))
959: finish_hard_link(file, fname, ndx, &sxp->st, itemizing, code, -1);
960: #endif
961: return -2;
962: }
963:
964: return FNAMECMP_BASIS_DIR_LOW + j;
965:
966: got_nothing_for_ya:
967: sxp->st = real_st;
968: return -1;
969: }
970:
971: /* This is only called for non-regular files. We return -2 if we've finished
972: * handling the file, or -1 if no dest-linking occurred, or a non-negative
973: * value if we found an alternate basis file. */
974: static int try_dests_non(struct file_struct *file, char *fname, int ndx,
975: char *cmpbuf, stat_x *sxp, int itemizing,
976: enum logcode code)
977: {
978: int best_match = -1;
979: int match_level = 0;
980: enum nonregtype type;
981: uint32 *devp;
982: #ifdef SUPPORT_LINKS
983: char lnk[MAXPATHLEN];
984: int len;
985: #endif
986: int j = 0;
987:
988: #ifndef SUPPORT_LINKS
989: if (S_ISLNK(file->mode))
990: return -1;
991: #endif
992: if (S_ISDIR(file->mode)) {
993: type = TYPE_DIR;
994: } else if (IS_SPECIAL(file->mode))
995: type = TYPE_SPECIAL;
996: else if (IS_DEVICE(file->mode))
997: type = TYPE_DEVICE;
998: #ifdef SUPPORT_LINKS
999: else if (S_ISLNK(file->mode))
1000: type = TYPE_SYMLINK;
1001: #endif
1002: else {
1003: rprintf(FERROR,
1004: "internal: try_dests_non() called with invalid mode (%o)\n",
1005: (int)file->mode);
1006: exit_cleanup(RERR_UNSUPPORTED);
1007: }
1008:
1009: do {
1010: pathjoin(cmpbuf, MAXPATHLEN, basis_dir[j], fname);
1011: if (link_stat(cmpbuf, &sxp->st, 0) < 0)
1012: continue;
1013: switch (type) {
1014: case TYPE_DIR:
1015: if (!S_ISDIR(sxp->st.st_mode))
1016: continue;
1017: break;
1018: case TYPE_SPECIAL:
1019: if (!IS_SPECIAL(sxp->st.st_mode))
1020: continue;
1021: break;
1022: case TYPE_DEVICE:
1023: if (!IS_DEVICE(sxp->st.st_mode))
1024: continue;
1025: break;
1026: case TYPE_SYMLINK:
1027: #ifdef SUPPORT_LINKS
1028: if (!S_ISLNK(sxp->st.st_mode))
1029: continue;
1030: break;
1031: #else
1032: return -1;
1033: #endif
1034: }
1035: if (match_level < 1) {
1036: match_level = 1;
1037: best_match = j;
1038: }
1039: switch (type) {
1040: case TYPE_DIR:
1041: case TYPE_SPECIAL:
1042: break;
1043: case TYPE_DEVICE:
1044: devp = F_RDEV_P(file);
1045: if (sxp->st.st_rdev != MAKEDEV(DEV_MAJOR(devp), DEV_MINOR(devp)))
1046: continue;
1047: break;
1048: case TYPE_SYMLINK:
1049: #ifdef SUPPORT_LINKS
1050: if ((len = do_readlink(cmpbuf, lnk, MAXPATHLEN-1)) <= 0)
1051: continue;
1052: lnk[len] = '\0';
1053: if (strcmp(lnk, F_SYMLINK(file)) != 0)
1054: continue;
1055: break;
1056: #else
1057: return -1;
1058: #endif
1059: }
1060: if (match_level < 2) {
1061: match_level = 2;
1062: best_match = j;
1063: }
1064: if (unchanged_attrs(cmpbuf, file, sxp)) {
1065: match_level = 3;
1066: best_match = j;
1067: break;
1068: }
1069: } while (basis_dir[++j] != NULL);
1070:
1071: if (!match_level)
1072: return -1;
1073:
1074: if (j != best_match) {
1075: j = best_match;
1076: pathjoin(cmpbuf, MAXPATHLEN, basis_dir[j], fname);
1077: if (link_stat(cmpbuf, &sxp->st, 0) < 0)
1078: return -1;
1079: }
1080:
1081: if (match_level == 3) {
1082: #ifdef SUPPORT_HARD_LINKS
1083: if (link_dest
1084: #ifndef CAN_HARDLINK_SYMLINK
1085: && !S_ISLNK(file->mode)
1086: #endif
1087: #ifndef CAN_HARDLINK_SPECIAL
1088: && !IS_SPECIAL(file->mode) && !IS_DEVICE(file->mode)
1089: #endif
1090: && !S_ISDIR(file->mode)) {
1091: if (do_link(cmpbuf, fname) < 0) {
1092: rsyserr(FERROR_XFER, errno,
1093: "failed to hard-link %s with %s",
1094: cmpbuf, fname);
1095: return j;
1096: }
1097: if (preserve_hard_links && F_IS_HLINKED(file))
1098: finish_hard_link(file, fname, ndx, NULL, itemizing, code, -1);
1099: } else
1100: #endif
1101: match_level = 2;
1102: if (itemizing && stdout_format_has_i
1103: && (INFO_GTE(NAME, 2) || stdout_format_has_i > 1)) {
1104: int chg = compare_dest && type != TYPE_DIR ? 0
1105: : ITEM_LOCAL_CHANGE + (match_level == 3 ? ITEM_XNAME_FOLLOWS : 0);
1106: char *lp = match_level == 3 ? "" : NULL;
1107: itemize(cmpbuf, file, ndx, 0, sxp, chg + ITEM_MATCHED, 0, lp);
1108: }
1109: if (INFO_GTE(NAME, 2) && maybe_ATTRS_REPORT) {
1110: rprintf(FCLIENT, "%s%s is uptodate\n",
1111: fname, type == TYPE_DIR ? "/" : "");
1112: }
1113: return -2;
1114: }
1115:
1116: return j;
1117: }
1118:
1119: static void list_file_entry(struct file_struct *f)
1120: {
1121: char permbuf[PERMSTRING_SIZE];
1122: int64 len;
1123: int colwidth = human_readable ? 14 : 11;
1124:
1125: if (!F_IS_ACTIVE(f)) {
1126: /* this can happen if duplicate names were removed */
1127: return;
1128: }
1129:
1130: permstring(permbuf, f->mode);
1131: len = F_LENGTH(f);
1132:
1133: /* TODO: indicate '+' if the entry has an ACL. */
1134:
1135: #ifdef SUPPORT_LINKS
1136: if (preserve_links && S_ISLNK(f->mode)) {
1137: rprintf(FINFO, "%s %*s %s %s -> %s\n",
1138: permbuf, colwidth, human_num(len),
1139: timestring(f->modtime), f_name(f, NULL),
1140: F_SYMLINK(f));
1141: } else
1142: #endif
1143: if (missing_args == 2 && f->mode == 0) {
1144: rprintf(FINFO, "%-*s %s\n",
1145: colwidth + 31, "*missing",
1146: f_name(f, NULL));
1147: } else {
1148: rprintf(FINFO, "%s %*s %s %s\n",
1149: permbuf, colwidth, human_num(len),
1150: timestring(f->modtime), f_name(f, NULL));
1151: }
1152: }
1153:
1154: static int phase = 0;
1155: static int dflt_perms;
1156:
1157: static int implied_dirs_are_missing;
1158: /* Helper for recv_generator's skip_dir and dry_missing_dir tests. */
1159: static BOOL is_below(struct file_struct *file, struct file_struct *subtree)
1160: {
1161: return F_DEPTH(file) > F_DEPTH(subtree)
1162: && (!implied_dirs_are_missing || f_name_has_prefix(file, subtree));
1163: }
1164:
1165: /* Acts on the indicated item in cur_flist whose name is fname. If a dir,
1166: * make sure it exists, and has the right permissions/timestamp info. For
1167: * all other non-regular files (symlinks, etc.) we create them here. For
1168: * regular files that have changed, we try to find a basis file and then
1169: * start sending checksums. The ndx is the file's unique index value.
1170: *
1171: * The fname parameter must point to a MAXPATHLEN buffer! (e.g it gets
1172: * passed to delete_item(), which can use it during a recursive delete.)
1173: *
1174: * Note that f_out is set to -1 when doing final directory-permission and
1175: * modification-time repair. */
1176: static void recv_generator(char *fname, struct file_struct *file, int ndx,
1177: int itemizing, enum logcode code, int f_out)
1178: {
1179: static const char *parent_dirname = "";
1180: static struct file_struct *prior_dir_file = NULL;
1181: /* Missing dir not created due to --dry-run; will still be scanned. */
1182: static struct file_struct *dry_missing_dir = NULL;
1183: /* Missing dir whose contents are skipped altogether due to
1184: * --ignore-non-existing, daemon exclude, or mkdir failure. */
1185: static struct file_struct *skip_dir = NULL;
1186: static struct file_list *fuzzy_dirlist[MAX_BASIS_DIRS+1];
1187: static int need_fuzzy_dirlist = 0;
1188: struct file_struct *fuzzy_file = NULL;
1189: int fd = -1, f_copy = -1;
1190: stat_x sx, real_sx;
1191: STRUCT_STAT partial_st;
1192: struct file_struct *back_file = NULL;
1193: int statret, real_ret, stat_errno;
1194: char *fnamecmp, *partialptr, *backupptr = NULL;
1195: char fnamecmpbuf[MAXPATHLEN];
1196: uchar fnamecmp_type;
1197: int del_opts = delete_mode || force_delete ? DEL_RECURSE : 0;
1198: int is_dir = !S_ISDIR(file->mode) ? 0
1199: : inc_recurse && ndx != cur_flist->ndx_start - 1 ? -1
1200: : 1;
1201:
1202: if (DEBUG_GTE(GENR, 1))
1203: rprintf(FINFO, "recv_generator(%s,%d)\n", fname, ndx);
1204:
1205: if (list_only) {
1206: if (is_dir < 0
1207: || (is_dir && !implied_dirs && file->flags & FLAG_IMPLIED_DIR))
1208: return;
1209: list_file_entry(file);
1210: return;
1211: }
1212:
1213: if (skip_dir) {
1214: if (is_below(file, skip_dir)) {
1215: if (is_dir)
1216: file->flags |= FLAG_MISSING_DIR;
1217: #ifdef SUPPORT_HARD_LINKS
1218: else if (F_IS_HLINKED(file))
1219: handle_skipped_hlink(file, itemizing, code, f_out);
1220: #endif
1221: return;
1222: }
1223: skip_dir = NULL;
1224: }
1225:
1226: init_stat_x(&sx);
1227: if (daemon_filter_list.head && (*fname != '.' || fname[1])) {
1228: if (check_filter(&daemon_filter_list, FLOG, fname, is_dir) < 0) {
1229: if (is_dir < 0)
1230: return;
1231: #ifdef SUPPORT_HARD_LINKS
1232: if (F_IS_HLINKED(file))
1233: handle_skipped_hlink(file, itemizing, code, f_out);
1234: #endif
1235: rprintf(FERROR_XFER,
1236: "ERROR: daemon refused to receive %s \"%s\"\n",
1237: is_dir ? "directory" : "file", fname);
1238: if (is_dir)
1239: goto skipping_dir_contents;
1240: return;
1241: }
1242: }
1243:
1244: if (dry_run > 1 || (dry_missing_dir && is_below(file, dry_missing_dir))) {
1245: int i;
1246: parent_is_dry_missing:
1247: for (i = 0; i < fuzzy_basis; i++) {
1248: if (fuzzy_dirlist[i]) {
1249: flist_free(fuzzy_dirlist[i]);
1250: fuzzy_dirlist[i] = NULL;
1251: }
1252: }
1253: parent_dirname = "";
1254: statret = -1;
1255: stat_errno = ENOENT;
1256: } else {
1257: const char *dn = file->dirname ? file->dirname : ".";
1258: dry_missing_dir = NULL;
1259: if (parent_dirname != dn && strcmp(parent_dirname, dn) != 0) {
1260: /* Each parent dir must be in the file list or the flist data is bad.
1261: * Optimization: most of the time the parent dir will be the last dir
1262: * this function was asked to process in the file list. */
1263: if (!inc_recurse
1264: && (*dn != '.' || dn[1]) /* Avoid an issue with --relative and the "." dir. */
1265: && (prior_dir_file && strcmp(dn, f_name(prior_dir_file, NULL)) != 0)
1266: && flist_find_name(cur_flist, dn, 1) < 0) {
1267: rprintf(FERROR,
1268: "ABORTING due to invalid path from sender: %s/%s\n",
1269: dn, file->basename);
1270: exit_cleanup(RERR_PROTOCOL);
1271: }
1272: if (relative_paths && !implied_dirs
1273: && do_stat(dn, &sx.st) < 0) {
1274: if (dry_run)
1275: goto parent_is_dry_missing;
1276: if (make_path(fname, MKP_DROP_NAME | MKP_SKIP_SLASH) < 0) {
1277: rsyserr(FERROR_XFER, errno,
1278: "recv_generator: mkdir %s failed",
1279: full_fname(dn));
1280: }
1281: }
1282: if (fuzzy_basis) {
1283: int i;
1284: for (i = 0; i < fuzzy_basis; i++) {
1285: if (fuzzy_dirlist[i]) {
1286: flist_free(fuzzy_dirlist[i]);
1287: fuzzy_dirlist[i] = NULL;
1288: }
1289: }
1290: need_fuzzy_dirlist = 1;
1291: }
1292: #ifdef SUPPORT_ACLS
1293: if (!preserve_perms)
1294: dflt_perms = default_perms_for_dir(dn);
1295: #endif
1296: }
1297: parent_dirname = dn;
1298:
1299: if (need_fuzzy_dirlist && S_ISREG(file->mode)) {
1300: int i;
1301: strlcpy(fnamecmpbuf, dn, sizeof fnamecmpbuf);
1302: for (i = 0; i < fuzzy_basis; i++) {
1303: if (i && pathjoin(fnamecmpbuf, MAXPATHLEN, basis_dir[i-1], dn) >= MAXPATHLEN)
1304: continue;
1305: fuzzy_dirlist[i] = get_dirlist(fnamecmpbuf, -1, GDL_IGNORE_FILTER_RULES);
1306: if (fuzzy_dirlist[i] && fuzzy_dirlist[i]->used == 0) {
1307: flist_free(fuzzy_dirlist[i]);
1308: fuzzy_dirlist[i] = NULL;
1309: }
1310: }
1311: need_fuzzy_dirlist = 0;
1312: }
1313:
1314: statret = link_stat(fname, &sx.st, keep_dirlinks && is_dir);
1315: stat_errno = errno;
1316: }
1317:
1318: if (missing_args == 2 && file->mode == 0) {
1319: if (filter_list.head && check_filter(&filter_list, FINFO, fname, is_dir) < 0)
1320: return;
1321: if (statret == 0)
1322: delete_item(fname, sx.st.st_mode, del_opts);
1323: return;
1324: }
1325:
1326: if (ignore_non_existing > 0 && statret == -1 && stat_errno == ENOENT) {
1327: if (is_dir) {
1328: if (is_dir < 0)
1329: return;
1330: skip_dir = file;
1331: file->flags |= FLAG_MISSING_DIR;
1332: }
1333: #ifdef SUPPORT_HARD_LINKS
1334: else if (F_IS_HLINKED(file))
1335: handle_skipped_hlink(file, itemizing, code, f_out);
1336: #endif
1337: if (INFO_GTE(SKIP, 1)) {
1338: rprintf(FINFO, "not creating new %s \"%s\"\n",
1339: is_dir ? "directory" : "file", fname);
1340: }
1341: return;
1342: }
1343:
1344: if (statret == 0 && !(sx.st.st_mode & S_IWUSR)
1345: && !am_root && sx.st.st_uid == our_uid)
1346: del_opts |= DEL_NO_UID_WRITE;
1347:
1348: if (ignore_existing > 0 && statret == 0
1349: && (!is_dir || !S_ISDIR(sx.st.st_mode))) {
1350: if (INFO_GTE(SKIP, 1) && is_dir >= 0)
1351: rprintf(FINFO, "%s exists\n", fname);
1352: #ifdef SUPPORT_HARD_LINKS
1353: if (F_IS_HLINKED(file))
1354: handle_skipped_hlink(file, itemizing, code, f_out);
1355: #endif
1356: goto cleanup;
1357: }
1358:
1359: fnamecmp = fname;
1360:
1361: if (is_dir) {
1362: mode_t added_perms;
1363: if (!implied_dirs && file->flags & FLAG_IMPLIED_DIR)
1364: goto cleanup;
1365: if (am_root < 0) {
1366: /* For --fake-super, the dir must be useable by the copying
1367: * user, just like it would be for root. */
1368: added_perms = S_IRUSR|S_IWUSR|S_IXUSR;
1369: } else
1370: added_perms = 0;
1371: if (is_dir < 0) {
1372: if (!(preserve_times & PRESERVE_DIR_TIMES))
1373: return;
1374: /* In inc_recurse mode we want to make sure any missing
1375: * directories get created while we're still processing
1376: * the parent dir (which allows us to touch the parent
1377: * dir's mtime right away). We will handle the dir in
1378: * full later (right before we handle its contents). */
1379: if (statret == 0
1380: && (S_ISDIR(sx.st.st_mode)
1381: || delete_item(fname, sx.st.st_mode, del_opts | DEL_FOR_DIR) != 0))
1382: goto cleanup; /* Any errors get reported later. */
1383: if (do_mkdir(fname, (file->mode|added_perms) & 0700) == 0)
1384: file->flags |= FLAG_DIR_CREATED;
1385: goto cleanup;
1386: }
1387: /* The file to be received is a directory, so we need
1388: * to prepare appropriately. If there is already a
1389: * file of that name and it is *not* a directory, then
1390: * we need to delete it. If it doesn't exist, then
1391: * (perhaps recursively) create it. */
1392: if (statret == 0 && !S_ISDIR(sx.st.st_mode)) {
1393: if (delete_item(fname, sx.st.st_mode, del_opts | DEL_FOR_DIR) != 0)
1394: goto skipping_dir_contents;
1395: statret = -1;
1396: }
1397: if (dry_run && statret != 0) {
1398: if (!dry_missing_dir)
1399: dry_missing_dir = file;
1400: file->flags |= FLAG_MISSING_DIR;
1401: }
1402: init_stat_x(&real_sx);
1403: real_sx.st = sx.st;
1404: real_ret = statret;
1405: if (file->flags & FLAG_DIR_CREATED)
1406: statret = -1;
1407: if (!preserve_perms) { /* See comment in non-dir code below. */
1408: file->mode = dest_mode(file->mode, sx.st.st_mode,
1409: dflt_perms, statret == 0);
1410: }
1411: if (statret != 0 && basis_dir[0] != NULL) {
1412: int j = try_dests_non(file, fname, ndx, fnamecmpbuf, &sx,
1413: itemizing, code);
1414: if (j == -2) {
1415: itemizing = 0;
1416: code = FNONE;
1417: statret = 1;
1418: } else if (j >= 0) {
1419: statret = 1;
1420: fnamecmp = fnamecmpbuf;
1421: }
1422: }
1423: if (itemizing && f_out != -1) {
1424: itemize(fnamecmp, file, ndx, statret, &sx,
1425: statret ? ITEM_LOCAL_CHANGE : 0, 0, NULL);
1426: }
1427: if (real_ret != 0 && do_mkdir(fname,file->mode|added_perms) < 0 && errno != EEXIST) {
1428: if (!relative_paths || errno != ENOENT
1429: || make_path(fname, MKP_DROP_NAME | MKP_SKIP_SLASH) < 0
1430: || (do_mkdir(fname, file->mode|added_perms) < 0 && errno != EEXIST)) {
1431: rsyserr(FERROR_XFER, errno,
1432: "recv_generator: mkdir %s failed",
1433: full_fname(fname));
1434: skipping_dir_contents:
1435: rprintf(FERROR,
1436: "*** Skipping any contents from this failed directory ***\n");
1437: skip_dir = file;
1438: file->flags |= FLAG_MISSING_DIR;
1439: goto cleanup;
1440: }
1441: }
1442:
1443: #ifdef SUPPORT_XATTRS
1444: if (preserve_xattrs && statret == 1)
1445: copy_xattrs(fnamecmpbuf, fname);
1446: #endif
1447: if (set_file_attrs(fname, file, real_ret ? NULL : &real_sx, NULL, 0)
1448: && INFO_GTE(NAME, 1) && code != FNONE && f_out != -1)
1449: rprintf(code, "%s/\n", fname);
1450:
1451: /* We need to ensure that the dirs in the transfer have both
1452: * readable and writable permissions during the time we are
1453: * putting files within them. This is then restored to the
1454: * former permissions after the transfer is done. */
1455: #ifdef HAVE_CHMOD
1456: if (!am_root && (file->mode & S_IRWXU) != S_IRWXU && dir_tweaking) {
1457: mode_t mode = file->mode | S_IRWXU;
1458: if (do_chmod(fname, mode) < 0) {
1459: rsyserr(FERROR_XFER, errno,
1460: "failed to modify permissions on %s",
1461: full_fname(fname));
1462: }
1463: need_retouch_dir_perms = 1;
1464: }
1465: #endif
1466:
1467: if (real_ret != 0 && one_file_system)
1468: real_sx.st.st_dev = filesystem_dev;
1469: if (inc_recurse) {
1470: if (one_file_system) {
1471: uint32 *devp = F_DIR_DEV_P(file);
1472: DEV_MAJOR(devp) = major(real_sx.st.st_dev);
1473: DEV_MINOR(devp) = minor(real_sx.st.st_dev);
1474: }
1475: }
1476: else if (delete_during && f_out != -1 && !phase
1477: && !(file->flags & FLAG_MISSING_DIR)) {
1478: if (file->flags & FLAG_CONTENT_DIR)
1479: delete_in_dir(fname, file, &real_sx.st.st_dev);
1480: else
1481: change_local_filter_dir(fname, strlen(fname), F_DEPTH(file));
1482: }
1483: prior_dir_file = file;
1484: goto cleanup;
1485: }
1486:
1487: /* If we're not preserving permissions, change the file-list's
1488: * mode based on the local permissions and some heuristics. */
1489: if (!preserve_perms) {
1490: int exists = statret == 0 && !S_ISDIR(sx.st.st_mode);
1491: file->mode = dest_mode(file->mode, sx.st.st_mode, dflt_perms,
1492: exists);
1493: }
1494:
1495: #ifdef SUPPORT_HARD_LINKS
1496: if (preserve_hard_links && F_HLINK_NOT_FIRST(file)
1497: && hard_link_check(file, ndx, fname, statret, &sx, itemizing, code))
1498: goto cleanup;
1499: #endif
1500:
1501: if (preserve_links && S_ISLNK(file->mode)) {
1502: #ifdef SUPPORT_LINKS
1503: const char *sl = F_SYMLINK(file);
1504: if (safe_symlinks && unsafe_symlink(sl, fname)) {
1505: if (INFO_GTE(NAME, 1)) {
1506: if (solo_file) {
1507: /* fname contains the destination path, but we
1508: * want to report the source path. */
1509: fname = f_name(file, NULL);
1510: }
1511: rprintf(FINFO,
1512: "ignoring unsafe symlink \"%s\" -> \"%s\"\n",
1513: fname, sl);
1514: }
1515: return;
1516: }
1517: if (statret == 0) {
1518: char lnk[MAXPATHLEN];
1519: int len;
1520:
1521: if (S_ISLNK(sx.st.st_mode)
1522: && (len = do_readlink(fname, lnk, MAXPATHLEN-1)) > 0
1523: && strncmp(lnk, sl, len) == 0 && sl[len] == '\0') {
1524: /* The link is pointing to the right place. */
1525: set_file_attrs(fname, file, &sx, NULL, maybe_ATTRS_REPORT);
1526: if (itemizing)
1527: itemize(fname, file, ndx, 0, &sx, 0, 0, NULL);
1528: #ifdef SUPPORT_HARD_LINKS
1529: if (preserve_hard_links && F_IS_HLINKED(file))
1530: finish_hard_link(file, fname, ndx, &sx.st, itemizing, code, -1);
1531: #endif
1532: if (remove_source_files == 1)
1533: goto return_with_success;
1534: goto cleanup;
1535: }
1536: } else if (basis_dir[0] != NULL) {
1537: int j = try_dests_non(file, fname, ndx, fnamecmpbuf, &sx,
1538: itemizing, code);
1539: if (j == -2) {
1540: #ifndef CAN_HARDLINK_SYMLINK
1541: if (link_dest) {
1542: /* Resort to --copy-dest behavior. */
1543: } else
1544: #endif
1545: if (!copy_dest)
1546: goto cleanup;
1547: itemizing = 0;
1548: code = FNONE;
1549: } else if (j >= 0) {
1550: statret = 1;
1551: fnamecmp = fnamecmpbuf;
1552: }
1553: }
1554: if (atomic_create(file, fname, sl, NULL, MAKEDEV(0, 0), &sx, statret == 0 ? DEL_FOR_SYMLINK : 0)) {
1555: set_file_attrs(fname, file, NULL, NULL, 0);
1556: if (itemizing) {
1557: if (statret == 0 && !S_ISLNK(sx.st.st_mode))
1558: statret = -1;
1559: itemize(fnamecmp, file, ndx, statret, &sx,
1560: ITEM_LOCAL_CHANGE|ITEM_REPORT_CHANGE, 0, NULL);
1561: }
1562: if (code != FNONE && INFO_GTE(NAME, 1))
1563: rprintf(code, "%s -> %s\n", fname, sl);
1564: #ifdef SUPPORT_HARD_LINKS
1565: if (preserve_hard_links && F_IS_HLINKED(file))
1566: finish_hard_link(file, fname, ndx, NULL, itemizing, code, -1);
1567: #endif
1568: /* This does not check remove_source_files == 1
1569: * because this is one of the items that the old
1570: * --remove-sent-files option would remove. */
1571: if (remove_source_files)
1572: goto return_with_success;
1573: }
1574: #endif
1575: goto cleanup;
1576: }
1577:
1578: if ((am_root && preserve_devices && IS_DEVICE(file->mode))
1579: || (preserve_specials && IS_SPECIAL(file->mode))) {
1580: dev_t rdev;
1581: int del_for_flag = 0;
1582: if (IS_DEVICE(file->mode)) {
1583: uint32 *devp = F_RDEV_P(file);
1584: rdev = MAKEDEV(DEV_MAJOR(devp), DEV_MINOR(devp));
1585: } else
1586: rdev = 0;
1587: if (statret == 0) {
1588: if (IS_DEVICE(file->mode)) {
1589: if (!IS_DEVICE(sx.st.st_mode))
1590: statret = -1;
1591: del_for_flag = DEL_FOR_DEVICE;
1592: } else {
1593: if (!IS_SPECIAL(sx.st.st_mode))
1594: statret = -1;
1595: del_for_flag = DEL_FOR_SPECIAL;
1596: }
1597: if (statret == 0
1598: && BITS_EQUAL(sx.st.st_mode, file->mode, _S_IFMT)
1599: && (IS_SPECIAL(sx.st.st_mode) || sx.st.st_rdev == rdev)) {
1600: /* The device or special file is identical. */
1601: set_file_attrs(fname, file, &sx, NULL, maybe_ATTRS_REPORT);
1602: if (itemizing)
1603: itemize(fname, file, ndx, 0, &sx, 0, 0, NULL);
1604: #ifdef SUPPORT_HARD_LINKS
1605: if (preserve_hard_links && F_IS_HLINKED(file))
1606: finish_hard_link(file, fname, ndx, &sx.st, itemizing, code, -1);
1607: #endif
1608: if (remove_source_files == 1)
1609: goto return_with_success;
1610: goto cleanup;
1611: }
1612: } else if (basis_dir[0] != NULL) {
1613: int j = try_dests_non(file, fname, ndx, fnamecmpbuf, &sx,
1614: itemizing, code);
1615: if (j == -2) {
1616: #ifndef CAN_HARDLINK_SPECIAL
1617: if (link_dest) {
1618: /* Resort to --copy-dest behavior. */
1619: } else
1620: #endif
1621: if (!copy_dest)
1622: goto cleanup;
1623: itemizing = 0;
1624: code = FNONE;
1625: } else if (j >= 0) {
1626: statret = 1;
1627: fnamecmp = fnamecmpbuf;
1628: }
1629: }
1630: if (DEBUG_GTE(GENR, 1)) {
1631: rprintf(FINFO, "mknod(%s, 0%o, [%ld,%ld])\n",
1632: fname, (int)file->mode,
1633: (long)major(rdev), (long)minor(rdev));
1634: }
1635: if (atomic_create(file, fname, NULL, NULL, rdev, &sx, del_for_flag)) {
1636: set_file_attrs(fname, file, NULL, NULL, 0);
1637: if (itemizing) {
1638: itemize(fnamecmp, file, ndx, statret, &sx,
1639: ITEM_LOCAL_CHANGE|ITEM_REPORT_CHANGE, 0, NULL);
1640: }
1641: if (code != FNONE && INFO_GTE(NAME, 1))
1642: rprintf(code, "%s\n", fname);
1643: #ifdef SUPPORT_HARD_LINKS
1644: if (preserve_hard_links && F_IS_HLINKED(file))
1645: finish_hard_link(file, fname, ndx, NULL, itemizing, code, -1);
1646: #endif
1647: if (remove_source_files == 1)
1648: goto return_with_success;
1649: }
1650: goto cleanup;
1651: }
1652:
1653: if (!S_ISREG(file->mode)) {
1654: if (solo_file)
1655: fname = f_name(file, NULL);
1656: rprintf(FINFO, "skipping non-regular file \"%s\"\n", fname);
1657: goto cleanup;
1658: }
1659:
1660: if (max_size >= 0 && F_LENGTH(file) > max_size) {
1661: if (INFO_GTE(SKIP, 1)) {
1662: if (solo_file)
1663: fname = f_name(file, NULL);
1664: rprintf(FINFO, "%s is over max-size\n", fname);
1665: }
1666: goto cleanup;
1667: }
1668: if (min_size >= 0 && F_LENGTH(file) < min_size) {
1669: if (INFO_GTE(SKIP, 1)) {
1670: if (solo_file)
1671: fname = f_name(file, NULL);
1672: rprintf(FINFO, "%s is under min-size\n", fname);
1673: }
1674: goto cleanup;
1675: }
1676:
1677: if (update_only > 0 && statret == 0
1678: && cmp_time(sx.st.st_mtime, file->modtime) > 0) {
1679: if (INFO_GTE(SKIP, 1))
1680: rprintf(FINFO, "%s is newer\n", fname);
1681: #ifdef SUPPORT_HARD_LINKS
1682: if (F_IS_HLINKED(file))
1683: handle_skipped_hlink(file, itemizing, code, f_out);
1684: #endif
1685: goto cleanup;
1686: }
1687:
1688: fnamecmp_type = FNAMECMP_FNAME;
1689:
1690: if (statret == 0 && !S_ISREG(sx.st.st_mode)) {
1691: if (delete_item(fname, sx.st.st_mode, del_opts | DEL_FOR_FILE) != 0)
1692: goto cleanup;
1693: statret = -1;
1694: stat_errno = ENOENT;
1695: }
1696:
1697: if (basis_dir[0] != NULL && (statret != 0 || !copy_dest)) {
1698: int j = try_dests_reg(file, fname, ndx, fnamecmpbuf, &sx,
1699: statret == 0, itemizing, code);
1700: if (j == -2) {
1701: if (remove_source_files == 1)
1702: goto return_with_success;
1703: goto cleanup;
1704: }
1705: if (j >= 0) {
1706: fnamecmp = fnamecmpbuf;
1707: fnamecmp_type = j;
1708: statret = 0;
1709: }
1710: }
1711:
1712: init_stat_x(&real_sx);
1713: real_sx.st = sx.st; /* Don't copy xattr/acl pointers, as they would free wrong. */
1714: real_ret = statret;
1715:
1716: if (partial_dir && (partialptr = partial_dir_fname(fname)) != NULL
1717: && link_stat(partialptr, &partial_st, 0) == 0
1718: && S_ISREG(partial_st.st_mode)) {
1719: if (statret != 0)
1720: goto prepare_to_open;
1721: } else
1722: partialptr = NULL;
1723:
1724: if (statret != 0 && fuzzy_basis) {
1725: /* Sets fnamecmp_type to FNAMECMP_FUZZY or above. */
1726: fuzzy_file = find_fuzzy(file, fuzzy_dirlist, &fnamecmp_type);
1727: if (fuzzy_file) {
1728: f_name(fuzzy_file, fnamecmpbuf);
1729: if (DEBUG_GTE(FUZZY, 1)) {
1730: rprintf(FINFO, "fuzzy basis selected for %s: %s\n",
1731: fname, fnamecmpbuf);
1732: }
1733: sx.st.st_size = F_LENGTH(fuzzy_file);
1734: statret = 0;
1735: fnamecmp = fnamecmpbuf;
1736: }
1737: }
1738:
1739: if (statret != 0) {
1740: #ifdef SUPPORT_HARD_LINKS
1741: if (preserve_hard_links && F_HLINK_NOT_LAST(file)) {
1742: cur_flist->in_progress++;
1743: goto cleanup;
1744: }
1745: #endif
1746: if (stat_errno == ENOENT)
1747: goto notify_others;
1748: rsyserr(FERROR_XFER, stat_errno, "recv_generator: failed to stat %s",
1749: full_fname(fname));
1750: goto cleanup;
1751: }
1752:
1753: if (fnamecmp_type <= FNAMECMP_BASIS_DIR_HIGH)
1754: ;
1755: else if (fnamecmp_type == FNAMECMP_FUZZY)
1756: ;
1757: else if (unchanged_file(fnamecmp, file, &sx.st)) {
1758: if (partialptr) {
1759: do_unlink(partialptr);
1760: handle_partial_dir(partialptr, PDIR_DELETE);
1761: }
1762: set_file_attrs(fname, file, &sx, NULL, maybe_ATTRS_REPORT);
1763: if (itemizing)
1764: itemize(fnamecmp, file, ndx, statret, &sx, 0, 0, NULL);
1765: #ifdef SUPPORT_HARD_LINKS
1766: if (preserve_hard_links && F_IS_HLINKED(file))
1767: finish_hard_link(file, fname, ndx, &sx.st, itemizing, code, -1);
1768: #endif
1769: if (remove_source_files != 1)
1770: goto cleanup;
1771: return_with_success:
1772: if (!dry_run)
1773: send_msg_int(MSG_SUCCESS, ndx);
1774: goto cleanup;
1775: }
1776:
1777: if (append_mode > 0 && sx.st.st_size >= F_LENGTH(file)) {
1778: #ifdef SUPPORT_HARD_LINKS
1779: if (F_IS_HLINKED(file))
1780: handle_skipped_hlink(file, itemizing, code, f_out);
1781: #endif
1782: goto cleanup;
1783: }
1784:
1785: prepare_to_open:
1786: if (partialptr) {
1787: sx.st = partial_st;
1788: fnamecmp = partialptr;
1789: fnamecmp_type = FNAMECMP_PARTIAL_DIR;
1790: statret = 0;
1791: }
1792:
1793: if (!do_xfers)
1794: goto notify_others;
1795:
1796: if (read_batch || whole_file) {
1797: if (inplace && make_backups > 0 && fnamecmp_type == FNAMECMP_FNAME) {
1798: if (!(backupptr = get_backup_name(fname)))
1799: goto cleanup;
1800: if (!(back_file = make_file(fname, NULL, NULL, 0, NO_FILTERS)))
1801: goto pretend_missing;
1802: if (copy_file(fname, backupptr, -1, back_file->mode) < 0) {
1803: unmake_file(back_file);
1804: back_file = NULL;
1805: goto cleanup;
1806: }
1807: }
1808: goto notify_others;
1809: }
1810:
1811: if (fuzzy_dirlist[0]) {
1812: int j = flist_find(fuzzy_dirlist[0], file);
1813: if (j >= 0) /* don't use changing file as future fuzzy basis */
1814: fuzzy_dirlist[0]->files[j]->flags |= FLAG_FILE_SENT;
1815: }
1816:
1817: /* open the file */
1818: if ((fd = do_open(fnamecmp, O_RDONLY, 0)) < 0) {
1819: rsyserr(FERROR, errno, "failed to open %s, continuing",
1820: full_fname(fnamecmp));
1821: pretend_missing:
1822: /* pretend the file didn't exist */
1823: #ifdef SUPPORT_HARD_LINKS
1824: if (preserve_hard_links && F_HLINK_NOT_LAST(file)) {
1825: cur_flist->in_progress++;
1826: goto cleanup;
1827: }
1828: #endif
1829: statret = real_ret = -1;
1830: goto notify_others;
1831: }
1832:
1833: if (inplace && make_backups > 0 && fnamecmp_type == FNAMECMP_FNAME) {
1834: if (!(backupptr = get_backup_name(fname))) {
1835: close(fd);
1836: goto cleanup;
1837: }
1838: if (!(back_file = make_file(fname, NULL, NULL, 0, NO_FILTERS))) {
1839: close(fd);
1840: goto pretend_missing;
1841: }
1842: if (robust_unlink(backupptr) && errno != ENOENT) {
1843: rsyserr(FERROR_XFER, errno, "unlink %s",
1844: full_fname(backupptr));
1845: unmake_file(back_file);
1846: back_file = NULL;
1847: close(fd);
1848: goto cleanup;
1849: }
1850: if ((f_copy = do_open(backupptr, O_WRONLY | O_CREAT | O_TRUNC | O_EXCL, 0600)) < 0) {
1851: rsyserr(FERROR_XFER, errno, "open %s", full_fname(backupptr));
1852: unmake_file(back_file);
1853: back_file = NULL;
1854: close(fd);
1855: goto cleanup;
1856: }
1857: fnamecmp_type = FNAMECMP_BACKUP;
1858: }
1859:
1860: if (DEBUG_GTE(DELTASUM, 3)) {
1861: rprintf(FINFO, "gen mapped %s of size %s\n",
1862: fnamecmp, big_num(sx.st.st_size));
1863: }
1864:
1865: if (DEBUG_GTE(DELTASUM, 2))
1866: rprintf(FINFO, "generating and sending sums for %d\n", ndx);
1867:
1868: notify_others:
1869: if (remove_source_files && !delay_updates && !phase && !dry_run)
1870: increment_active_files(ndx, itemizing, code);
1871: if (inc_recurse && (!dry_run || write_batch < 0))
1872: cur_flist->in_progress++;
1873: #ifdef SUPPORT_HARD_LINKS
1874: if (preserve_hard_links && F_IS_HLINKED(file))
1875: file->flags |= FLAG_FILE_SENT;
1876: #endif
1877: write_ndx(f_out, ndx);
1878: if (itemizing) {
1879: int iflags = ITEM_TRANSFER;
1880: if (always_checksum > 0)
1881: iflags |= ITEM_REPORT_CHANGE;
1882: if (fnamecmp_type != FNAMECMP_FNAME)
1883: iflags |= ITEM_BASIS_TYPE_FOLLOWS;
1884: if (fnamecmp_type >= FNAMECMP_FUZZY)
1885: iflags |= ITEM_XNAME_FOLLOWS;
1886: itemize(fnamecmp, file, -1, real_ret, &real_sx, iflags, fnamecmp_type,
1887: fuzzy_file ? fuzzy_file->basename : NULL);
1888: free_stat_x(&real_sx);
1889: }
1890:
1891: if (!do_xfers) {
1892: #ifdef SUPPORT_HARD_LINKS
1893: if (preserve_hard_links && F_IS_HLINKED(file))
1894: finish_hard_link(file, fname, ndx, &sx.st, itemizing, code, -1);
1895: #endif
1896: goto cleanup;
1897: }
1898: if (read_batch)
1899: goto cleanup;
1900:
1901: if (statret != 0 || whole_file)
1902: write_sum_head(f_out, NULL);
1903: else if (sx.st.st_size <= 0) {
1904: write_sum_head(f_out, NULL);
1905: close(fd);
1906: } else {
1907: if (generate_and_send_sums(fd, sx.st.st_size, f_out, f_copy) < 0) {
1908: rprintf(FWARNING,
1909: "WARNING: file is too large for checksum sending: %s\n",
1910: fnamecmp);
1911: write_sum_head(f_out, NULL);
1912: }
1913: close(fd);
1914: }
1915:
1916: cleanup:
1917: if (back_file) {
1918: int save_preserve_xattrs = preserve_xattrs;
1919: if (f_copy >= 0)
1920: close(f_copy);
1921: #ifdef SUPPORT_XATTRS
1922: if (preserve_xattrs) {
1923: copy_xattrs(fname, backupptr);
1924: preserve_xattrs = 0;
1925: }
1926: #endif
1927: set_file_attrs(backupptr, back_file, NULL, NULL, 0);
1928: preserve_xattrs = save_preserve_xattrs;
1929: if (INFO_GTE(BACKUP, 1)) {
1930: rprintf(FINFO, "backed up %s to %s\n",
1931: fname, backupptr);
1932: }
1933: unmake_file(back_file);
1934: }
1935:
1936: free_stat_x(&sx);
1937: }
1938:
1939: /* If we are replacing an existing hard link, symlink, device, or special file,
1940: * create a temp-name item and rename it into place. A symlimk specifies slnk,
1941: * a hard link specifies hlnk, otherwise we create a device based on rdev.
1942: * Specify 0 for the del_for_flag if there is not a file to replace. This
1943: * returns 1 on success and 0 on failure. */
1944: int atomic_create(struct file_struct *file, char *fname, const char *slnk, const char *hlnk,
1945: dev_t rdev, stat_x *sxp, int del_for_flag)
1946: {
1947: char tmpname[MAXPATHLEN];
1948: const char *create_name;
1949: int skip_atomic, dir_in_the_way = del_for_flag && S_ISDIR(sxp->st.st_mode);
1950:
1951: if (!del_for_flag || dir_in_the_way || tmpdir || !get_tmpname(tmpname, fname, True))
1952: skip_atomic = 1;
1953: else
1954: skip_atomic = 0;
1955:
1956: if (del_for_flag) {
1957: if (make_backups > 0 && !dir_in_the_way) {
1958: if (!make_backup(fname, skip_atomic))
1959: return 0;
1960: } else if (skip_atomic) {
1961: int del_opts = delete_mode || force_delete ? DEL_RECURSE : 0;
1962: if (delete_item(fname, sxp->st.st_mode, del_opts | del_for_flag) != 0)
1963: return 0;
1964: }
1965: }
1966:
1967: create_name = skip_atomic ? fname : tmpname;
1968:
1969: if (slnk) {
1970: #ifdef SUPPORT_LINKS
1971: if (do_symlink(slnk, create_name) < 0) {
1972: rsyserr(FERROR_XFER, errno, "symlink %s -> \"%s\" failed",
1973: full_fname(create_name), slnk);
1974: return 0;
1975: }
1976: #else
1977: return 0;
1978: #endif
1979: } else if (hlnk) {
1980: #ifdef SUPPORT_HARD_LINKS
1981: if (!hard_link_one(file, create_name, hlnk, 0))
1982: return 0;
1983: #else
1984: return 0;
1985: #endif
1986: } else {
1987: if (do_mknod(create_name, file->mode, rdev) < 0) {
1988: rsyserr(FERROR_XFER, errno, "mknod %s failed",
1989: full_fname(create_name));
1990: return 0;
1991: }
1992: }
1993:
1994: if (!skip_atomic) {
1995: if (do_rename(tmpname, fname) < 0) {
1996: rsyserr(FERROR_XFER, errno, "rename %s -> \"%s\" failed",
1997: full_fname(tmpname), full_fname(fname));
1998: do_unlink(tmpname);
1999: return 0;
2000: }
2001: }
2002:
2003: return 1;
2004: }
2005:
2006: #ifdef SUPPORT_HARD_LINKS
2007: static void handle_skipped_hlink(struct file_struct *file, int itemizing,
2008: enum logcode code, int f_out)
2009: {
2010: char fbuf[MAXPATHLEN];
2011: int new_last_ndx;
2012: struct file_list *save_flist = cur_flist;
2013:
2014: /* If we skip the last item in a chain of links and there was a
2015: * prior non-skipped hard-link waiting to finish, finish it now. */
2016: if ((new_last_ndx = skip_hard_link(file, &cur_flist)) < 0)
2017: return;
2018:
2019: file = cur_flist->files[new_last_ndx - cur_flist->ndx_start];
2020: cur_flist->in_progress--; /* undo prior increment */
2021: f_name(file, fbuf);
2022: recv_generator(fbuf, file, new_last_ndx, itemizing, code, f_out);
2023:
2024: cur_flist = save_flist;
2025: }
2026: #endif
2027:
2028: static void touch_up_dirs(struct file_list *flist, int ndx)
2029: {
2030: static int counter = 0;
2031: struct file_struct *file;
2032: char *fname;
2033: BOOL fix_dir_perms;
2034: int i, start, end;
2035:
2036: if (ndx < 0) {
2037: start = 0;
2038: end = flist->used - 1;
2039: } else
2040: start = end = ndx;
2041:
2042: /* Fix any directory permissions that were modified during the
2043: * transfer and/or re-set any tweaked modified-time values. */
2044: for (i = start; i <= end; i++, counter++) {
2045: file = flist->files[i];
2046: if (!F_IS_ACTIVE(file))
2047: continue;
2048: if (!S_ISDIR(file->mode)
2049: || (!implied_dirs && file->flags & FLAG_IMPLIED_DIR))
2050: continue;
2051: if (DEBUG_GTE(TIME, 2)) {
2052: fname = f_name(file, NULL);
2053: rprintf(FINFO, "touch_up_dirs: %s (%d)\n",
2054: NS(fname), i);
2055: }
2056: /* Be sure not to retouch permissions with --fake-super. */
2057: fix_dir_perms = !am_root && !(file->mode & S_IWUSR);
2058: if (file->flags & FLAG_MISSING_DIR || !(need_retouch_dir_times || fix_dir_perms))
2059: continue;
2060: fname = f_name(file, NULL);
2061: if (fix_dir_perms)
2062: do_chmod(fname, file->mode);
2063: if (need_retouch_dir_times) {
2064: STRUCT_STAT st;
2065: if (link_stat(fname, &st, 0) == 0
2066: && cmp_time(st.st_mtime, file->modtime) != 0)
2067: set_modtime(fname, file->modtime, F_MOD_NSEC(file), file->mode);
2068: }
2069: if (counter >= loopchk_limit) {
2070: if (allowed_lull)
2071: maybe_send_keepalive(time(NULL), MSK_ALLOW_FLUSH);
2072: else
2073: maybe_flush_socket(0);
2074: counter = 0;
2075: }
2076: }
2077: }
2078:
2079: void check_for_finished_files(int itemizing, enum logcode code, int check_redo)
2080: {
2081: struct file_struct *file;
2082: struct file_list *flist;
2083: char fbuf[MAXPATHLEN];
2084: int ndx;
2085:
2086: while (1) {
2087: #ifdef SUPPORT_HARD_LINKS
2088: if (preserve_hard_links && (ndx = get_hlink_num()) != -1) {
2089: int send_failed = (ndx == -2);
2090: if (send_failed)
2091: ndx = get_hlink_num();
2092: flist = flist_for_ndx(ndx, "check_for_finished_files.1");
2093: file = flist->files[ndx - flist->ndx_start];
2094: assert(file->flags & FLAG_HLINKED);
2095: if (send_failed)
2096: handle_skipped_hlink(file, itemizing, code, sock_f_out);
2097: else
2098: finish_hard_link(file, f_name(file, fbuf), ndx, NULL, itemizing, code, -1);
2099: flist->in_progress--;
2100: continue;
2101: }
2102: #endif
2103:
2104: if (check_redo && (ndx = get_redo_num()) != -1) {
2105: OFF_T save_max_size = max_size;
2106: OFF_T save_min_size = min_size;
2107: csum_length = SUM_LENGTH;
2108: max_size = -1;
2109: min_size = -1;
2110: ignore_existing = -ignore_existing;
2111: ignore_non_existing = -ignore_non_existing;
2112: update_only = -update_only;
2113: always_checksum = -always_checksum;
2114: size_only = -size_only;
2115: append_mode = -append_mode;
2116: make_backups = -make_backups; /* avoid dup backup w/inplace */
2117: ignore_times++;
2118:
2119: flist = cur_flist;
2120: cur_flist = flist_for_ndx(ndx, "check_for_finished_files.2");
2121:
2122: file = cur_flist->files[ndx - cur_flist->ndx_start];
2123: if (solo_file)
2124: strlcpy(fbuf, solo_file, sizeof fbuf);
2125: else
2126: f_name(file, fbuf);
2127: recv_generator(fbuf, file, ndx, itemizing, code, sock_f_out);
2128: cur_flist->to_redo--;
2129:
2130: cur_flist = flist;
2131:
2132: csum_length = SHORT_SUM_LENGTH;
2133: max_size = save_max_size;
2134: min_size = save_min_size;
2135: ignore_existing = -ignore_existing;
2136: ignore_non_existing = -ignore_non_existing;
2137: update_only = -update_only;
2138: always_checksum = -always_checksum;
2139: size_only = -size_only;
2140: append_mode = -append_mode;
2141: make_backups = -make_backups;
2142: ignore_times--;
2143: continue;
2144: }
2145:
2146: if (cur_flist == first_flist)
2147: break;
2148:
2149: /* We only get here if inc_recurse is enabled. */
2150: if (first_flist->in_progress || first_flist->to_redo)
2151: break;
2152:
2153: write_ndx(sock_f_out, NDX_DONE);
2154: if (!read_batch && !flist_eof) {
2155: int old_total = 0;
2156: for (flist = first_flist; flist != cur_flist; flist = flist->next)
2157: old_total += flist->used;
2158: maybe_flush_socket(!flist_eof && file_total - old_total < MIN_FILECNT_LOOKAHEAD/2);
2159: }
2160:
2161: if (delete_during == 2 || !dir_tweaking) {
2162: /* Skip directory touch-up. */
2163: } else if (first_flist->parent_ndx >= 0)
2164: touch_up_dirs(dir_flist, first_flist->parent_ndx);
2165:
2166: flist_free(first_flist); /* updates first_flist */
2167: }
2168: }
2169:
2170: void generate_files(int f_out, const char *local_name)
2171: {
2172: int i, ndx, next_loopchk = 0;
2173: char fbuf[MAXPATHLEN];
2174: int itemizing;
2175: enum logcode code;
2176: int save_info_flist = info_levels[INFO_FLIST];
2177: int save_info_progress = info_levels[INFO_PROGRESS];
2178:
2179: if (protocol_version >= 29) {
2180: itemizing = 1;
2181: maybe_ATTRS_REPORT = stdout_format_has_i ? 0 : ATTRS_REPORT;
2182: code = logfile_format_has_i ? FNONE : FLOG;
2183: } else if (am_daemon) {
2184: itemizing = logfile_format_has_i && do_xfers;
2185: maybe_ATTRS_REPORT = ATTRS_REPORT;
2186: code = itemizing || !do_xfers ? FCLIENT : FINFO;
2187: } else if (!am_server) {
2188: itemizing = stdout_format_has_i;
2189: maybe_ATTRS_REPORT = stdout_format_has_i ? 0 : ATTRS_REPORT;
2190: code = itemizing ? FNONE : FINFO;
2191: } else {
2192: itemizing = 0;
2193: maybe_ATTRS_REPORT = ATTRS_REPORT;
2194: code = FINFO;
2195: }
2196: solo_file = local_name;
2197: dir_tweaking = !(list_only || solo_file || dry_run);
2198: need_retouch_dir_times = preserve_times & PRESERVE_DIR_TIMES;
2199: loopchk_limit = allowed_lull ? allowed_lull * 5 : 200;
2200: symlink_timeset_failed_flags = ITEM_REPORT_TIME
2201: | (protocol_version >= 30 || !am_server ? ITEM_REPORT_TIMEFAIL : 0);
2202: implied_dirs_are_missing = relative_paths && !implied_dirs && protocol_version < 30;
2203:
2204: if (DEBUG_GTE(GENR, 1))
2205: rprintf(FINFO, "generator starting pid=%d\n", (int)getpid());
2206:
2207: if (delete_before && !solo_file && cur_flist->used > 0)
2208: do_delete_pass();
2209: if (delete_during == 2) {
2210: deldelay_size = BIGPATHBUFLEN * 4;
2211: deldelay_buf = new_array(char, deldelay_size);
2212: if (!deldelay_buf)
2213: out_of_memory("delete-delay");
2214: }
2215: info_levels[INFO_FLIST] = info_levels[INFO_PROGRESS] = 0;
2216:
2217: if (append_mode > 0 || whole_file < 0)
2218: whole_file = 0;
2219: if (DEBUG_GTE(FLIST, 1)) {
2220: rprintf(FINFO, "delta-transmission %s\n",
2221: whole_file
2222: ? "disabled for local transfer or --whole-file"
2223: : "enabled");
2224: }
2225:
2226: dflt_perms = (ACCESSPERMS & ~orig_umask);
2227:
2228: do {
2229: #ifdef SUPPORT_HARD_LINKS
2230: if (preserve_hard_links && inc_recurse) {
2231: while (!flist_eof && file_total < MIN_FILECNT_LOOKAHEAD/2)
2232: wait_for_receiver();
2233: }
2234: #endif
2235:
2236: if (inc_recurse && cur_flist->parent_ndx >= 0) {
2237: struct file_struct *fp = dir_flist->files[cur_flist->parent_ndx];
2238: if (solo_file)
2239: strlcpy(fbuf, solo_file, sizeof fbuf);
2240: else
2241: f_name(fp, fbuf);
2242: ndx = cur_flist->ndx_start - 1;
2243: recv_generator(fbuf, fp, ndx, itemizing, code, f_out);
2244: if (delete_during && dry_run < 2 && !list_only
2245: && !(fp->flags & FLAG_MISSING_DIR)) {
2246: if (fp->flags & FLAG_CONTENT_DIR) {
2247: dev_t dirdev;
2248: if (one_file_system) {
2249: uint32 *devp = F_DIR_DEV_P(fp);
2250: dirdev = MAKEDEV(DEV_MAJOR(devp), DEV_MINOR(devp));
2251: } else
2252: dirdev = MAKEDEV(0, 0);
2253: delete_in_dir(fbuf, fp, &dirdev);
2254: } else
2255: change_local_filter_dir(fbuf, strlen(fbuf), F_DEPTH(fp));
2256: }
2257: }
2258: for (i = cur_flist->low; i <= cur_flist->high; i++) {
2259: struct file_struct *file = cur_flist->sorted[i];
2260:
2261: if (!F_IS_ACTIVE(file))
2262: continue;
2263:
2264: if (unsort_ndx)
2265: ndx = F_NDX(file);
2266: else
2267: ndx = i + cur_flist->ndx_start;
2268:
2269: if (solo_file)
2270: strlcpy(fbuf, solo_file, sizeof fbuf);
2271: else
2272: f_name(file, fbuf);
2273: recv_generator(fbuf, file, ndx, itemizing, code, f_out);
2274:
2275: check_for_finished_files(itemizing, code, 0);
2276:
2277: if (i + cur_flist->ndx_start >= next_loopchk) {
2278: if (allowed_lull)
2279: maybe_send_keepalive(time(NULL), MSK_ALLOW_FLUSH);
2280: else
2281: maybe_flush_socket(0);
2282: next_loopchk += loopchk_limit;
2283: }
2284: }
2285:
2286: if (!inc_recurse) {
2287: write_ndx(f_out, NDX_DONE);
2288: break;
2289: }
2290:
2291: while (1) {
2292: check_for_finished_files(itemizing, code, 1);
2293: if (cur_flist->next || flist_eof)
2294: break;
2295: wait_for_receiver();
2296: }
2297: } while ((cur_flist = cur_flist->next) != NULL);
2298:
2299: if (delete_during)
2300: delete_in_dir(NULL, NULL, &dev_zero);
2301: phase++;
2302: if (DEBUG_GTE(GENR, 1))
2303: rprintf(FINFO, "generate_files phase=%d\n", phase);
2304:
2305: while (1) {
2306: check_for_finished_files(itemizing, code, 1);
2307: if (msgdone_cnt)
2308: break;
2309: wait_for_receiver();
2310: }
2311:
2312: phase++;
2313: if (DEBUG_GTE(GENR, 1))
2314: rprintf(FINFO, "generate_files phase=%d\n", phase);
2315:
2316: write_ndx(f_out, NDX_DONE);
2317:
2318: /* Reduce round-trip lag-time for a useless delay-updates phase. */
2319: if (protocol_version >= 29 && EARLY_DELAY_DONE_MSG())
2320: write_ndx(f_out, NDX_DONE);
2321:
2322: if (protocol_version >= 31 && EARLY_DELETE_DONE_MSG()) {
2323: if ((INFO_GTE(STATS, 2) && (delete_mode || force_delete)) || read_batch)
2324: write_del_stats(f_out);
2325: if (EARLY_DELAY_DONE_MSG()) /* Can't send this before delay */
2326: write_ndx(f_out, NDX_DONE);
2327: }
2328:
2329: /* Read MSG_DONE for the redo phase (and any prior messages). */
2330: while (1) {
2331: check_for_finished_files(itemizing, code, 0);
2332: if (msgdone_cnt > 1)
2333: break;
2334: wait_for_receiver();
2335: }
2336:
2337: if (protocol_version >= 29) {
2338: phase++;
2339: if (DEBUG_GTE(GENR, 1))
2340: rprintf(FINFO, "generate_files phase=%d\n", phase);
2341: if (!EARLY_DELAY_DONE_MSG()) {
2342: write_ndx(f_out, NDX_DONE);
2343: if (protocol_version >= 31 && EARLY_DELETE_DONE_MSG())
2344: write_ndx(f_out, NDX_DONE);
2345: }
2346: /* Read MSG_DONE for delay-updates phase & prior messages. */
2347: while (msgdone_cnt == 2)
2348: wait_for_receiver();
2349: }
2350:
2351: info_levels[INFO_FLIST] = save_info_flist;
2352: info_levels[INFO_PROGRESS] = save_info_progress;
2353:
2354: if (delete_during == 2)
2355: do_delayed_deletions(fbuf);
2356: if (delete_after && !solo_file && file_total > 0)
2357: do_delete_pass();
2358:
2359: if (max_delete >= 0 && skipped_deletes) {
2360: rprintf(FWARNING,
2361: "Deletions stopped due to --max-delete limit (%d skipped)\n",
2362: skipped_deletes);
2363: io_error |= IOERR_DEL_LIMIT;
2364: }
2365:
2366: if (protocol_version >= 31) {
2367: if (!EARLY_DELETE_DONE_MSG()) {
2368: if (INFO_GTE(STATS, 2) || read_batch)
2369: write_del_stats(f_out);
2370: write_ndx(f_out, NDX_DONE);
2371: }
2372:
2373: /* Read MSG_DONE for late-delete phase & prior messages. */
2374: while (msgdone_cnt == 3)
2375: wait_for_receiver();
2376: }
2377:
2378: if ((need_retouch_dir_perms || need_retouch_dir_times)
2379: && dir_tweaking && (!inc_recurse || delete_during == 2))
2380: touch_up_dirs(dir_flist, -1);
2381:
2382: if (DEBUG_GTE(GENR, 1))
2383: rprintf(FINFO, "generate_files finished\n");
2384: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>