X-Git-Url: https://mattmccutchen.net/rsync/rsync.git/blobdiff_plain/d0221f1d2bb77a8fa9ce8e86ab52ee566c7a9b77..8e41b68e8f975c02a5d9281be780ba5d1a385107:/receiver.c diff --git a/receiver.c b/receiver.c index 17601e6e..98666487 100644 --- a/receiver.c +++ b/receiver.c @@ -3,11 +3,11 @@ * * Copyright (C) 1996-2000 Andrew Tridgell * Copyright (C) 1996 Paul Mackerras - * Copyright (C) 2003, 2004, 2005, 2006 Wayne Davison + * Copyright (C) 2003-2007 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 - * the Free Software Foundation; either version 2 of the License, or + * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, @@ -16,17 +16,17 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. + * with this program; if not, visit the http://fsf.org website. */ #include "rsync.h" extern int verbose; +extern int dry_run; extern int do_xfers; extern int am_server; extern int do_progress; -extern int incremental; +extern int inc_recurse; extern int log_before_transfer; extern int stdout_format_has_i; extern int logfile_format_has_i; @@ -38,6 +38,7 @@ extern int protocol_version; extern int relative_paths; extern int preserve_hard_links; extern int preserve_perms; +extern int preserve_xattrs; extern int basis_dir_cnt; extern int make_backups; extern int cleanup_got_literal; @@ -48,12 +49,12 @@ extern int keep_partial; extern int checksum_seed; extern int inplace; extern int delay_updates; +extern mode_t orig_umask; extern struct stats stats; -extern char *stdout_format; extern char *tmpdir; extern char *partial_dir; extern char *basis_dir[]; -extern struct file_list *cur_flist, *first_flist; +extern struct file_list *cur_flist, *first_flist, *dir_flist; extern struct filter_list_struct server_filter_list; static struct bitbag *delayed_bits = NULL; @@ -124,13 +125,13 @@ int get_tmpname(char *fnametmp, char *fname) static int receive_data(int f_in, char *fname_r, int fd_r, OFF_T size_r, - char *fname, int fd, OFF_T total_size) + const char *fname, int fd, OFF_T total_size) { - static char file_sum1[MD4_SUM_LENGTH]; - static char file_sum2[MD4_SUM_LENGTH]; + static char file_sum1[MAX_DIGEST_LEN]; + static char file_sum2[MAX_DIGEST_LEN]; struct map_struct *mapbuf; struct sum_struct sum; - int32 len; + int32 len, sum_len; OFF_T offset = 0; OFF_T offset2; char *data; @@ -258,15 +259,15 @@ static int receive_data(int f_in, char *fname_r, int fd_r, OFF_T size_r, exit_cleanup(RERR_FILEIO); } - sum_end(file_sum1); + sum_len = sum_end(file_sum1); if (mapbuf) unmap_file(mapbuf); - read_buf(f_in,file_sum2,MD4_SUM_LENGTH); + read_buf(f_in, file_sum2, sum_len); if (verbose > 2) rprintf(FINFO,"got file_sum\n"); - if (fd != -1 && memcmp(file_sum1, file_sum2, MD4_SUM_LENGTH) != 0) + if (fd != -1 && memcmp(file_sum1, file_sum2, sum_len) != 0) return 0; return 1; } @@ -319,10 +320,10 @@ static int get_next_gen_ndx(int fd, int next_gen_ndx, int desired_ndx) } next_gen_ndx = read_int(fd); if (next_gen_ndx == -1) { - if (incremental) - next_gen_ndx = first_flist->prev->count + first_flist->prev->ndx_start; + if (inc_recurse) + next_gen_ndx = first_flist->prev->used + first_flist->prev->ndx_start; else - next_gen_ndx = cur_flist->count; + next_gen_ndx = cur_flist->used; } } return next_gen_ndx; @@ -349,13 +350,17 @@ int recv_files(int f_in, char *local_name) int itemizing = am_server ? logfile_format_has_i : stdout_format_has_i; enum logcode log_code = log_before_transfer ? FLOG : FINFO; int max_phase = protocol_version >= 29 ? 2 : 1; + int dflt_perms = (ACCESSPERMS & ~orig_umask); +#ifdef SUPPORT_ACLS + const char *parent_dirname = ""; +#endif int ndx, recv_ok; if (verbose > 2) - rprintf(FINFO, "recv_files(%d) starting\n", cur_flist->count); + rprintf(FINFO, "recv_files(%d) starting\n", cur_flist->used); if (delay_updates) - delayed_bits = bitbag_create(cur_flist->count + 1); + delayed_bits = bitbag_create(cur_flist->used + 1); updating_basis = inplace; @@ -363,18 +368,18 @@ int recv_files(int f_in, char *local_name) cleanup_disable(); /* This call also sets cur_flist. */ - ndx = read_ndx_and_attrs(f_in, -1, &iflags, - &fnamecmp_type, xname, &xlen); + ndx = read_ndx_and_attrs(f_in, &iflags, &fnamecmp_type, + xname, &xlen); if (ndx == NDX_DONE) { - if (incremental && first_flist) { + if (inc_recurse && first_flist) { flist_free(first_flist); if (first_flist) continue; } if (read_batch && cur_flist) { - int high = incremental - ? first_flist->prev->count + first_flist->prev->ndx_start - : cur_flist->count; + int high = inc_recurse + ? first_flist->prev->used + first_flist->prev->ndx_start + : cur_flist->used; get_next_gen_ndx(batch_gen_fd, next_gen_ndx, high); next_gen_ndx = -1; } @@ -384,18 +389,30 @@ int recv_files(int f_in, char *local_name) rprintf(FINFO, "recv_files phase=%d\n", phase); if (phase == 2 && delay_updates) handle_delayed_updates(local_name); - send_msg(MSG_DONE, "", 0); + send_msg(MSG_DONE, "", 0, 0); continue; } - file = cur_flist->files[ndx - cur_flist->ndx_start]; + if (ndx - cur_flist->ndx_start >= 0) + file = cur_flist->files[ndx - cur_flist->ndx_start]; + else + file = dir_flist->files[cur_flist->parent_ndx]; fname = local_name ? local_name : f_name(file, fbuf); if (verbose > 2) rprintf(FINFO, "recv_files(%s)\n", fname); +#ifdef SUPPORT_XATTRS + if (iflags & ITEM_REPORT_XATTR && !dry_run) + recv_xattr_request(file, f_in); +#endif + if (!(iflags & ITEM_TRANSFER)) { maybe_log_item(file, iflags, itemizing, xname); +#ifdef SUPPORT_XATTRS + if (preserve_xattrs && iflags & ITEM_REPORT_XATTR && !dry_run) + set_file_attrs(fname, file, NULL, fname, 0); +#endif continue; } if (phase == 2) { @@ -456,6 +473,8 @@ int recv_files(int f_in, char *local_name) "(Skipping batched update for \"%s\")\n", fname); discard_receive_data(f_in, F_LENGTH(file)); + if (inc_recurse) + send_msg_int(MSG_NO_SEND, ndx); continue; } next_gen_ndx = -1; @@ -539,6 +558,8 @@ int recv_files(int f_in, char *local_name) full_fname(fnamecmp)); discard_receive_data(f_in, F_LENGTH(file)); close(fd1); + if (inc_recurse) + send_msg_int(MSG_NO_SEND, ndx); continue; } @@ -552,6 +573,8 @@ int recv_files(int f_in, char *local_name) full_fname(fnamecmp)); discard_receive_data(f_in, F_LENGTH(file)); close(fd1); + if (inc_recurse) + send_msg_int(MSG_NO_SEND, ndx); continue; } @@ -564,7 +587,16 @@ int recv_files(int f_in, char *local_name) * mode based on the local permissions and some heuristics. */ if (!preserve_perms) { int exists = fd1 != -1; - file->mode = dest_mode(file->mode, st.st_mode, exists); +#ifdef SUPPORT_ACLS + const char *dn = file->dirname ? file->dirname : "."; + if (parent_dirname != dn + && strcmp(parent_dirname, dn) != 0) { + dflt_perms = default_perms_for_dir(dn); + parent_dirname = dn; + } +#endif + file->mode = dest_mode(file->mode, st.st_mode, + dflt_perms, exists); } /* We now check to see if we are writing the file "inplace" */ @@ -576,6 +608,8 @@ int recv_files(int f_in, char *local_name) discard_receive_data(f_in, F_LENGTH(file)); if (fd1 != -1) close(fd1); + if (inc_recurse) + send_msg_int(MSG_NO_SEND, ndx); continue; } } else { @@ -583,6 +617,8 @@ int recv_files(int f_in, char *local_name) discard_receive_data(f_in, F_LENGTH(file)); if (fd1 != -1) close(fd1); + if (inc_recurse) + send_msg_int(MSG_NO_SEND, ndx); continue; } @@ -609,6 +645,8 @@ int recv_files(int f_in, char *local_name) discard_receive_data(f_in, F_LENGTH(file)); if (fd1 != -1) close(fd1); + if (inc_recurse) + send_msg_int(MSG_NO_SEND, ndx); continue; } @@ -643,15 +681,15 @@ int recv_files(int f_in, char *local_name) temp_copy_name = NULL; else temp_copy_name = partialptr; - finish_transfer(fname, fnametmp, temp_copy_name, - file, recv_ok, 1); + finish_transfer(fname, fnametmp, fnamecmp, + temp_copy_name, file, recv_ok, 1); if (fnamecmp == partialptr) { do_unlink(partialptr); handle_partial_dir(partialptr, PDIR_DELETE); } } else if (keep_partial && partialptr && handle_partial_dir(partialptr, PDIR_CREATE)) { - finish_transfer(partialptr, fnametmp, NULL, + finish_transfer(partialptr, fnametmp, fnamecmp, NULL, file, recv_ok, !partial_dir); if (delay_updates && recv_ok) { bitbag_set_bit(delayed_bits, ndx); @@ -665,7 +703,7 @@ int recv_files(int f_in, char *local_name) cleanup_disable(); if (recv_ok > 0) { - if (remove_source_files || incremental + if (remove_source_files || inc_recurse || (preserve_hard_links && F_IS_HLINKED(file))) send_msg_int(MSG_SUCCESS, ndx); } else if (!recv_ok) { @@ -692,7 +730,7 @@ int recv_files(int f_in, char *local_name) if (!redoing) { send_msg_int(MSG_REDO, ndx); file->flags |= FLAG_FILE_SENT; - } else if (incremental) + } else if (inc_recurse) send_msg_int(MSG_NO_SEND, ndx); } }