--- embedaddon/rsync/sender.c 2016/11/01 09:54:32 1.1.1.3 +++ 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-2015 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; @@ -32,6 +33,7 @@ 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; @@ -40,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; @@ -62,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; @@ -89,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); @@ -128,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; @@ -138,22 +141,25 @@ 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; } - if (S_ISREG(file->mode) /* Symlinks & devices don't need this check: */ - && (st.st_size != F_LENGTH(file) || st.st_mtime != file->modtime + if (st.st_size != F_LENGTH(file) || st.st_mtime != file->modtime #ifdef ST_MTIME_NSEC || (NSEC_BUMP(file) && (uint32)st.ST_MTIME_NSEC != F_MOD_NSEC(file)) #endif - )) { + ) { 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) @@ -202,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); @@ -218,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; @@ -268,8 +297,7 @@ void send_files(int f_in, int f_out) 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)) { @@ -312,10 +340,10 @@ 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); @@ -324,8 +352,7 @@ void send_files(int f_in, int f_out) 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; } @@ -335,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)); @@ -356,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; @@ -365,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); @@ -376,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)) @@ -393,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); @@ -406,6 +463,8 @@ void send_files(int f_in, int f_out) } } close(fd); + if (unlink_tmp) + unlink(tmp); free_sums(s);