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);
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;
{
int32 blength;
int s2length;
+ int64 l;
if (block_size)
blength = block_size;
else if (len <= BLOCK_SIZE * BLOCK_SIZE)
blength = BLOCK_SIZE;
else {
+ int32 max_blength = protocol_version < 30 ? OLD_MAX_BLOCK_SIZE : MAX_BLOCK_SIZE;
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)
- blength = MAX_BLOCK_SIZE;
+ if (c < 0 || c >= max_blength)
+ blength = max_blength;
else {
blength = 0;
do {
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--) {}
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,
*
* 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;
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);
if (mapbuf)
unmap_file(mapbuf);
+
+ return 0;
}
{
char buf[MAXPATHLEN];
const char *copy_to, *partialptr;
+ int save_preserve_xattrs = preserve_xattrs;
int ok, fd_w;
if (inplace) {
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;
}
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
if (j == -2) {
itemizing = 0;
code = FNONE;
+ statret = 1;
} else if (j >= 0)
statret = 1;
}
goto cleanup;
}
}
+#ifdef SUPPORT_XATTRS
+ if (preserve_xattrs && statret == 1)
+ copy_xattrs(fnamecmpbuf, fname);
+#endif
if (set_file_attrs(fname, file, real_ret ? NULL : &real_sx, NULL, 0)
&& verbose && code != FNONE && f_out != -1)
rprintf(code, "%s/\n", fname);
}
}
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;
}
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;
}
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);
if (inc_recurse && cur_flist->parent_ndx >= 0) {
struct file_struct *fp = dir_flist->files[cur_flist->parent_ndx];
- f_name(fp, fbuf);
+ if (solo_file)
+ strlcpy(fbuf, solo_file, sizeof fbuf);
+ else
+ 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++) {