mirror of
https://github.com/RsyncProject/rsync.git
synced 2026-05-24 23:05:52 -04:00
Compare commits
28 Commits
v3.0.3pre1
...
v3.0.3pre3
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
13074c982b | ||
|
|
2171b9395b | ||
|
|
20bb1eb7ae | ||
|
|
7ee7bcd4e9 | ||
|
|
844810d609 | ||
|
|
67347196b1 | ||
|
|
e424e26128 | ||
|
|
ca7d17e41d | ||
|
|
6283e9ef43 | ||
|
|
7462c6ac39 | ||
|
|
f31850966f | ||
|
|
4ecf3e0671 | ||
|
|
60a986f504 | ||
|
|
0e9c3564c6 | ||
|
|
164cb66add | ||
|
|
0d9eba0312 | ||
|
|
d1f66d8d79 | ||
|
|
cc911409d6 | ||
|
|
a64f19e24b | ||
|
|
4337eeb754 | ||
|
|
928da42359 | ||
|
|
e717fa4d37 | ||
|
|
cc56eb2acc | ||
|
|
88e05f8489 | ||
|
|
9ec8583ef5 | ||
|
|
e9489cd6cb | ||
|
|
f1ca7c4429 | ||
|
|
adc4ebdd76 |
@@ -66,8 +66,8 @@ install: all
|
||||
${INSTALLCMD} ${INSTALL_STRIP} -m 755 rsync$(EXEEXT) ${DESTDIR}${bindir}
|
||||
-mkdir -p ${DESTDIR}${mandir}/man1
|
||||
-mkdir -p ${DESTDIR}${mandir}/man5
|
||||
if test -f $(srcdir)/rsync.1; then ${INSTALLMAN} -m 644 $(srcdir)/rsync.1 ${DESTDIR}${mandir}/man1; fi
|
||||
if test -f $(srcdir)/rsyncd.conf.5; then ${INSTALLMAN} -m 644 $(srcdir)/rsyncd.conf.5 ${DESTDIR}${mandir}/man5; fi
|
||||
if test -f rsync.1; then ${INSTALLMAN} -m 644 rsync.1 ${DESTDIR}${mandir}/man1; fi
|
||||
if test -f rsyncd.conf.5; then ${INSTALLMAN} -m 644 rsyncd.conf.5 ${DESTDIR}${mandir}/man5; fi
|
||||
|
||||
install-strip:
|
||||
$(MAKE) INSTALL_STRIP='-s' install
|
||||
@@ -146,12 +146,14 @@ Makefile: Makefile.in config.status
|
||||
proto: proto.h-tstamp
|
||||
|
||||
proto.h: proto.h-tstamp
|
||||
@echo ' ' >/dev/null
|
||||
@if test -f proto.h; then :; else cp -p $(srcdir)/proto.h .; fi
|
||||
|
||||
proto.h-tstamp: $(srcdir)/*.c $(srcdir)/lib/compat.c
|
||||
perl $(srcdir)/mkproto.pl $(srcdir)/*.c $(srcdir)/lib/compat.c
|
||||
|
||||
man: rsync.1 rsyncd.conf.5
|
||||
@if test -f rsync.1; then :; else cp -p $(srcdir)/rsync.1 .; fi
|
||||
@if test -f rsyncd.conf.5; then :; else cp -p $(srcdir)/rsyncd.conf.5 .; fi
|
||||
|
||||
rsync.1: rsync.yo
|
||||
yodl2man -o rsync.1 $(srcdir)/rsync.yo
|
||||
|
||||
48
NEWS
48
NEWS
@@ -9,30 +9,72 @@ Changes since 3.0.2:
|
||||
|
||||
- Fixed a crash bug in the hard-link code.
|
||||
|
||||
- Fixed the sending of xattr directory information when the code finds a
|
||||
--link-dest or --copy-dest directory with unchanged xattrs -- the
|
||||
destination directory now gets these unchanged xattrs properly applied.
|
||||
|
||||
- Fixed an xattr-sending glitch that could cause an "Internal abbrev"
|
||||
error.
|
||||
|
||||
- Fixed the combination of --xattrs and --backup.
|
||||
|
||||
- The generator no longer allows a '.' dir to be excluded by a daemon-
|
||||
exclude rule.
|
||||
|
||||
- Fixed deletion handling when copying a single, empty directory (with no
|
||||
files) to a differently named, non-existent directory.
|
||||
|
||||
- Fixed the conversion of spaces into dashes in the %M log escape.
|
||||
|
||||
- Fixed several places in the code that were not returning the right
|
||||
errno when a function failed.
|
||||
|
||||
- Fixed the backing up of a device or special file into a backup dir.
|
||||
|
||||
- Moved the setting of the socket options prior to the connect().
|
||||
|
||||
- If rsync exits in the middle of a --progress output, it now outputs a
|
||||
newline to prevent the progress line from being overwritten.
|
||||
newline to help prevent the progress line from being overwritten.
|
||||
|
||||
- Fixed a problem with how a destination path with a trailing slash was
|
||||
compared against the daemon excludes.
|
||||
- Fixed a problem with how a destination path with a trailing slash or
|
||||
a trailing dot-dir was compared against the daemon excludes.
|
||||
|
||||
- If a file's length is so huge that we overflow a checksum buffer count
|
||||
(i.e. several hundred TB), warn the user and avoid sending an invalid
|
||||
checksum struct over the wire.
|
||||
|
||||
- If an source arg is excluded, --relative no longer adds the excluded
|
||||
arg's implied dirs to the transfer. This fix also made the exclude
|
||||
check happen in the better place in the sending code.
|
||||
|
||||
- Use the overflow_exit() function for overflows, not out_of_memory().
|
||||
|
||||
- Improved the code to better handle a system that has only 32-bit file
|
||||
offsets.
|
||||
|
||||
ENHANCEMENTS:
|
||||
|
||||
- The rsyncd.conf manpage now consistently refers to the parameters in
|
||||
the daemon config file as "parameters".
|
||||
|
||||
- The description of the --inplace option was improved.
|
||||
|
||||
DEVELOPER RELATED:
|
||||
|
||||
- Fixed a testcase failure if the tests are run as root and made some
|
||||
compatibility improvements.
|
||||
|
||||
- Improved the daemon tests, including checking module comments, the
|
||||
listing of files, and the ensuring that daemon excludes can't affect
|
||||
a dot-dir arg.
|
||||
|
||||
- Improved some build rules for those that build in a separate directory
|
||||
from the source, including better install rules for the man pages, and
|
||||
the fixing of a proto.h-tstamp rule that could make the binaries get
|
||||
rebuild without cause.
|
||||
|
||||
- Improved the testsuite to work around a problem with some utilities
|
||||
(e.g. cp -p & touch -r) rounding sub-second timestamps.
|
||||
|
||||
- Ensure that the early patches don't cause any generated-file hunks to
|
||||
bleed-over into patches that follow.
|
||||
|
||||
78
backup.c
78
backup.c
@@ -180,10 +180,19 @@ int make_bak_dir(const char *fullpath)
|
||||
/* robustly move a file, creating new directory structures if necessary */
|
||||
static int robust_move(const char *src, char *dst)
|
||||
{
|
||||
if (robust_rename(src, dst, NULL, 0755) < 0
|
||||
&& (errno != ENOENT || make_bak_dir(dst) < 0
|
||||
|| robust_rename(src, dst, NULL, 0755) < 0))
|
||||
return -1;
|
||||
if (robust_rename(src, dst, NULL, 0755) < 0) {
|
||||
int save_errno = errno ? errno : EINVAL; /* 0 paranoia */
|
||||
if (errno == ENOENT && make_bak_dir(dst) == 0) {
|
||||
if (robust_rename(src, dst, NULL, 0755) < 0)
|
||||
save_errno = errno ? errno : save_errno;
|
||||
else
|
||||
save_errno = 0;
|
||||
}
|
||||
if (save_errno) {
|
||||
errno = save_errno;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -195,6 +204,7 @@ static int keep_backup(const char *fname)
|
||||
stat_x sx;
|
||||
struct file_struct *file;
|
||||
char *buf;
|
||||
int save_preserve_xattrs = preserve_xattrs;
|
||||
int kept = 0;
|
||||
int ret_code;
|
||||
|
||||
@@ -234,15 +244,23 @@ static int keep_backup(const char *fname)
|
||||
/* Check to see if this is a device file, or link */
|
||||
if ((am_root && preserve_devices && IS_DEVICE(file->mode))
|
||||
|| (preserve_specials && IS_SPECIAL(file->mode))) {
|
||||
uint32 *devp = F_RDEV_P(file);
|
||||
dev_t rdev = MAKEDEV(DEV_MAJOR(devp), DEV_MINOR(devp));
|
||||
int save_errno;
|
||||
do_unlink(buf);
|
||||
if (do_mknod(buf, file->mode, rdev) < 0
|
||||
&& (errno != ENOENT || make_bak_dir(buf) < 0
|
||||
|| do_mknod(buf, file->mode, rdev) < 0)) {
|
||||
rsyserr(FERROR, errno, "mknod %s failed",
|
||||
full_fname(buf));
|
||||
} else if (verbose > 2) {
|
||||
if (do_mknod(buf, file->mode, sx.st.st_rdev) < 0) {
|
||||
save_errno = errno ? errno : EINVAL; /* 0 paranoia */
|
||||
if (errno == ENOENT && make_bak_dir(buf) == 0) {
|
||||
if (do_mknod(buf, file->mode, sx.st.st_rdev) < 0)
|
||||
save_errno = errno ? errno : save_errno;
|
||||
else
|
||||
save_errno = 0;
|
||||
}
|
||||
if (save_errno) {
|
||||
rsyserr(FERROR, save_errno, "mknod %s failed",
|
||||
full_fname(buf));
|
||||
}
|
||||
} else
|
||||
save_errno = 0;
|
||||
if (verbose > 2 && save_errno == 0) {
|
||||
rprintf(FINFO, "make_backup: DEVICE %s successful.\n",
|
||||
fname);
|
||||
}
|
||||
@@ -252,11 +270,18 @@ static int keep_backup(const char *fname)
|
||||
|
||||
if (!kept && S_ISDIR(file->mode)) {
|
||||
/* make an empty directory */
|
||||
if (do_mkdir(buf, file->mode) < 0
|
||||
&& (errno != ENOENT || make_bak_dir(buf) < 0
|
||||
|| do_mkdir(buf, file->mode) < 0)) {
|
||||
rsyserr(FINFO, errno, "mkdir %s failed",
|
||||
full_fname(buf));
|
||||
if (do_mkdir(buf, file->mode) < 0) {
|
||||
int save_errno = errno ? errno : EINVAL; /* 0 paranoia */
|
||||
if (errno == ENOENT && make_bak_dir(buf) == 0) {
|
||||
if (do_mkdir(buf, file->mode) < 0)
|
||||
save_errno = errno ? errno : save_errno;
|
||||
else
|
||||
save_errno = 0;
|
||||
}
|
||||
if (save_errno) {
|
||||
rsyserr(FINFO, save_errno, "mkdir %s failed",
|
||||
full_fname(buf));
|
||||
}
|
||||
}
|
||||
|
||||
ret_code = do_rmdir(fname);
|
||||
@@ -278,11 +303,18 @@ static int keep_backup(const char *fname)
|
||||
kept = 1;
|
||||
} else {
|
||||
do_unlink(buf);
|
||||
if (do_symlink(sl, buf) < 0
|
||||
&& (errno != ENOENT || make_bak_dir(buf) < 0
|
||||
|| do_symlink(sl, buf) < 0)) {
|
||||
rsyserr(FERROR, errno, "link %s -> \"%s\"",
|
||||
full_fname(buf), sl);
|
||||
if (do_symlink(sl, buf) < 0) {
|
||||
int save_errno = errno ? errno : EINVAL; /* 0 paranoia */
|
||||
if (errno == ENOENT && make_bak_dir(buf) == 0) {
|
||||
if (do_symlink(sl, buf) < 0)
|
||||
save_errno = errno ? errno : save_errno;
|
||||
else
|
||||
save_errno = 0;
|
||||
}
|
||||
if (save_errno) {
|
||||
rsyserr(FERROR, save_errno, "link %s -> \"%s\"",
|
||||
full_fname(buf), sl);
|
||||
}
|
||||
}
|
||||
do_unlink(fname);
|
||||
kept = 1;
|
||||
@@ -308,7 +340,9 @@ static int keep_backup(const char *fname)
|
||||
robust_unlink(fname); /* Just in case... */
|
||||
}
|
||||
}
|
||||
preserve_xattrs = 0;
|
||||
set_file_attrs(buf, file, NULL, fname, 0);
|
||||
preserve_xattrs = save_preserve_xattrs;
|
||||
unmake_file(file);
|
||||
|
||||
if (verbose > 1) {
|
||||
|
||||
@@ -27,7 +27,6 @@ extern int am_daemon;
|
||||
extern int io_error;
|
||||
extern int keep_partial;
|
||||
extern int got_xfer_error;
|
||||
extern int progress_is_active;
|
||||
extern char *partial_dir;
|
||||
extern char *logfile_name;
|
||||
|
||||
@@ -116,9 +115,6 @@ NORETURN void _exit_cleanup(int code, const char *file, int line)
|
||||
|
||||
exit_code = unmodified_code = code;
|
||||
|
||||
if (progress_is_active && exit_code && !am_server)
|
||||
rprintf(FINFO, "\n");
|
||||
|
||||
if (verbose > 3) {
|
||||
rprintf(FINFO,
|
||||
"_exit_cleanup(code=%d, file=%s, line=%d): entered\n",
|
||||
|
||||
@@ -5,7 +5,7 @@ AC_CONFIG_SRCDIR([byteorder.h])
|
||||
AC_CONFIG_HEADER(config.h)
|
||||
AC_PREREQ(2.59)
|
||||
|
||||
RSYNC_VERSION=3.0.3pre1
|
||||
RSYNC_VERSION=3.0.3pre3
|
||||
AC_SUBST(RSYNC_VERSION)
|
||||
AC_MSG_NOTICE([Configuring rsync $RSYNC_VERSION])
|
||||
|
||||
|
||||
64
flist.c
64
flist.c
@@ -638,7 +638,7 @@ static struct file_struct *recv_file_entry(struct file_list *flist,
|
||||
int alloc_len, basename_len, linkname_len;
|
||||
int extra_len = file_extra_cnt * EXTRA_LEN;
|
||||
int first_hlink_ndx = -1;
|
||||
OFF_T file_length;
|
||||
int64 file_length;
|
||||
const char *basename;
|
||||
struct file_struct *file;
|
||||
alloc_pool_t *pool;
|
||||
@@ -837,8 +837,14 @@ static struct file_struct *recv_file_entry(struct file_list *flist,
|
||||
if (always_checksum && S_ISREG(mode))
|
||||
extra_len += SUM_EXTRA_CNT * EXTRA_LEN;
|
||||
|
||||
#if SIZEOF_INT64 >= 8
|
||||
if (file_length > 0xFFFFFFFFu && S_ISREG(mode))
|
||||
extra_len += EXTRA_LEN;
|
||||
#endif
|
||||
if (file_length < 0) {
|
||||
rprintf(FERROR, "Offset underflow: file-length is negative\n");
|
||||
exit_cleanup(RERR_UNSUPPORTED);
|
||||
}
|
||||
|
||||
if (inc_recurse && S_ISDIR(mode)) {
|
||||
if (one_file_system) {
|
||||
@@ -871,10 +877,17 @@ static struct file_struct *recv_file_entry(struct file_list *flist,
|
||||
#endif
|
||||
file->modtime = (time_t)modtime;
|
||||
file->len32 = (uint32)file_length;
|
||||
#if SIZEOF_INT64 >= 8
|
||||
if (file_length > 0xFFFFFFFFu && S_ISREG(mode)) {
|
||||
#if SIZEOF_CAPITAL_OFF_T < 8
|
||||
rprintf(FERROR, "Offset overflow: attempted 64-bit file-length\n");
|
||||
exit_cleanup(RERR_UNSUPPORTED);
|
||||
#else
|
||||
file->flags |= FLAG_LENGTH64;
|
||||
OPT_EXTRA(file, 0)->unum = (uint32)(file_length >> 32);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
file->mode = mode;
|
||||
if (preserve_uid)
|
||||
F_OWNER(file) = uid;
|
||||
@@ -1009,7 +1022,12 @@ static struct file_struct *recv_file_entry(struct file_list *flist,
|
||||
* and performing extensive checks against global options.
|
||||
*
|
||||
* Returns a pointer to the new file struct, or NULL if there was an error
|
||||
* or this file should be excluded. */
|
||||
* or this file should be excluded.
|
||||
*
|
||||
* Note: Any error (here or in send_file_name) that results in the omission of
|
||||
* an existent source file from the file list should set
|
||||
* "io_error |= IOERR_GENERAL" to avoid deletion of the file from the
|
||||
* destination if --delete is on. */
|
||||
struct file_struct *make_file(const char *fname, struct file_list *flist,
|
||||
STRUCT_STAT *stp, int flags, int filter_level)
|
||||
{
|
||||
@@ -1023,10 +1041,10 @@ struct file_struct *make_file(const char *fname, struct file_list *flist,
|
||||
const char *basename;
|
||||
alloc_pool_t *pool;
|
||||
STRUCT_STAT st;
|
||||
int excl_ret;
|
||||
char *bp;
|
||||
|
||||
if (strlcpy(thisname, fname, sizeof thisname) >= sizeof thisname) {
|
||||
io_error |= IOERR_GENERAL;
|
||||
rprintf(FINFO, "skipping overly long name: %s\n", fname);
|
||||
return NULL;
|
||||
}
|
||||
@@ -1078,7 +1096,6 @@ struct file_struct *make_file(const char *fname, struct file_list *flist,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* backup.c calls us with filter_level set to NO_FILTERS. */
|
||||
if (filter_level == NO_FILTERS)
|
||||
goto skip_filters;
|
||||
|
||||
@@ -1106,17 +1123,7 @@ struct file_struct *make_file(const char *fname, struct file_list *flist,
|
||||
} else
|
||||
flags &= ~FLAG_CONTENT_DIR;
|
||||
|
||||
if (S_ISDIR(st.st_mode)) {
|
||||
if (flags & FLAG_DOTDIR_NAME) {
|
||||
/* A "." fname (or "/." fname in relative mode) is
|
||||
* never excluded. No other trailing-dotdir names
|
||||
* are possible. */
|
||||
excl_ret = 0;
|
||||
} else
|
||||
excl_ret = is_excluded(thisname, 1, filter_level);
|
||||
} else
|
||||
excl_ret = is_excluded(thisname, 0, filter_level);
|
||||
if (excl_ret) {
|
||||
if (is_excluded(thisname, S_ISDIR(st.st_mode) != 0, filter_level)) {
|
||||
if (ignore_perishable)
|
||||
non_perishable_cnt++;
|
||||
return NULL;
|
||||
@@ -1175,8 +1182,10 @@ struct file_struct *make_file(const char *fname, struct file_list *flist,
|
||||
linkname_len = 0;
|
||||
#endif
|
||||
|
||||
#if SIZEOF_CAPITAL_OFF_T >= 8
|
||||
if (st.st_size > 0xFFFFFFFFu && S_ISREG(st.st_mode))
|
||||
extra_len += EXTRA_LEN;
|
||||
#endif
|
||||
|
||||
#if EXTRA_ROUNDING > 0
|
||||
if (extra_len & (EXTRA_ROUNDING * EXTRA_LEN))
|
||||
@@ -1221,10 +1230,12 @@ struct file_struct *make_file(const char *fname, struct file_list *flist,
|
||||
file->flags = flags;
|
||||
file->modtime = st.st_mtime;
|
||||
file->len32 = (uint32)st.st_size;
|
||||
#if SIZEOF_CAPITAL_OFF_T >= 8
|
||||
if (st.st_size > 0xFFFFFFFFu && S_ISREG(st.st_mode)) {
|
||||
file->flags |= FLAG_LENGTH64;
|
||||
OPT_EXTRA(file, 0)->unum = (uint32)(st.st_size >> 32);
|
||||
}
|
||||
#endif
|
||||
file->mode = st.st_mode;
|
||||
if (uid_ndx) /* Check uid_ndx instead of preserve_uid for del support */
|
||||
F_OWNER(file) = st.st_uid;
|
||||
@@ -1336,15 +1347,19 @@ static struct file_struct *send_file_name(int f, struct file_list *flist,
|
||||
if (preserve_acls && !S_ISLNK(file->mode)) {
|
||||
sx.st.st_mode = file->mode;
|
||||
sx.acc_acl = sx.def_acl = NULL;
|
||||
if (get_acl(fname, &sx) < 0)
|
||||
if (get_acl(fname, &sx) < 0) {
|
||||
io_error |= IOERR_GENERAL;
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#ifdef SUPPORT_XATTRS
|
||||
if (preserve_xattrs) {
|
||||
sx.xattr = NULL;
|
||||
if (get_xattr(fname, &sx) < 0)
|
||||
if (get_xattr(fname, &sx) < 0) {
|
||||
io_error |= IOERR_GENERAL;
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -1853,7 +1868,7 @@ struct file_list *send_file_list(int f, int argc, char *argv[])
|
||||
int64 start_write;
|
||||
int use_ff_fd = 0;
|
||||
int disable_buffering;
|
||||
int arg_flags, flags = recurse ? FLAG_CONTENT_DIR : 0;
|
||||
int flags = recurse ? FLAG_CONTENT_DIR : 0;
|
||||
int reading_remotely = filesfrom_host != NULL;
|
||||
int rl_flags = (reading_remotely ? 0 : RL_DUMP_COMMENTS)
|
||||
#ifdef ICONV_OPTION
|
||||
@@ -2035,6 +2050,11 @@ struct file_list *send_file_list(int f, int argc, char *argv[])
|
||||
continue;
|
||||
}
|
||||
|
||||
/* A dot-dir should not be excluded! */
|
||||
if (name_type != DOTDIR_NAME
|
||||
&& is_excluded(fbuf, S_ISDIR(st.st_mode) != 0, ALL_FILTERS))
|
||||
continue;
|
||||
|
||||
if (S_ISDIR(st.st_mode) && !xfer_dirs) {
|
||||
rprintf(FINFO, "skipping directory %s\n", fbuf);
|
||||
continue;
|
||||
@@ -2060,13 +2080,11 @@ struct file_list *send_file_list(int f, int argc, char *argv[])
|
||||
if (one_file_system)
|
||||
filesystem_dev = st.st_dev;
|
||||
|
||||
arg_flags = name_type == DOTDIR_NAME ? FLAG_DOTDIR_NAME : 0;
|
||||
|
||||
if (recurse || (xfer_dirs && name_type != NORMAL_NAME)) {
|
||||
struct file_struct *file;
|
||||
arg_flags |= FLAG_TOP_DIR | FLAG_CONTENT_DIR;
|
||||
file = send_file_name(f, flist, fbuf, &st,
|
||||
arg_flags | flags, ALL_FILTERS);
|
||||
FLAG_TOP_DIR | FLAG_CONTENT_DIR | flags,
|
||||
NO_FILTERS);
|
||||
if (!file)
|
||||
continue;
|
||||
if (inc_recurse) {
|
||||
@@ -2080,7 +2098,7 @@ struct file_list *send_file_list(int f, int argc, char *argv[])
|
||||
} else
|
||||
send_if_directory(f, flist, file, fbuf, len, flags);
|
||||
} else
|
||||
send_file_name(f, flist, fbuf, &st, arg_flags | flags, ALL_FILTERS);
|
||||
send_file_name(f, flist, fbuf, &st, flags, NO_FILTERS);
|
||||
}
|
||||
|
||||
gettimeofday(&end_tv, NULL);
|
||||
|
||||
77
generator.c
77
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;
|
||||
}
|
||||
@@ -1432,6 +1444,7 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
|
||||
if (j == -2) {
|
||||
itemizing = 0;
|
||||
code = FNONE;
|
||||
statret = 1;
|
||||
} else if (j >= 0)
|
||||
statret = 1;
|
||||
}
|
||||
@@ -1454,6 +1467,10 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
|
||||
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);
|
||||
@@ -1868,15 +1885,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;
|
||||
}
|
||||
@@ -1929,18 +1952,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);
|
||||
@@ -2179,7 +2215,10 @@ void generate_files(int f_out, const char *local_name)
|
||||
|
||||
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
|
||||
|
||||
@@ -104,7 +104,9 @@ void *hashtable_find(struct hashtable *tbl, int64 key, int allocate_if_missing)
|
||||
a = b = c = 0xdeadbeef + (8 << 2);
|
||||
|
||||
#define rot(x,k) (((x)<<(k)) ^ ((x)>>(32-(k))))
|
||||
#if SIZEOF_INT64 >= 8
|
||||
b += (uint32)(key >> 32);
|
||||
#endif
|
||||
a += (uint32)key;
|
||||
c ^= b; c -= rot(b, 14);
|
||||
a ^= c; a -= rot(c, 11);
|
||||
|
||||
6
log.c
6
log.c
@@ -37,6 +37,7 @@ extern int protocol_version;
|
||||
extern int preserve_times;
|
||||
extern int uid_ndx;
|
||||
extern int gid_ndx;
|
||||
extern int progress_is_active;
|
||||
extern int stdout_format_has_i;
|
||||
extern int stdout_format_has_o_or_i;
|
||||
extern int logfile_format_has_i;
|
||||
@@ -320,6 +321,11 @@ void rwrite(enum logcode code, const char *buf, int len, int is_utf8)
|
||||
exit_cleanup(RERR_MESSAGEIO);
|
||||
}
|
||||
|
||||
if (progress_is_active && !am_server) {
|
||||
fputc('\n', f);
|
||||
progress_is_active = 0;
|
||||
}
|
||||
|
||||
trailing_CR_or_NL = len && (buf[len-1] == '\n' || buf[len-1] == '\r')
|
||||
? buf[--len] : 0;
|
||||
|
||||
|
||||
7
main.c
7
main.c
@@ -509,12 +509,13 @@ static char *get_local_name(struct file_list *flist, char *dest_path)
|
||||
|
||||
if (daemon_filter_list.head) {
|
||||
char *slash = strrchr(dest_path, '/');
|
||||
if (slash && slash[1] == '\0')
|
||||
if (slash && (slash[1] == '\0' || (slash[1] == '.' && slash[2] == '\0')))
|
||||
*slash = '\0';
|
||||
else
|
||||
slash = NULL;
|
||||
if (check_filter(&daemon_filter_list, FLOG, dest_path, 0) < 0
|
||||
|| check_filter(&daemon_filter_list, FLOG, dest_path, 1) < 0) {
|
||||
if ((*dest_path != '.' || dest_path[1] != '\0')
|
||||
&& (check_filter(&daemon_filter_list, FLOG, dest_path, 0) < 0
|
||||
|| check_filter(&daemon_filter_list, FLOG, dest_path, 1) < 0)) {
|
||||
rprintf(FERROR, "skipping daemon-excluded destination \"%s\"\n",
|
||||
dest_path);
|
||||
exit_cleanup(RERR_FILESELECT);
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
Summary: A fast, versatile, remote (and local) file-copying tool
|
||||
Name: rsync
|
||||
Version: 3.0.3
|
||||
%define fullversion %{version}pre1
|
||||
Release: 0.1.pre1
|
||||
%define fullversion %{version}pre3
|
||||
Release: 0.1.pre3
|
||||
%define srcdir src-previews
|
||||
Group: Applications/Internet
|
||||
Source0: http://rsync.samba.org/ftp/rsync/%{srcdir}/rsync-%{fullversion}.tar.gz
|
||||
@@ -66,8 +66,8 @@ rm -rf $RPM_BUILD_ROOT
|
||||
%{_mandir}/man5/rsyncd.conf.5*
|
||||
|
||||
%changelog
|
||||
* Wed May 07 2008 Wayne Davison <wayned@samba.org>
|
||||
Released 3.0.3pre1.
|
||||
* Sun Jun 22 2008 Wayne Davison <wayned@samba.org>
|
||||
Released 3.0.3pre3.
|
||||
|
||||
* Fri Mar 21 2008 Wayne Davison <wayned@samba.org>
|
||||
Added installation of /etc/xinetd.d/rsync file and some commented-out
|
||||
|
||||
@@ -111,13 +111,13 @@ static void rprint_progress(OFF_T ofs, OFF_T size, struct timeval *now,
|
||||
stats.num_transferred_files,
|
||||
stats.num_files - current_file_index - 1,
|
||||
stats.num_files);
|
||||
progress_is_active = 0;
|
||||
} else {
|
||||
} else
|
||||
strlcpy(eol, "\r", sizeof eol);
|
||||
progress_is_active = 1;
|
||||
}
|
||||
progress_is_active = 0;
|
||||
rprintf(FCLIENT, "%12s %3d%% %7.2f%s %s%s",
|
||||
human_num(ofs), pct, rate, units, rembuf, eol);
|
||||
if (!is_last)
|
||||
progress_is_active = 1;
|
||||
}
|
||||
|
||||
void set_current_file_index(struct file_struct *file, int ndx)
|
||||
|
||||
8
rsync.c
8
rsync.c
@@ -561,8 +561,12 @@ int finish_transfer(const char *fname, const char *fnametmp,
|
||||
goto do_set_file_attrs;
|
||||
}
|
||||
|
||||
if (make_backups > 0 && overwriting_basis && !make_backup(fname))
|
||||
return 1;
|
||||
if (make_backups > 0 && overwriting_basis) {
|
||||
if (!make_backup(fname))
|
||||
return 1;
|
||||
if (fnamecmp == fname)
|
||||
fnamecmp = get_backup_name(fname);
|
||||
}
|
||||
|
||||
/* Change permissions before putting the file into place. */
|
||||
set_file_attrs(fnametmp, file, NULL, fnamecmp,
|
||||
|
||||
3
rsync.h
3
rsync.h
@@ -83,7 +83,6 @@
|
||||
/* These flags are passed to functions but not stored. */
|
||||
|
||||
#define FLAG_DIVERT_DIRS (1<<16)/* sender */
|
||||
#define FLAG_DOTDIR_NAME (1<<17)/* sender */
|
||||
|
||||
#define BITS_SET(val,bits) (((val) & (bits)) == (bits))
|
||||
#define BITS_SETnUNSET(val,onbits,offbits) (((val) & ((onbits)|(offbits))) == (onbits))
|
||||
@@ -498,10 +497,12 @@ typedef unsigned int size_t;
|
||||
#if SIZEOF_OFF_T == 8 || !SIZEOF_OFF64_T || !defined HAVE_STRUCT_STAT64
|
||||
#define OFF_T off_t
|
||||
#define STRUCT_STAT struct stat
|
||||
#define SIZEOF_CAPITAL_OFF_T SIZEOF_OFF_T
|
||||
#else
|
||||
#define OFF_T off64_t
|
||||
#define STRUCT_STAT struct stat64
|
||||
#define USE_STAT64_FUNCS 1
|
||||
#define SIZEOF_CAPITAL_OFF_T SIZEOF_OFF64_T
|
||||
#endif
|
||||
|
||||
/* CAVEAT: on some systems, int64 will really be a 32-bit integer IFF
|
||||
|
||||
50
rsync.yo
50
rsync.yo
@@ -1,5 +1,5 @@
|
||||
mailto(rsync-bugs@samba.org)
|
||||
manpage(rsync)(1)(7 May 2008)()()
|
||||
manpage(rsync)(1)(22 Jun 2008)()()
|
||||
manpagename(rsync)(a fast, versatile, remote (and local) file-copying tool)
|
||||
manpagesynopsis()
|
||||
|
||||
@@ -697,13 +697,25 @@ date is on the objects. In other words, if the source has a directory
|
||||
where the destination has a file, the transfer would occur regardless of
|
||||
the timestamps.
|
||||
|
||||
dit(bf(--inplace)) This causes rsync not to create a new copy of the file
|
||||
and then move it into place. Instead rsync will overwrite the existing
|
||||
file, meaning that the rsync algorithm can't accomplish the full amount of
|
||||
network reduction it might be able to otherwise (since it does not yet try
|
||||
to sort data matches). One exception to this is if you combine the option
|
||||
with bf(--backup), since rsync is smart enough to use the backup file as the
|
||||
basis file for the transfer.
|
||||
dit(bf(--inplace)) This option changes how rsync transfers a file when the
|
||||
file's data needs to be updated: instead of the default method of creating
|
||||
a new copy of the file and moving it into place when it is complete, rsync
|
||||
instead writes the updated data directly to the destination file.
|
||||
|
||||
This has several effects: (1) in-use binaries cannot be updated (either the
|
||||
OS will prevent this from happening, or binaries that attempt to swap-in
|
||||
their data will misbehave or crash), (2) the file's data will be in an
|
||||
inconsistent state during the transfer, (3) a file's data may be left in an
|
||||
inconsistent state after the transfer if the transfer is interrupted or if
|
||||
an update fails, (4) a file that does not have write permissions can not be
|
||||
updated, and (5) the efficiency of rsync's delta-transfer algorithm may be
|
||||
reduced if some data in the destination file is overwritten before it can
|
||||
be copied to a position later in the file (one exception to this is if you
|
||||
combine this option with bf(--backup), since rsync is smart enough to use
|
||||
the backup file as the basis file for the transfer).
|
||||
|
||||
WARNING: you should not use this option to update files that are being
|
||||
accessed by others, so be careful when choosing to use this for a copy.
|
||||
|
||||
This option is useful for transfer of large files with block-based changes
|
||||
or appended data, and also on systems that are disk bound, not network
|
||||
@@ -714,12 +726,6 @@ the file), but conflicts with bf(--partial-dir) and bf(--delay-updates).
|
||||
Prior to rsync 2.6.4 bf(--inplace) was also incompatible with bf(--compare-dest)
|
||||
and bf(--link-dest).
|
||||
|
||||
WARNING: The file's data will be in an inconsistent state during the
|
||||
transfer (and possibly afterward if the transfer gets interrupted), so you
|
||||
should not use this option to update files that are in use. Also note that
|
||||
rsync will be unable to update a file in-place that is not writable by the
|
||||
receiving user.
|
||||
|
||||
dit(bf(--append)) This causes rsync to update a file by appending data onto
|
||||
the end of the file, which presumes that the data that already exists on
|
||||
the receiving side is identical with the start of the file on the sending
|
||||
@@ -986,7 +992,7 @@ with the files and update them on the remote system. Note that if this
|
||||
option is not used, the optimization that excludes files that have not been
|
||||
modified cannot be effective; in other words, a missing bf(-t) or bf(-a) will
|
||||
cause the next transfer to behave as if it used bf(-I), causing all files to be
|
||||
updated (though the rsync algorithm will make the update fairly efficient
|
||||
updated (though rsync's delta-transfer algorithm will make the update fairly efficient
|
||||
if the files haven't actually changed, you're much better off using bf(-t)).
|
||||
|
||||
dit(bf(-O, --omit-dir-times)) This tells rsync to omit directories when
|
||||
@@ -1058,7 +1064,7 @@ the "bytes sent", "bytes received", "literal data", and "matched data"
|
||||
statistics are too small, and the "speedup" value is equivalent to a run
|
||||
where no file transfers are needed.
|
||||
|
||||
dit(bf(-W, --whole-file)) With this option the delta-transfer algorithm
|
||||
dit(bf(-W, --whole-file)) With this option rsync's delta-transfer algorithm
|
||||
is not used and the whole file is sent as-is instead. The transfer may be
|
||||
faster if this option is used when the bandwidth between the source and
|
||||
destination machines is higher than the bandwidth to disk (especially when the
|
||||
@@ -1225,7 +1231,7 @@ transferring small, junk files.
|
||||
See the bf(--max-size) option for a description of SIZE.
|
||||
|
||||
dit(bf(-B, --block-size=BLOCKSIZE)) This forces the block size used in
|
||||
the rsync algorithm to a fixed value. It is normally selected based on
|
||||
rsync's delta-transfer algorithm to a fixed value. It is normally selected based on
|
||||
the size of each file being updated. See the technical report for details.
|
||||
|
||||
dit(bf(-e, --rsh=COMMAND)) This option allows you to choose an alternative
|
||||
@@ -1759,14 +1765,14 @@ For a list of the possible escape characters, see the "log format" setting
|
||||
in the rsyncd.conf manpage.
|
||||
|
||||
dit(bf(--stats)) This tells rsync to print a verbose set of statistics
|
||||
on the file transfer, allowing you to tell how effective the rsync
|
||||
on the file transfer, allowing you to tell how effective rsync's delta-transfer
|
||||
algorithm is for your data.
|
||||
|
||||
The current statistics are as follows: quote(itemization(
|
||||
it() bf(Number of files) is the count of all "files" (in the generic
|
||||
sense), which includes directories, symlinks, etc.
|
||||
it() bf(Number of files transferred) is the count of normal files that
|
||||
were updated via the rsync algorithm, which does not include created
|
||||
were updated via rsync's delta-transfer algorithm, which does not include created
|
||||
dirs, symlinks, etc.
|
||||
it() bf(Total file size) is the total sum of all file sizes in the transfer.
|
||||
This does not count any size for directories or special files, but does
|
||||
@@ -1827,7 +1833,7 @@ after it has served its purpose.
|
||||
Note that if bf(--whole-file) is specified (or implied), any partial-dir
|
||||
file that is found for a file that is being updated will simply be removed
|
||||
(since
|
||||
rsync is sending files without using the delta transfer algorithm).
|
||||
rsync is sending files without using rsync's delta-transfer algorithm).
|
||||
|
||||
Rsync will create the em(DIR) if it is missing (just the last dir -- not
|
||||
the whole path). This makes it easy to use a relative path (such as
|
||||
@@ -1945,7 +1951,7 @@ sender's file, which is being reconstructed at a rate of 110.64 kilobytes
|
||||
per second, and the transfer will finish in 4 seconds if the current rate
|
||||
is maintained until the end.
|
||||
|
||||
These statistics can be misleading if the delta transfer algorithm is
|
||||
These statistics can be misleading if rsync's delta-transfer algorithm is
|
||||
in use. For example, if the sender's file consists of the basis file
|
||||
followed by additional data, the reported rate will probably drop
|
||||
dramatically when the receiver gets to the literal data, and the transfer
|
||||
@@ -2876,7 +2882,7 @@ url(http://rsync.samba.org/)(http://rsync.samba.org/)
|
||||
|
||||
manpagesection(VERSION)
|
||||
|
||||
This man page is current for version 3.0.3pre1 of rsync.
|
||||
This man page is current for version 3.0.3pre3 of rsync.
|
||||
|
||||
manpagesection(INTERNAL OPTIONS)
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
mailto(rsync-bugs@samba.org)
|
||||
manpage(rsyncd.conf)(5)(7 May 2008)()()
|
||||
manpage(rsyncd.conf)(5)(22 Jun 2008)()()
|
||||
manpagename(rsyncd.conf)(configuration file for rsync in daemon mode)
|
||||
manpagesynopsis()
|
||||
|
||||
@@ -700,7 +700,7 @@ url(http://rsync.samba.org/)(http://rsync.samba.org/)
|
||||
|
||||
manpagesection(VERSION)
|
||||
|
||||
This man page is current for version 3.0.3pre1 of rsync.
|
||||
This man page is current for version 3.0.3pre3 of rsync.
|
||||
|
||||
manpagesection(CREDITS)
|
||||
|
||||
|
||||
@@ -155,10 +155,10 @@ RSYNC="$rsync_bin $*"
|
||||
#RSYNC="valgrind $rsync_bin $*"
|
||||
|
||||
TLS_ARGS=''
|
||||
if egrep '^#define HAVE_LUTIMES 1' "$srcdir/config.h" >/dev/null; then
|
||||
if egrep '^#define HAVE_LUTIMES 1' config.h >/dev/null; then
|
||||
TLS_ARGS="$TLS_ARGS -l"
|
||||
fi
|
||||
if egrep '#undef CHOWN_MODIFIES_SYMLINK' "$srcdir/config.h" >/dev/null; then
|
||||
if egrep '#undef CHOWN_MODIFIES_SYMLINK' config.h >/dev/null; then
|
||||
TLS_ARGS="$TLS_ARGS -L"
|
||||
fi
|
||||
|
||||
@@ -238,7 +238,10 @@ prep_scratch() {
|
||||
# Get rid of default ACLs and dir-setgid to avoid confusing some tests.
|
||||
$setfacl_nodef "$scratchdir" || true
|
||||
chmod g-s "$scratchdir"
|
||||
ln -s "$srcdir" "$scratchdir/src"
|
||||
case "$srcdir" in
|
||||
/*) ln -s "$srcdir" "$scratchdir/src" ;;
|
||||
*) ln -s "$TOOLDIR/$srcdir" "$scratchdir/src" ;;
|
||||
esac
|
||||
return 0
|
||||
}
|
||||
|
||||
|
||||
6
t_stub.c
6
t_stub.c
@@ -26,6 +26,7 @@ int module_id = -1;
|
||||
int relative_paths = 0;
|
||||
int human_readable = 0;
|
||||
int module_dirlen = 0;
|
||||
int preserve_xattrs = 0;
|
||||
mode_t orig_umask = 002;
|
||||
char *partial_dir;
|
||||
char *module_dir;
|
||||
@@ -69,6 +70,11 @@ struct filter_list_struct daemon_filter_list;
|
||||
return -1;
|
||||
}
|
||||
|
||||
int copy_xattrs(UNUSED(const char *source), UNUSED(const char *dest))
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
char *lp_name(UNUSED(int mod))
|
||||
{
|
||||
return NULL;
|
||||
|
||||
@@ -36,7 +36,7 @@ for fn in deep/name1 deep/name2; do
|
||||
done
|
||||
|
||||
echo deleted-file >"$todir/dname"
|
||||
cp -p "$todir/dname" "$chkdir"
|
||||
cp_touch "$todir/dname" "$chkdir"
|
||||
|
||||
checkit "$RSYNC -avv --no-whole-file --delete-delay \
|
||||
--backup --backup-dir='$bakdir' '$fromdir/' '$todir/'" "$fromdir" "$todir" \
|
||||
|
||||
@@ -19,15 +19,23 @@
|
||||
# checking the log file
|
||||
# password authentication
|
||||
|
||||
# TODO: Put the common framework in a common file, so that we can have
|
||||
# subtests fail and keep going.
|
||||
|
||||
. "$suitedir/rsync.fns"
|
||||
|
||||
chkfile="$scratchdir/rsync.chk"
|
||||
outfile="$scratchdir/rsync.out"
|
||||
|
||||
SSH="src/support/lsh --no-cd"
|
||||
DIR_REPL='s/^\(d[^ ]*\) *[0-9][0-9]* /\1 DIR /'
|
||||
LS_REPL='s;[0-9][0-9][0-9][0-9]/[0-9][0-9]/[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9];####/##/## ##:##:##;'
|
||||
|
||||
build_rsyncd_conf
|
||||
|
||||
makepath "$fromdir/foo" "$fromdir/bar/baz"
|
||||
makepath "$todir"
|
||||
echo one >"$fromdir/foo/one"
|
||||
echo two >"$fromdir/bar/two"
|
||||
echo three >"$fromdir/bar/baz/three"
|
||||
|
||||
cd "$scratchdir"
|
||||
|
||||
ln -s test-rsyncd.conf rsyncd.conf
|
||||
@@ -46,4 +54,36 @@ $RSYNC -ve "$SSH" --rsync-path="$RSYNC$confopt" localhost::
|
||||
RSYNC_CONNECT_PROG="$RSYNC --config=$conf --daemon"
|
||||
export RSYNC_CONNECT_PROG
|
||||
|
||||
$RSYNC -v localhost::
|
||||
$RSYNC -v localhost:: \
|
||||
| tee "$outfile"
|
||||
# These have a space-padded 15-char name, then a tab, then a comment.
|
||||
sed 's/NOCOMMENT//' <<EOT >"$chkfile"
|
||||
test-from r/o
|
||||
test-to r/w
|
||||
test-scratch NOCOMMENT
|
||||
EOT
|
||||
diff $diffopt "$chkfile" "$outfile" || test_fail "test 1 failed"
|
||||
|
||||
$RSYNC -r localhost::test-hidden \
|
||||
| sed "$DIR_REPL" | sed "$LS_REPL" \
|
||||
| tee "$outfile"
|
||||
cat <<EOT >"$chkfile"
|
||||
drwxr-xr-x DIR ####/##/## ##:##:## .
|
||||
drwxr-xr-x DIR ####/##/## ##:##:## bar
|
||||
-rw-r--r-- 4 ####/##/## ##:##:## bar/two
|
||||
drwxr-xr-x DIR ####/##/## ##:##:## bar/baz
|
||||
-rw-r--r-- 6 ####/##/## ##:##:## bar/baz/three
|
||||
drwxr-xr-x DIR ####/##/## ##:##:## foo
|
||||
-rw-r--r-- 4 ####/##/## ##:##:## foo/one
|
||||
EOT
|
||||
diff $diffopt "$chkfile" "$outfile" || test_fail "test 2 failed"
|
||||
|
||||
$RSYNC -r localhost::test-from/f* \
|
||||
| sed "$DIR_REPL" | sed "$LS_REPL" \
|
||||
| tee "$outfile"
|
||||
cat <<EOT >"$chkfile"
|
||||
drwxr-xr-x DIR ####/##/## ##:##:## foo
|
||||
-rw-r--r-- 4 ####/##/## ##:##:## foo/one
|
||||
EOT
|
||||
diff $diffopt "$chkfile" "$outfile" || test_fail "test 3 failed"
|
||||
|
||||
|
||||
@@ -76,7 +76,8 @@ mknod "$fromdir/block2" b 42 73 || test_skipped "Can't create block device node"
|
||||
mknod "$fromdir/block3" b 105 73 || test_skipped "Can't create block device node"
|
||||
ln "$fromdir/block3" "$fromdir/block2.5" || echo "Skipping hard-linked device test..."
|
||||
mkfifo "$fromdir/fifo" || mknod "$fromdir/fifo" p || test_skipped "Can't run mkfifo"
|
||||
touch -r "$fromdir/block" "$fromdir/block2"
|
||||
# Work around time rounding/truncating issue by touching both files.
|
||||
touch -r "$fromdir/block" "$fromdir/block" "$fromdir/block2"
|
||||
|
||||
$RSYNC -ai "$fromdir/block" "$todir/block2" \
|
||||
| tee "$outfile"
|
||||
|
||||
@@ -153,13 +153,13 @@ checkit "$RSYNC -avvC --filter='merge $excl' --delete-excluded \
|
||||
|
||||
rm "$chkdir"/foo/file1
|
||||
rm "$chkdir"/bar/down/to/bar/baz/*.deep
|
||||
cp -p "$fromdir"/bar/down/to/foo/*.junk "$chkdir"/bar/down/to/foo
|
||||
cp -p "$fromdir"/bar/down/to/foo/to "$chkdir"/bar/down/to/foo
|
||||
cp_touch "$fromdir"/bar/down/to/foo/*.junk "$chkdir"/bar/down/to/foo
|
||||
cp_touch "$fromdir"/bar/down/to/foo/to "$chkdir"/bar/down/to/foo
|
||||
|
||||
$RSYNC -av --existing -f 'show .filt*' -f 'hide,! */' --del "$fromdir/" "$todir/"
|
||||
|
||||
echo retained >"$todir"/bar/down/to/bar/baz/nodel.deep
|
||||
cp -p "$todir"/bar/down/to/bar/baz/nodel.deep "$chkdir"/bar/down/to/bar/baz
|
||||
cp_touch "$todir"/bar/down/to/bar/baz/nodel.deep "$chkdir"/bar/down/to/bar/baz
|
||||
|
||||
$RSYNC -av --existing --filter='-! */' "$fromdir/" "$chkdir/"
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@ mkdir "$fromdir"
|
||||
mkdir "$todir"
|
||||
|
||||
cp -p "$srcdir"/rsync.c "$fromdir"/rsync.c
|
||||
cp -p "$fromdir"/rsync.c "$todir"/rsync2.c
|
||||
cp_touch "$fromdir"/rsync.c "$todir"/rsync2.c
|
||||
sleep 1
|
||||
|
||||
# Let's do it!
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
|
||||
. "$suitedir/rsync.fns"
|
||||
|
||||
SSH=support/lsh
|
||||
SSH="$scratchdir/src/support/lsh"
|
||||
|
||||
outfile="$scratchdir/rsync.out"
|
||||
|
||||
|
||||
@@ -28,8 +28,7 @@ ln "$fromdir/foo/config1" "$fromdir/foo/extra"
|
||||
rm -f "$to2dir"
|
||||
|
||||
# Check if rsync is set to hard-link symlinks.
|
||||
confile=`echo "$scratchdir" | sed 's;/testtmp/itemize$;/config.h;'`
|
||||
if egrep '^#define CAN_HARDLINK_SYMLINK 1' "$confile" >/dev/null; then
|
||||
if egrep '^#define CAN_HARDLINK_SYMLINK 1' config.h >/dev/null; then
|
||||
L=hL
|
||||
else
|
||||
L=cL
|
||||
|
||||
@@ -19,15 +19,15 @@ mkdir from2/sub1 from3/sub1
|
||||
mkdir from3/sub2 from1/dir-and-not-dir
|
||||
mkdir chk chk/sub1 chk/sub2 chk/dir-and-not-dir
|
||||
echo "one" >from1/one
|
||||
cp -p from1/one from2/one
|
||||
cp -p from1/one from3/one
|
||||
cp_touch from1/one from2/one
|
||||
cp_touch from1/one from3/one
|
||||
echo "two" >from1/two
|
||||
echo "three" >from2/three
|
||||
echo "four" >from3/four
|
||||
echo "five" >from1/five
|
||||
echo "six" >from3/six
|
||||
echo "sub1" >from2/sub1/uno
|
||||
cp -p from2/sub1/uno from3/sub1/uno
|
||||
cp_touch from2/sub1/uno from3/sub1/uno
|
||||
echo "sub2" >from3/sub1/dos
|
||||
echo "sub3" >from2/sub1/tres
|
||||
echo "subby" >from3/sub2/subby
|
||||
@@ -36,11 +36,11 @@ echo "not-dir" >from3/dir-and-not-dir
|
||||
echo "arg-test" >deep/arg-test
|
||||
echo "shallow" >shallow
|
||||
|
||||
cp -p from1/one from1/two from2/three from3/four from1/five from3/six chk
|
||||
cp -p deep/arg-test shallow chk
|
||||
cp -p from1/dir-and-not-dir/inside chk/dir-and-not-dir
|
||||
cp -p from2/sub1/uno from3/sub1/dos from2/sub1/tres chk/sub1
|
||||
cp -p from3/sub2/subby chk/sub2
|
||||
cp_touch from1/one from1/two from2/three from3/four from1/five from3/six chk
|
||||
cp_touch deep/arg-test shallow chk
|
||||
cp_touch from1/dir-and-not-dir/inside chk/dir-and-not-dir
|
||||
cp_touch from2/sub1/uno from3/sub1/dos from2/sub1/tres chk/sub1
|
||||
cp_touch from3/sub2/subby chk/sub2
|
||||
|
||||
# Make sure that time has moved on.
|
||||
sleep 1
|
||||
|
||||
@@ -52,6 +52,29 @@ runtest() {
|
||||
fi
|
||||
}
|
||||
|
||||
set_cp_destdir() {
|
||||
while test $# -gt 1; do
|
||||
shift
|
||||
done
|
||||
destdir="$1"
|
||||
}
|
||||
|
||||
# Perform a "cp -p", making sure that timestamps are really the same,
|
||||
# even if the copy rounded microsecond times on the destination file.
|
||||
cp_touch() {
|
||||
cp -p "${@}" || test_fail "cp -p failed"
|
||||
if test $# -gt 2 -o -d "$2"; then
|
||||
set_cp_destdir "${@}" # sets destdir var
|
||||
while test $# -gt 1; do
|
||||
destname="$destdir/`basename $1`"
|
||||
touch -r "$destname" "$1" "$destname"
|
||||
shift
|
||||
done
|
||||
else
|
||||
touch -r "$2" "$1" "$2"
|
||||
fi
|
||||
}
|
||||
|
||||
# Call this if you want to filter out verbose messages (-v or -vv) from
|
||||
# the output of an rsync run (whittling the output down to just the file
|
||||
# messages). This isn't needed if you use -i without -v.
|
||||
@@ -244,7 +267,7 @@ hosts allow = localhost 127.0.0.0/24 192.168.0.0/16 10.0.0.0/8 $hostname
|
||||
log file = $logfile
|
||||
log format = %i %h [%a] %m (%u) %l %f%L
|
||||
transfer logging = yes
|
||||
exclude = foobar.baz
|
||||
exclude = ? foobar.baz
|
||||
max verbosity = 9
|
||||
uid = 0
|
||||
gid = 0
|
||||
@@ -252,14 +275,20 @@ gid = 0
|
||||
[test-from]
|
||||
path = $fromdir
|
||||
read only = yes
|
||||
comment = r/o
|
||||
|
||||
[test-to]
|
||||
path = $todir
|
||||
read only = no
|
||||
comment = r/w
|
||||
|
||||
[test-scratch]
|
||||
path = $scratchdir
|
||||
read only = no
|
||||
|
||||
[test-hidden]
|
||||
path = $fromdir
|
||||
list = no
|
||||
EOF
|
||||
|
||||
# Build a helper script to ignore exit code 23
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
|
||||
. "$suitedir/rsync.fns"
|
||||
|
||||
SSH=support/lsh
|
||||
SSH="$scratchdir/src/support/lsh"
|
||||
|
||||
if test x"$rsync_enable_ssh_tests" = xyes; then
|
||||
if type ssh >/dev/null ; then
|
||||
|
||||
@@ -46,7 +46,7 @@ echo deeper >"$fromdir/foo/bar/file5"
|
||||
|
||||
makepath "$chkdir/foo"
|
||||
echo wow >"$chkdir/file1"
|
||||
cp -p "$fromdir/foo/file3" "$chkdir/foo"
|
||||
cp_touch "$fromdir/foo/file3" "$chkdir/foo"
|
||||
|
||||
files='foo file0 file1 file2 foo/file3 file4 foo/bar/file5'
|
||||
|
||||
@@ -64,6 +64,10 @@ xset user.foo foo file2
|
||||
xset user.bar bar file2
|
||||
xset user.long 'a long attribute for our new file that tests to ensure that this works' file2
|
||||
|
||||
xset user.dir1 'need to test directory xattrs too' foo
|
||||
xset user.dir2 'another xattr' foo
|
||||
xset user.dir3 'this is one last one for the moment' foo
|
||||
|
||||
xset user.foo 'new foo' foo/file3 foo/bar/file5
|
||||
xset user.bar 'new bar' foo/file3 foo/bar/file5
|
||||
xset user.long 'this is also a long attribute that will be truncated in the initial data send' foo/file3 foo/bar/file5
|
||||
@@ -91,12 +95,12 @@ cd "$todir"
|
||||
xls $files | diff $diffopt "$scratchdir/xattrs.txt" -
|
||||
|
||||
cd "$fromdir"
|
||||
rm -rf "$todir"
|
||||
|
||||
xset user.nice 'this is nice, but different' file1
|
||||
|
||||
xls $files >"$scratchdir/xattrs.txt"
|
||||
|
||||
rm -rf "$todir"
|
||||
|
||||
checkit "$RSYNC -aiX --fake-super --link-dest=../chk . ../to" "$chkdir" "$todir"
|
||||
|
||||
cd "$todir"
|
||||
@@ -109,5 +113,31 @@ if [ -s "$scratchdir/ls-diff" ]; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
cd "$fromdir"
|
||||
rm -rf "$todir" "$chkdir"
|
||||
|
||||
rsync -aX file1 file2
|
||||
rsync -aX file1 file2 ../chk/
|
||||
rsync -aX --del ../chk/ .
|
||||
rsync -aX file1 ../lnk/
|
||||
|
||||
xls file1 file2 >"$scratchdir/xattrs.txt"
|
||||
|
||||
checkit "$RSYNC -aiiX --copy-dest=../lnk . ../to" "$chkdir" "$todir"
|
||||
|
||||
cd "$todir"
|
||||
xls file1 file2 | diff $diffopt "$scratchdir/xattrs.txt" -
|
||||
|
||||
cd "$fromdir"
|
||||
rm "$todir/file2"
|
||||
|
||||
echo extra >file1
|
||||
rsync -aX . ../chk/
|
||||
|
||||
checkit "$RSYNC -aiiX . ../to" "$chkdir" "$todir"
|
||||
|
||||
cd "$todir"
|
||||
xls file1 file2 | diff $diffopt "$scratchdir/xattrs.txt" -
|
||||
|
||||
# The script would have aborted on error, so getting here means we've won.
|
||||
exit 0
|
||||
|
||||
43
util.c
43
util.c
@@ -29,6 +29,7 @@ extern int module_id;
|
||||
extern int modify_window;
|
||||
extern int relative_paths;
|
||||
extern int human_readable;
|
||||
extern int preserve_xattrs;
|
||||
extern char *module_dir;
|
||||
extern unsigned int module_dirlen;
|
||||
extern mode_t orig_umask;
|
||||
@@ -264,6 +265,8 @@ static int safe_read(int desc, char *ptr, size_t len)
|
||||
|
||||
/* Copy a file. If ofd < 0, copy_file unlinks and opens the "dest" file.
|
||||
* Otherwise, it just writes to and closes the provided file descriptor.
|
||||
* In either case, if --xattrs are being preserved, the dest file will
|
||||
* have its xattrs set from the source file.
|
||||
*
|
||||
* This is used in conjunction with the --temp-dir, --backup, and
|
||||
* --copy-dest options. */
|
||||
@@ -275,38 +278,54 @@ int copy_file(const char *source, const char *dest, int ofd,
|
||||
int len; /* Number of bytes read into `buf'. */
|
||||
|
||||
if ((ifd = do_open(source, O_RDONLY, 0)) < 0) {
|
||||
int save_errno = errno;
|
||||
rsyserr(FERROR_XFER, errno, "open %s", full_fname(source));
|
||||
errno = save_errno;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (ofd < 0) {
|
||||
if (robust_unlink(dest) && errno != ENOENT) {
|
||||
int save_errno = errno;
|
||||
rsyserr(FERROR_XFER, errno, "unlink %s", full_fname(dest));
|
||||
errno = save_errno;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ((ofd = do_open(dest, O_WRONLY | O_CREAT | O_TRUNC | O_EXCL, mode)) < 0
|
||||
&& (!create_bak_dir || errno != ENOENT || make_bak_dir(dest) < 0
|
||||
|| (ofd = do_open(dest, O_WRONLY | O_CREAT | O_TRUNC | O_EXCL, mode)) < 0)) {
|
||||
rsyserr(FERROR_XFER, errno, "open %s", full_fname(dest));
|
||||
close(ifd);
|
||||
return -1;
|
||||
if ((ofd = do_open(dest, O_WRONLY | O_CREAT | O_TRUNC | O_EXCL, mode)) < 0) {
|
||||
int save_errno = errno ? errno : EINVAL; /* 0 paranoia */
|
||||
if (create_bak_dir && errno == ENOENT && make_bak_dir(dest) == 0) {
|
||||
if ((ofd = do_open(dest, O_WRONLY | O_CREAT | O_TRUNC | O_EXCL, mode)) < 0)
|
||||
save_errno = errno ? errno : save_errno;
|
||||
else
|
||||
save_errno = 0;
|
||||
}
|
||||
if (save_errno) {
|
||||
rsyserr(FERROR_XFER, save_errno, "open %s", full_fname(dest));
|
||||
close(ifd);
|
||||
errno = save_errno;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
while ((len = safe_read(ifd, buf, sizeof buf)) > 0) {
|
||||
if (full_write(ofd, buf, len) < 0) {
|
||||
int save_errno = errno;
|
||||
rsyserr(FERROR_XFER, errno, "write %s", full_fname(dest));
|
||||
close(ifd);
|
||||
close(ofd);
|
||||
errno = save_errno;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (len < 0) {
|
||||
int save_errno = errno;
|
||||
rsyserr(FERROR_XFER, errno, "read %s", full_fname(source));
|
||||
close(ifd);
|
||||
close(ofd);
|
||||
errno = save_errno;
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -316,11 +335,18 @@ int copy_file(const char *source, const char *dest, int ofd,
|
||||
}
|
||||
|
||||
if (close(ofd) < 0) {
|
||||
int save_errno = errno;
|
||||
rsyserr(FERROR_XFER, errno, "close failed on %s",
|
||||
full_fname(dest));
|
||||
errno = save_errno;
|
||||
return -1;
|
||||
}
|
||||
|
||||
#ifdef SUPPORT_XATTRS
|
||||
if (preserve_xattrs)
|
||||
copy_xattrs(source, dest);
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -401,8 +427,11 @@ int robust_rename(const char *from, const char *to, const char *partialptr,
|
||||
switch (errno) {
|
||||
#ifdef ETXTBSY
|
||||
case ETXTBSY:
|
||||
if (robust_unlink(to) != 0)
|
||||
if (robust_unlink(to) != 0) {
|
||||
errno = ETXTBSY;
|
||||
return -1;
|
||||
}
|
||||
errno = ETXTBSY;
|
||||
break;
|
||||
#endif
|
||||
case EXDEV:
|
||||
|
||||
65
xattrs.c
65
xattrs.c
@@ -44,9 +44,9 @@ extern int checksum_seed;
|
||||
|
||||
#define XATTR_ABBREV(x) ((size_t)((x).name - (x).datum) < (x).datum_len)
|
||||
|
||||
#define XSTATE_ABBREV 0
|
||||
#define XSTATE_DONE 1
|
||||
#define XSTATE_TODO 2
|
||||
#define XSTATE_ABBREV 1
|
||||
#define XSTATE_DONE 2
|
||||
#define XSTATE_TODO 3
|
||||
|
||||
#define USER_PREFIX "user."
|
||||
#define UPRE_LEN ((int)sizeof USER_PREFIX - 1)
|
||||
@@ -288,6 +288,48 @@ int get_xattr(const char *fname, stat_x *sxp)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int copy_xattrs(const char *source, const char *dest)
|
||||
{
|
||||
ssize_t list_len, name_len;
|
||||
size_t datum_len;
|
||||
char *name, *ptr;
|
||||
#ifdef HAVE_LINUX_XATTRS
|
||||
int user_only = am_sender ? 0 : !am_root;
|
||||
#endif
|
||||
|
||||
/* This puts the name list into the "namebuf" buffer. */
|
||||
if ((list_len = get_xattr_names(source)) < 0)
|
||||
return -1;
|
||||
|
||||
for (name = namebuf; list_len > 0; name += name_len) {
|
||||
name_len = strlen(name) + 1;
|
||||
list_len -= name_len;
|
||||
|
||||
#ifdef HAVE_LINUX_XATTRS
|
||||
/* We always ignore the system namespace, and non-root
|
||||
* ignores everything but the user namespace. */
|
||||
if (user_only ? !HAS_PREFIX(name, USER_PREFIX)
|
||||
: HAS_PREFIX(name, SYSTEM_PREFIX))
|
||||
continue;
|
||||
#endif
|
||||
|
||||
datum_len = 0;
|
||||
if (!(ptr = get_xattr_data(source, name, &datum_len, 0)))
|
||||
return -1;
|
||||
if (sys_lsetxattr(dest, name, ptr, datum_len) < 0) {
|
||||
int save_errno = errno ? errno : EINVAL;
|
||||
rsyserr(FERROR_XFER, errno,
|
||||
"rsync_xal_set: lsetxattr(\"%s\",\"%s\") failed",
|
||||
dest, name);
|
||||
errno = save_errno;
|
||||
return -1;
|
||||
}
|
||||
free(ptr);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int find_matching_xattr(item_list *xalp)
|
||||
{
|
||||
size_t i, j;
|
||||
@@ -461,9 +503,11 @@ int xattr_diff(struct file_struct *file, stat_x *sxp, int find_all)
|
||||
return !xattrs_equal;
|
||||
}
|
||||
|
||||
/* When called by the generator with a NULL fname, this tells the sender
|
||||
* which abbreviated xattr values we need. When called by the sender
|
||||
* (with a non-NULL fname), we send all the extra xattr data it needs. */
|
||||
/* When called by the generator (with a NULL fname), this tells the sender
|
||||
* all the abbreviated xattr values we need. When called by the sender
|
||||
* (with a non-NULL fname), we send all the extra xattr data it needs.
|
||||
* The generator may also call with f_out < 0 to just change all the
|
||||
* XSTATE_ABBREV states into XSTATE_DONE. */
|
||||
void send_xattr_request(const char *fname, struct file_struct *file, int f_out)
|
||||
{
|
||||
item_list *lst = rsync_xal_l.items;
|
||||
@@ -482,6 +526,7 @@ void send_xattr_request(const char *fname, struct file_struct *file, int f_out)
|
||||
rxa->datum[0] = XSTATE_DONE;
|
||||
continue;
|
||||
case XSTATE_TODO:
|
||||
assert(f_out >= 0);
|
||||
break;
|
||||
default:
|
||||
continue;
|
||||
@@ -510,7 +555,8 @@ void send_xattr_request(const char *fname, struct file_struct *file, int f_out)
|
||||
}
|
||||
}
|
||||
|
||||
write_byte(f_out, 0); /* end the list */
|
||||
if (f_out >= 0)
|
||||
write_byte(f_out, 0); /* end the list */
|
||||
}
|
||||
|
||||
/* When called by the sender, read the request from the generator and mark
|
||||
@@ -544,8 +590,9 @@ int recv_xattr_request(struct file_struct *file, int f_in)
|
||||
who_am_i(), num, f_name(file, NULL));
|
||||
exit_cleanup(RERR_STREAMIO);
|
||||
}
|
||||
if (rxa->datum_len <= MAX_FULL_DATUM || rxa->datum[0] != XSTATE_ABBREV) {
|
||||
rprintf(FERROR, "[%s] internal abbrev error!\n", who_am_i());
|
||||
if (!XATTR_ABBREV(*rxa) || rxa->datum[0] != XSTATE_ABBREV) {
|
||||
rprintf(FERROR, "[%s] internal abbrev error on %s (%s, len=%ld)!\n",
|
||||
who_am_i(), f_name(file, NULL), rxa->name, (long)rxa->datum_len);
|
||||
exit_cleanup(RERR_STREAMIO);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user