X-Git-Url: https://mattmccutchen.net/rsync/rsync.git/blobdiff_plain/819bfe459919769c9ddae14affeaa79596c640bb..7462c6ac39d86cb8252ec47246569e3ddda35b6a:/generator.c diff --git a/generator.c b/generator.c index ff31e063..2ae88dbe 100644 --- a/generator.c +++ b/generator.c @@ -557,10 +557,13 @@ static void do_delete_pass(void) for (j = 0; j < cur_flist->used; j++) { struct file_struct *file = cur_flist->sorted[j]; - if (!(file->flags & FLAG_CONTENT_DIR)) + f_name(file, fbuf); + + if (!(file->flags & FLAG_CONTENT_DIR)) { + change_local_filter_dir(fbuf, strlen(fbuf), F_DEPTH(file)); continue; + } - f_name(file, fbuf); if (verbose > 1 && file->flags & FLAG_TOP_DIR) rprintf(FINFO, "deleting in %s\n", fbuf); @@ -694,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; @@ -750,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; @@ -757,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) @@ -780,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--) {} @@ -794,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, @@ -810,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; @@ -818,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); @@ -858,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; } @@ -919,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) { @@ -943,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; } @@ -1281,8 +1296,8 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx, skip_dir = NULL; } - if (daemon_filter_list.head) { - if (check_filter(&daemon_filter_list, fname, is_dir) < 0) { + if (daemon_filter_list.head && (*fname != '.' || fname[1])) { + if (check_filter(&daemon_filter_list, FLOG, fname, is_dir) < 0) { if (is_dir < 0) return; #ifdef SUPPORT_HARD_LINKS @@ -1480,8 +1495,12 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx, } } else if (delete_during && f_out != -1 && !phase - && BITS_SETnUNSET(file->flags, FLAG_CONTENT_DIR, FLAG_MISSING_DIR)) - delete_in_dir(fname, file, &real_sx.st.st_dev); + && !(file->flags & FLAG_MISSING_DIR)) { + if (file->flags & FLAG_CONTENT_DIR) + delete_in_dir(fname, file, &real_sx.st.st_dev); + else + change_local_filter_dir(fname, strlen(fname), F_DEPTH(file)); + } goto cleanup; } @@ -1861,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; } @@ -1922,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); @@ -2175,16 +2213,18 @@ void generate_files(int f_out, const char *local_name) f_name(fp, fbuf); ndx = cur_flist->ndx_start - 1; recv_generator(fbuf, fp, ndx, itemizing, code, f_out); - if (delete_during && dry_run < 2 && !list_only) { - if (BITS_SETnUNSET(fp->flags, FLAG_CONTENT_DIR, FLAG_MISSING_DIR)) { + if (delete_during && dry_run < 2 && !list_only + && !(fp->flags & FLAG_MISSING_DIR)) { + if (fp->flags & FLAG_CONTENT_DIR) { dev_t dirdev; if (one_file_system) { uint32 *devp = F_DIR_DEV_P(fp); dirdev = MAKEDEV(DEV_MAJOR(devp), DEV_MINOR(devp)); } else dirdev = MAKEDEV(0, 0); - delete_in_dir(f_name(fp, fbuf), fp, &dirdev); - } + delete_in_dir(fbuf, fp, &dirdev); + } else + change_local_filter_dir(fbuf, strlen(fbuf), F_DEPTH(fp)); } } for (i = cur_flist->low; i <= cur_flist->high; i++) {