|
|
| version 1.1.1.2, 2013/10/14 07:51:14 | version 1.1.1.4, 2021/03/17 00:32:36 |
|---|---|
| Line 3 | Line 3 |
| * | * |
| * Copyright (C) 1996 Andrew Tridgell | * Copyright (C) 1996 Andrew Tridgell |
| * Copyright (C) 1996 Paul Mackerras | * 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 | * 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 | * it under the terms of the GNU General Public License as published by |
| Line 21 | Line 21 |
| #include "rsync.h" | #include "rsync.h" |
| #include "inums.h" | #include "inums.h" |
| #include "ifuncs.h" | |
| extern int do_xfers; | extern int do_xfers; |
| extern int am_server; | extern int am_server; |
| Line 29 extern int inc_recurse; | Line 30 extern int inc_recurse; |
| extern int log_before_transfer; | extern int log_before_transfer; |
| extern int stdout_format_has_i; | extern int stdout_format_has_i; |
| extern int logfile_format_has_i; | extern int logfile_format_has_i; |
| extern int want_xattr_optim; | |
| extern int csum_length; | extern int csum_length; |
| extern int append_mode; | extern int append_mode; |
| extern int copy_links; | |
| extern int io_error; | extern int io_error; |
| extern int flist_eof; | extern int flist_eof; |
| extern int allowed_lull; | extern int allowed_lull; |
| Line 39 extern int protocol_version; | Line 42 extern int protocol_version; |
| extern int remove_source_files; | extern int remove_source_files; |
| extern int updating_basis_file; | extern int updating_basis_file; |
| extern int make_backups; | extern int make_backups; |
| extern int make_source_backups; | |
| extern int inplace; | extern int inplace; |
| extern int inplace_partial; | |
| extern int batch_fd; | extern int batch_fd; |
| extern int write_batch; | extern int write_batch; |
| extern int file_old_total; | extern int file_old_total; |
| extern BOOL want_progress_now; | |
| extern char *source_filter; | |
| extern struct stats stats; | extern struct stats stats; |
| extern struct file_list *cur_flist, *first_flist, *dir_flist; | extern struct file_list *cur_flist, *first_flist, *dir_flist; |
| Line 61 BOOL extra_flist_sending_enabled; | Line 68 BOOL extra_flist_sending_enabled; |
| **/ | **/ |
| static struct sum_struct *receive_sums(int f) | static struct sum_struct *receive_sums(int f) |
| { | { |
| struct sum_struct *s; | struct sum_struct *s = new(struct sum_struct); |
| int32 i; | |
| int lull_mod = protocol_version >= 31 ? 0 : allowed_lull * 5; | int lull_mod = protocol_version >= 31 ? 0 : allowed_lull * 5; |
| OFF_T offset = 0; | OFF_T offset = 0; |
| int32 i; | |
| if (!(s = new(struct sum_struct))) | |
| out_of_memory("receive_sums"); | |
| read_sum_head(f, s); | read_sum_head(f, s); |
| s->sums = NULL; | s->sums = NULL; |
| Line 88 static struct sum_struct *receive_sums(int f) | Line 92 static struct sum_struct *receive_sums(int f) |
| if (s->count == 0) | if (s->count == 0) |
| return(s); | return(s); |
| if (!(s->sums = new_array(struct sum_buf, s->count))) | s->sums = new_array(struct sum_buf, s->count); |
| out_of_memory("receive_sums"); | |
| for (i = 0; i < s->count; i++) { | for (i = 0; i < s->count; i++) { |
| s->sums[i].sum1 = read_int(f); | s->sums[i].sum1 = read_int(f); |
| Line 127 void successful_send(int ndx) | Line 130 void successful_send(int ndx) |
| struct file_struct *file; | struct file_struct *file; |
| struct file_list *flist; | struct file_list *flist; |
| STRUCT_STAT st; | STRUCT_STAT st; |
| int result; | |
| if (!remove_source_files) | if (!remove_source_files) |
| return; | return; |
| Line 137 void successful_send(int ndx) | Line 141 void successful_send(int ndx) |
| return; | return; |
| f_name(file, fname); | 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"; | failed_op = "re-lstat"; |
| goto failed; | goto failed; |
| } | } |
| Line 147 void successful_send(int ndx) | Line 151 void successful_send(int ndx) |
| || (NSEC_BUMP(file) && (uint32)st.ST_MTIME_NSEC != F_MOD_NSEC(file)) | || (NSEC_BUMP(file) && (uint32)st.ST_MTIME_NSEC != F_MOD_NSEC(file)) |
| #endif | #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; | 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_op = "remove"; |
| failed: | failed: |
| if (errno == ENOENT) | if (errno == ENOENT) |
| rprintf(FINFO, "sender file already removed: %s\n", fname); | rprintf(FINFO, "sender file already removed: %s\n", fname); |
| else | 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 { | } else { |
| if (INFO_GTE(REMOVE, 1)) | if (INFO_GTE(REMOVE, 1)) |
| rprintf(FINFO, "sender removed %s\n", fname); | rprintf(FINFO, "sender removed %s\n", fname); |
| Line 178 static void write_ndx_and_attrs(int f_out, int ndx, in | Line 186 static void write_ndx_and_attrs(int f_out, int ndx, in |
| write_vstring(f_out, buf, len); | write_vstring(f_out, buf, len); |
| #ifdef SUPPORT_XATTRS | #ifdef SUPPORT_XATTRS |
| if (preserve_xattrs && iflags & ITEM_REPORT_XATTR && do_xfers | 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); | send_xattr_request(fname, file, f_out); |
| #endif | #endif |
| } | } |
| Line 200 void send_files(int f_in, int f_out) | Line 208 void send_files(int f_in, int f_out) |
| int f_xfer = write_batch < 0 ? batch_fd : f_out; | int f_xfer = write_batch < 0 ? batch_fd : f_out; |
| int save_io_error = io_error; | int save_io_error = io_error; |
| int ndx, j; | 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)) | if (DEBUG_GTE(SEND, 1)) |
| rprintf(FINFO, "send_files starting\n"); | rprintf(FINFO, "send_files starting\n"); |
| progress_init(); | |
| while (1) { | while (1) { |
| if (inc_recurse) { | if (inc_recurse) { |
| send_extra_file_list(f_out, MIN_FILECNT_LOOKAHEAD); | send_extra_file_list(f_out, MIN_FILECNT_LOOKAHEAD); |
| Line 216 void send_files(int f_in, int f_out) | Line 246 void send_files(int f_in, int f_out) |
| extra_flist_sending_enabled = False; | extra_flist_sending_enabled = False; |
| if (ndx == NDX_DONE) { | if (ndx == NDX_DONE) { |
| if (!am_server && INFO_GTE(PROGRESS, 2) && cur_flist) { | if (!am_server && cur_flist) { |
| set_current_file_index(NULL, 0); | set_current_file_index(NULL, 0); |
| end_progress(0); | if (INFO_GTE(PROGRESS, 2)) |
| end_progress(0); | |
| } | } |
| if (inc_recurse && first_flist) { | if (inc_recurse && first_flist) { |
| file_old_total -= first_flist->used; | file_old_total -= first_flist->used; |
| Line 260 void send_files(int f_in, int f_out) | Line 291 void send_files(int f_in, int f_out) |
| #ifdef SUPPORT_XATTRS | #ifdef SUPPORT_XATTRS |
| if (preserve_xattrs && iflags & ITEM_REPORT_XATTR && do_xfers | 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); | recv_xattr_request(file, f_in); |
| #endif | #endif |
| if (!(iflags & ITEM_TRANSFER)) { | if (!(iflags & ITEM_TRANSFER)) { |
| maybe_log_item(file, iflags, itemizing, xname); | maybe_log_item(file, iflags, itemizing, xname); |
| write_ndx_and_attrs(f_out, ndx, iflags, fname, file, | write_ndx_and_attrs(f_out, ndx, iflags, fname, file, fnamecmp_type, xname, xlen); |
| fnamecmp_type, xname, xlen); | |
| if (iflags & ITEM_IS_NEW) { | if (iflags & ITEM_IS_NEW) { |
| stats.created_files++; | stats.created_files++; |
| if (S_ISREG(file->mode)) { | if (S_ISREG(file->mode)) { |
| Line 310 void send_files(int f_in, int f_out) | Line 340 void send_files(int f_in, int f_out) |
| stats.created_files++; | stats.created_files++; |
| } | } |
| updating_basis_file = inplace && (protocol_version >= 29 | updating_basis_file = (inplace_partial && fnamecmp_type == FNAMECMP_PARTIAL_DIR) |
| ? fnamecmp_type == FNAMECMP_FNAME : make_backups <= 0); | || (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); | set_current_file_index(file, ndx); |
| stats.xferred_files++; | stats.xferred_files++; |
| stats.total_transferred_size += F_LENGTH(file); | stats.total_transferred_size += F_LENGTH(file); |
| if (!log_before_transfer) | remember_initial_stats(); |
| remember_initial_stats(); | |
| if (!do_xfers) { /* log the transfer */ | if (!do_xfers) { /* log the transfer */ |
| log_item(FCLIENT, file, iflags, NULL); | log_item(FCLIENT, file, iflags, NULL); |
| write_ndx_and_attrs(f_out, ndx, iflags, fname, file, | write_ndx_and_attrs(f_out, ndx, iflags, fname, file, fnamecmp_type, xname, xlen); |
| fnamecmp_type, xname, xlen); | |
| continue; | continue; |
| } | } |
| Line 334 void send_files(int f_in, int f_out) | Line 362 void send_files(int f_in, int f_out) |
| exit_cleanup(RERR_PROTOCOL); | exit_cleanup(RERR_PROTOCOL); |
| } | } |
| unlink_tmp = 0; | |
| fd = do_open(fname, O_RDONLY, 0); | fd = do_open(fname, O_RDONLY, 0); |
| if (fd == -1) { | if (fd == -1) { |
| if (errno == ENOENT) { | if (errno == ENOENT) { |
| enum logcode c = am_daemon | enum logcode c = am_daemon && protocol_version < 28 ? FERROR : FWARNING; |
| && protocol_version < 28 ? FERROR | |
| : FWARNING; | |
| io_error |= IOERR_VANISHED; | io_error |= IOERR_VANISHED; |
| rprintf(c, "file has vanished: %s\n", | rprintf(c, "file has vanished: %s\n", |
| full_fname(fname)); | full_fname(fname)); |
| Line 355 void send_files(int f_in, int f_out) | Line 382 void send_files(int f_in, int f_out) |
| continue; | 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 */ | /* map the local file */ |
| if (do_fstat(fd, &st) != 0) { | if (do_fstat(fd, &st) != 0) { |
| io_error |= IOERR_GENERAL; | io_error |= IOERR_GENERAL; |
| Line 364 void send_files(int f_in, int f_out) | Line 418 void send_files(int f_in, int f_out) |
| exit_cleanup(RERR_FILEIO); | 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) { | if (st.st_size) { |
| int32 read_size = MAX(s->blength * 3, MAX_MAP_SIZE); | int32 read_size = MAX(s->blength * 3, MAX_MAP_SIZE); |
| mbuf = map_file(fd, st.st_size, read_size, s->blength); | mbuf = map_file(fd, st.st_size, read_size, s->blength); |
| Line 375 void send_files(int f_in, int f_out) | Line 432 void send_files(int f_in, int f_out) |
| path,slash,fname, big_num(st.st_size)); | path,slash,fname, big_num(st.st_size)); |
| } | } |
| write_ndx_and_attrs(f_out, ndx, iflags, fname, file, | write_ndx_and_attrs(f_out, ndx, iflags, fname, file, fnamecmp_type, xname, xlen); |
| fnamecmp_type, xname, xlen); | |
| write_sum_head(f_xfer, s); | write_sum_head(f_xfer, s); |
| if (DEBUG_GTE(DELTASUM, 2)) | if (DEBUG_GTE(DELTASUM, 2)) |
| Line 392 void send_files(int f_in, int f_out) | Line 448 void send_files(int f_in, int f_out) |
| match_sums(f_xfer, s, mbuf, st.st_size); | match_sums(f_xfer, s, mbuf, st.st_size); |
| if (INFO_GTE(PROGRESS, 1)) | if (INFO_GTE(PROGRESS, 1)) |
| end_progress(st.st_size); | end_progress(st.st_size); |
| else if (want_progress_now) | |
| instant_progress(fname); | |
| log_item(log_code, file, iflags, NULL); | log_item(log_code, file, iflags, NULL); |
| Line 405 void send_files(int f_in, int f_out) | Line 463 void send_files(int f_in, int f_out) |
| } | } |
| } | } |
| close(fd); | close(fd); |
| if (unlink_tmp) | |
| unlink(tmp); | |
| free_sums(s); | free_sums(s); |