* 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 version 2 as
- * published by the Free Software Foundation.
+ * it under the terms of the GNU General Public License as published by
+ * 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,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* 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 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;
extern int checksum_seed;
extern int inplace;
extern int delay_updates;
+extern mode_t orig_umask;
extern struct stats stats;
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;
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;
sum.flength = (OFF_T)sum.count * sum.blength;
if (sum.remainder)
sum.flength -= sum.blength - sum.remainder;
- for (j = CHUNK_SIZE; j < sum.flength; j += CHUNK_SIZE) {
- if (do_progress)
- show_progress(offset, total_size);
- sum_update(map_ptr(mapbuf, offset, CHUNK_SIZE),
- CHUNK_SIZE);
- offset = j;
- }
- if (offset < sum.flength) {
- int32 len = (int32)(sum.flength - offset);
- if (do_progress)
- show_progress(offset, total_size);
- sum_update(map_ptr(mapbuf, offset, len), len);
- offset = sum.flength;
+ if (append_mode == 2) {
+ for (j = CHUNK_SIZE; j < sum.flength; j += CHUNK_SIZE) {
+ if (do_progress)
+ show_progress(offset, total_size);
+ sum_update(map_ptr(mapbuf, offset, CHUNK_SIZE),
+ CHUNK_SIZE);
+ offset = j;
+ }
+ if (offset < sum.flength) {
+ int32 len = (int32)(sum.flength - offset);
+ if (do_progress)
+ show_progress(offset, total_size);
+ sum_update(map_ptr(mapbuf, offset, len), len);
+ }
}
+ offset = sum.flength;
if (fd != -1 && (j = do_lseek(fd, offset, SEEK_SET)) != offset) {
rsyserr(FERROR, errno, "lseek of %s returned %.0f, not %.0f",
full_fname(fname), (double)j, (double)offset);
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;
}
next_gen_ndx = read_int(fd);
if (next_gen_ndx == -1) {
if (inc_recurse)
- next_gen_ndx = first_flist->prev->count + first_flist->prev->ndx_start;
+ 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;
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;
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 (inc_recurse && first_flist) {
flist_free(first_flist);
}
if (read_batch && cur_flist) {
int high = inc_recurse
- ? first_flist->prev->count + first_flist->prev->ndx_start
- : cur_flist->count;
+ ? 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;
}
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) {
if (csum_length == SHORT_SUM_LENGTH) {
if (keep_partial && !partial_dir)
make_backups = -make_backups; /* prevents double backup */
+ if (append_mode)
+ sparse_files = -sparse_files;
append_mode = -append_mode;
- sparse_files = -sparse_files;
csum_length = SUM_LENGTH;
redoing = 1;
}
if (csum_length != SHORT_SUM_LENGTH) {
if (keep_partial && !partial_dir)
make_backups = -make_backups;
+ if (append_mode)
+ sparse_files = -sparse_files;
append_mode = -append_mode;
- sparse_files = -sparse_files;
csum_length = SHORT_SUM_LENGTH;
redoing = 0;
}
"(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;
full_fname(fnamecmp));
discard_receive_data(f_in, F_LENGTH(file));
close(fd1);
+ if (inc_recurse)
+ send_msg_int(MSG_NO_SEND, ndx);
continue;
}
full_fname(fnamecmp));
discard_receive_data(f_in, F_LENGTH(file));
close(fd1);
+ if (inc_recurse)
+ send_msg_int(MSG_NO_SEND, ndx);
continue;
}
* 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" */
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 {
discard_receive_data(f_in, F_LENGTH(file));
if (fd1 != -1)
close(fd1);
+ if (inc_recurse)
+ send_msg_int(MSG_NO_SEND, ndx);
continue;
}
discard_receive_data(f_in, F_LENGTH(file));
if (fd1 != -1)
close(fd1);
+ if (inc_recurse)
+ send_msg_int(MSG_NO_SEND, ndx);
continue;
}
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);