--- embedaddon/rsync/sender.c 2013/10/14 07:51:14 1.1.1.2 +++ embedaddon/rsync/sender.c 2021/03/17 00:32:36 1.1.1.4 @@ -3,7 +3,7 @@ * * Copyright (C) 1996 Andrew Tridgell * Copyright (C) 1996 Paul Mackerras - * Copyright (C) 2003-2013 Wayne Davison + * Copyright (C) 2003-2020 Wayne Davison * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -21,6 +21,7 @@ #include "rsync.h" #include "inums.h" +#include "ifuncs.h" extern int do_xfers; extern int am_server; @@ -29,8 +30,10 @@ extern int inc_recurse; extern int log_before_transfer; extern int stdout_format_has_i; extern int logfile_format_has_i; +extern int want_xattr_optim; extern int csum_length; extern int append_mode; +extern int copy_links; extern int io_error; extern int flist_eof; extern int allowed_lull; @@ -39,10 +42,14 @@ extern int protocol_version; extern int remove_source_files; extern int updating_basis_file; extern int make_backups; +extern int make_source_backups; extern int inplace; +extern int inplace_partial; extern int batch_fd; extern int write_batch; extern int file_old_total; +extern BOOL want_progress_now; +extern char *source_filter; extern struct stats stats; extern struct file_list *cur_flist, *first_flist, *dir_flist; @@ -61,14 +68,11 @@ BOOL extra_flist_sending_enabled; **/ static struct sum_struct *receive_sums(int f) { - struct sum_struct *s; - int32 i; + struct sum_struct *s = new(struct sum_struct); int lull_mod = protocol_version >= 31 ? 0 : allowed_lull * 5; OFF_T offset = 0; + int32 i; - if (!(s = new(struct sum_struct))) - out_of_memory("receive_sums"); - read_sum_head(f, s); s->sums = NULL; @@ -88,8 +92,7 @@ static struct sum_struct *receive_sums(int f) if (s->count == 0) return(s); - if (!(s->sums = new_array(struct sum_buf, s->count))) - out_of_memory("receive_sums"); + s->sums = new_array(struct sum_buf, s->count); for (i = 0; i < s->count; i++) { s->sums[i].sum1 = read_int(f); @@ -127,6 +130,7 @@ void successful_send(int ndx) struct file_struct *file; struct file_list *flist; STRUCT_STAT st; + int result; if (!remove_source_files) return; @@ -137,7 +141,7 @@ void successful_send(int ndx) return; f_name(file, fname); - if (do_lstat(fname, &st) < 0) { + if ((copy_links ? do_stat(fname, &st) : do_lstat(fname, &st)) < 0) { failed_op = "re-lstat"; goto failed; } @@ -147,17 +151,21 @@ void successful_send(int ndx) || (NSEC_BUMP(file) && (uint32)st.ST_MTIME_NSEC != F_MOD_NSEC(file)) #endif ) { - rprintf(FERROR, "ERROR: Skipping sender remove for changed file: %s\n", fname); + rprintf(FERROR_XFER, "ERROR: Skipping sender remove for changed file: %s\n", fname); return; } - if (do_unlink(fname) < 0) { + if (make_source_backups) + result = !make_backup(fname, True); + else + result = do_unlink(fname); + if (result < 0) { failed_op = "remove"; failed: if (errno == ENOENT) rprintf(FINFO, "sender file already removed: %s\n", fname); else - rsyserr(FERROR, errno, "sender failed to %s %s", failed_op, fname); + rsyserr(FERROR_XFER, errno, "sender failed to %s %s", failed_op, fname); } else { if (INFO_GTE(REMOVE, 1)) rprintf(FINFO, "sender removed %s\n", fname); @@ -178,7 +186,7 @@ static void write_ndx_and_attrs(int f_out, int ndx, in write_vstring(f_out, buf, len); #ifdef SUPPORT_XATTRS if (preserve_xattrs && iflags & ITEM_REPORT_XATTR && do_xfers - && (protocol_version < 31 || !BITS_SET(iflags, ITEM_XNAME_FOLLOWS|ITEM_LOCAL_CHANGE))) + && !(want_xattr_optim && BITS_SET(iflags, ITEM_XNAME_FOLLOWS|ITEM_LOCAL_CHANGE))) send_xattr_request(fname, file, f_out); #endif } @@ -200,10 +208,32 @@ void send_files(int f_in, int f_out) int f_xfer = write_batch < 0 ? batch_fd : f_out; int save_io_error = io_error; int ndx, j; + char *filter_argv[MAX_FILTER_ARGS + 1]; + char *tmp = 0; + int unlink_tmp = 0; + if (source_filter) { + char *p; + char *sep = " \t"; + int i; + for (p = strtok(source_filter, sep), i = 0; + p && i < MAX_FILTER_ARGS; + p = strtok(0, sep)) + filter_argv[i++] = p; + filter_argv[i] = NULL; + if (p) { + rprintf(FERROR, + "Too many arguments to source-filter (> %d)\n", + MAX_FILTER_ARGS); + exit_cleanup(RERR_SYNTAX); + } + } + if (DEBUG_GTE(SEND, 1)) rprintf(FINFO, "send_files starting\n"); + progress_init(); + while (1) { if (inc_recurse) { send_extra_file_list(f_out, MIN_FILECNT_LOOKAHEAD); @@ -216,9 +246,10 @@ void send_files(int f_in, int f_out) extra_flist_sending_enabled = False; if (ndx == NDX_DONE) { - if (!am_server && INFO_GTE(PROGRESS, 2) && cur_flist) { + if (!am_server && cur_flist) { set_current_file_index(NULL, 0); - end_progress(0); + if (INFO_GTE(PROGRESS, 2)) + end_progress(0); } if (inc_recurse && first_flist) { file_old_total -= first_flist->used; @@ -260,14 +291,13 @@ void send_files(int f_in, int f_out) #ifdef SUPPORT_XATTRS if (preserve_xattrs && iflags & ITEM_REPORT_XATTR && do_xfers - && (protocol_version < 31 || !BITS_SET(iflags, ITEM_XNAME_FOLLOWS|ITEM_LOCAL_CHANGE))) + && !(want_xattr_optim && BITS_SET(iflags, ITEM_XNAME_FOLLOWS|ITEM_LOCAL_CHANGE))) recv_xattr_request(file, f_in); #endif if (!(iflags & ITEM_TRANSFER)) { maybe_log_item(file, iflags, itemizing, xname); - write_ndx_and_attrs(f_out, ndx, iflags, fname, file, - fnamecmp_type, xname, xlen); + write_ndx_and_attrs(f_out, ndx, iflags, fname, file, fnamecmp_type, xname, xlen); if (iflags & ITEM_IS_NEW) { stats.created_files++; if (S_ISREG(file->mode)) { @@ -310,21 +340,19 @@ void send_files(int f_in, int f_out) stats.created_files++; } - updating_basis_file = inplace && (protocol_version >= 29 - ? fnamecmp_type == FNAMECMP_FNAME : make_backups <= 0); + updating_basis_file = (inplace_partial && fnamecmp_type == FNAMECMP_PARTIAL_DIR) + || (inplace && (protocol_version >= 29 ? fnamecmp_type == FNAMECMP_FNAME : make_backups <= 0)); - if (!am_server && INFO_GTE(PROGRESS, 1)) + if (!am_server) set_current_file_index(file, ndx); stats.xferred_files++; stats.total_transferred_size += F_LENGTH(file); - if (!log_before_transfer) - remember_initial_stats(); + remember_initial_stats(); if (!do_xfers) { /* log the transfer */ log_item(FCLIENT, file, iflags, NULL); - write_ndx_and_attrs(f_out, ndx, iflags, fname, file, - fnamecmp_type, xname, xlen); + write_ndx_and_attrs(f_out, ndx, iflags, fname, file, fnamecmp_type, xname, xlen); continue; } @@ -334,12 +362,11 @@ void send_files(int f_in, int f_out) exit_cleanup(RERR_PROTOCOL); } + unlink_tmp = 0; fd = do_open(fname, O_RDONLY, 0); if (fd == -1) { if (errno == ENOENT) { - enum logcode c = am_daemon - && protocol_version < 28 ? FERROR - : FWARNING; + enum logcode c = am_daemon && protocol_version < 28 ? FERROR : FWARNING; io_error |= IOERR_VANISHED; rprintf(c, "file has vanished: %s\n", full_fname(fname)); @@ -355,6 +382,33 @@ void send_files(int f_in, int f_out) continue; } + if (source_filter) { + int fd2; + char *tmpl = "/tmp/rsync-filtered_sourceXXXXXX"; + + tmp = strdup(tmpl); + fd2 = mkstemp(tmp); + if (fd2 == -1) { + rprintf(FERROR, "mkstemp %s failed: %s\n", + tmp, strerror(errno)); + } else { + int status; + pid_t pid = run_filter_on_file(filter_argv, fd2, fd); + close(fd); + close(fd2); + wait_process_with_flush(pid, &status); + if (status != 0) { + rprintf(FERROR, + "bypassing source filter %s; exited with code: %d\n", + source_filter, status); + fd = do_open(fname, O_RDONLY, 0); + } else { + fd = do_open(tmp, O_RDONLY, 0); + unlink_tmp = 1; + } + } + } + /* map the local file */ if (do_fstat(fd, &st) != 0) { io_error |= IOERR_GENERAL; @@ -364,6 +418,9 @@ void send_files(int f_in, int f_out) exit_cleanup(RERR_FILEIO); } + if (IS_DEVICE(st.st_mode) && st.st_size == 0) + st.st_size = get_device_size(fd, fname); + if (st.st_size) { int32 read_size = MAX(s->blength * 3, MAX_MAP_SIZE); mbuf = map_file(fd, st.st_size, read_size, s->blength); @@ -375,8 +432,7 @@ void send_files(int f_in, int f_out) path,slash,fname, big_num(st.st_size)); } - write_ndx_and_attrs(f_out, ndx, iflags, fname, file, - fnamecmp_type, xname, xlen); + write_ndx_and_attrs(f_out, ndx, iflags, fname, file, fnamecmp_type, xname, xlen); write_sum_head(f_xfer, s); if (DEBUG_GTE(DELTASUM, 2)) @@ -392,6 +448,8 @@ void send_files(int f_in, int f_out) match_sums(f_xfer, s, mbuf, st.st_size); if (INFO_GTE(PROGRESS, 1)) end_progress(st.st_size); + else if (want_progress_now) + instant_progress(fname); log_item(log_code, file, iflags, NULL); @@ -405,6 +463,8 @@ void send_files(int f_in, int f_out) } } close(fd); + if (unlink_tmp) + unlink(tmp); free_sums(s);