X-Git-Url: https://mattmccutchen.net/rsync/rsync.git/blobdiff_plain/f6f74b93efc1b37f6135650dc034d3403ef482b6..7462c6ac39d86cb8252ec47246569e3ddda35b6a:/generator.c diff --git a/generator.c b/generator.c index 80db57dd..2ae88dbe 100644 --- a/generator.c +++ b/generator.c @@ -697,8 +697,11 @@ void itemize(const char *fnamecmp, struct file_struct *file, int ndx, int statre if (iflags & ITEM_XNAME_FOLLOWS) write_vstring(sock_f_out, xname, strlen(xname)); #ifdef SUPPORT_XATTRS - if (iflags & ITEM_REPORT_XATTR && !dry_run) - send_xattr_request(NULL, file, sock_f_out); + if (preserve_xattrs && !dry_run + && iflags & (ITEM_REPORT_XATTR|ITEM_TRANSFER)) { + send_xattr_request(NULL, file, + iflags & ITEM_REPORT_XATTR ? sock_f_out : -1); + } #endif } else if (ndx >= 0) { enum logcode code = logfile_format_has_i ? FINFO : FCLIENT; @@ -753,6 +756,7 @@ static void sum_sizes_sqroot(struct sum_struct *sum, int64 len) { int32 blength; int s2length; + int64 l; if (block_size) blength = block_size; @@ -760,7 +764,6 @@ static void sum_sizes_sqroot(struct sum_struct *sum, int64 len) blength = BLOCK_SIZE; else { int32 c; - int64 l; int cnt; for (c = 1, l = len, cnt = 0; l >>= 2; c <<= 1, cnt++) {} if (cnt >= 31 || c >= MAX_BLOCK_SIZE) @@ -783,7 +786,6 @@ static void sum_sizes_sqroot(struct sum_struct *sum, int64 len) s2length = SUM_LENGTH; } else { int32 c; - int64 l; int b = BLOCKSUM_BIAS; for (l = len; l >>= 1; b += 2) {} for (c = blength; (c >>= 1) && b; b--) {} @@ -797,7 +799,10 @@ static void sum_sizes_sqroot(struct sum_struct *sum, int64 len) sum->blength = blength; sum->s2length = s2length; sum->remainder = (int32)(len % blength); - sum->count = (int32)(len / blength) + (sum->remainder != 0); + sum->count = (int32)(l = (len / blength) + (sum->remainder != 0)); + + if ((int64)sum->count != l) + sum->count = -1; if (sum->count && verbose > 2) { rprintf(FINFO, @@ -813,7 +818,7 @@ static void sum_sizes_sqroot(struct sum_struct *sum, int64 len) * * Generate approximately one checksum every block_len bytes. */ -static void generate_and_send_sums(int fd, OFF_T len, int f_out, int f_copy) +static int generate_and_send_sums(int fd, OFF_T len, int f_out, int f_copy) { int32 i; struct map_struct *mapbuf; @@ -821,10 +826,12 @@ static void generate_and_send_sums(int fd, OFF_T len, int f_out, int f_copy) OFF_T offset = 0; sum_sizes_sqroot(&sum, len); + if (sum.count < 0) + return -1; write_sum_head(f_out, &sum); if (append_mode > 0 && f_copy < 0) - return; + return 0; if (len > 0) mapbuf = map_file(fd, len, MAX_MAP_SIZE, sum.blength); @@ -861,6 +868,8 @@ static void generate_and_send_sums(int fd, OFF_T len, int f_out, int f_copy) if (mapbuf) unmap_file(mapbuf); + + return 0; } @@ -922,6 +931,7 @@ static int copy_altdest_file(const char *src, const char *dest, struct file_stru { char buf[MAXPATHLEN]; const char *copy_to, *partialptr; + int save_preserve_xattrs = preserve_xattrs; int ok, fd_w; if (inplace) { @@ -946,7 +956,9 @@ static int copy_altdest_file(const char *src, const char *dest, struct file_stru return -1; } partialptr = partial_dir ? partial_dir_fname(dest) : NULL; + preserve_xattrs = 0; /* xattrs were copied with file */ ok = finish_transfer(dest, copy_to, src, partialptr, file, 1, 0); + preserve_xattrs = save_preserve_xattrs; cleanup_disable(); return ok ? 0 : -1; } @@ -1284,7 +1296,7 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx, skip_dir = NULL; } - if (daemon_filter_list.head) { + if (daemon_filter_list.head && (*fname != '.' || fname[1])) { if (check_filter(&daemon_filter_list, FLOG, fname, is_dir) < 0) { if (is_dir < 0) return; @@ -1488,7 +1500,6 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx, delete_in_dir(fname, file, &real_sx.st.st_dev); else change_local_filter_dir(fname, strlen(fname), F_DEPTH(file)); - } goto cleanup; } @@ -1869,15 +1880,21 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx, close(fd); goto cleanup; } - if ((f_copy = do_open(backupptr, O_WRONLY | O_CREAT | O_TRUNC | O_EXCL, 0600)) < 0 - && (errno != ENOENT || make_bak_dir(backupptr) < 0 - || (f_copy = do_open(backupptr, O_WRONLY | O_CREAT | O_TRUNC | O_EXCL, 0600)) < 0)) { - rsyserr(FERROR_XFER, errno, "open %s", - full_fname(backupptr)); - unmake_file(back_file); - back_file = NULL; - close(fd); - goto cleanup; + if ((f_copy = do_open(backupptr, O_WRONLY | O_CREAT | O_TRUNC | O_EXCL, 0600)) < 0) { + int save_errno = errno ? errno : EINVAL; /* 0 paranoia */ + if (errno == ENOENT && make_bak_dir(backupptr) == 0) { + if ((f_copy = do_open(backupptr, O_WRONLY | O_CREAT | O_TRUNC | O_EXCL, 0600)) < 0) + save_errno = errno ? errno : save_errno; + else + save_errno = 0; + } + if (save_errno) { + rsyserr(FERROR_XFER, save_errno, "open %s", full_fname(backupptr)); + unmake_file(back_file); + back_file = NULL; + close(fd); + goto cleanup; + } } fnamecmp_type = FNAMECMP_BACKUP; } @@ -1930,18 +1947,31 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx, if (read_batch) goto cleanup; - if (statret != 0 || whole_file) + if (statret != 0 || whole_file || sx.st.st_size <= 0) write_sum_head(f_out, NULL); else { - generate_and_send_sums(fd, sx.st.st_size, f_out, f_copy); + if (generate_and_send_sums(fd, sx.st.st_size, f_out, f_copy) < 0) { + rprintf(FWARNING, + "WARNING: file is too large for checksum sending: %s\n", + fnamecmp); + write_sum_head(f_out, NULL); + } close(fd); } cleanup: if (back_file) { + int save_preserve_xattrs = preserve_xattrs; if (f_copy >= 0) close(f_copy); +#ifdef SUPPORT_XATTRS + if (preserve_xattrs) { + copy_xattrs(fname, backupptr); + preserve_xattrs = 0; + } +#endif set_file_attrs(backupptr, back_file, NULL, NULL, 0); + preserve_xattrs = save_preserve_xattrs; if (verbose > 1) { rprintf(FINFO, "backed up %s to %s\n", fname, backupptr);