#include "rsync.h"
#include "rounding.h"
+#include "io.h"
extern int verbose;
extern int list_only;
extern int copy_dirlinks;
extern int keep_dirlinks;
extern int preserve_acls;
+extern int preserve_xattrs;
extern int preserve_links;
extern int preserve_hard_links;
extern int preserve_devices;
#ifdef SUPPORT_HARD_LINKS
static int64 tmp_dev, tmp_ino;
#endif
-static char tmp_sum[MD4_SUM_LENGTH];
+static char tmp_sum[MAX_DIGEST_LEN];
-static char empty_sum[MD4_SUM_LENGTH];
+static char empty_sum[MAX_DIGEST_LEN];
static int flist_count_offset; /* for --delete --progress */
static void clean_flist(struct file_list *flist, int strip_root, int no_dups);
rprintf(FINFO, "FILE_STRUCT_LEN=%d, EXTRA_LEN=%d\n",
(int)FILE_STRUCT_LEN, (int)EXTRA_LEN);
}
- checksum_len = protocol_version < 21 ? 2 : MD4_SUM_LENGTH;
+ checksum_len = protocol_version < 21 ? 2
+ : protocol_version < 30 ? MD4_DIGEST_LEN
+ : MD5_DIGEST_LEN;
}
static int show_filelist_p(void)
if (dir && !push_dir(dir, 0)) {
io_error |= IOERR_GENERAL;
- rsyserr(FERROR, errno, "push_dir %s failed",
- full_fname(dir));
+ rsyserr(FERROR, errno, "push_dir %s failed in %s",
+ full_fname(dir), curr_dir);
return 0;
}
flags |= XMIT_SAME_RDEV_MAJOR;
else
rdev_major = major(rdev);
- if ((uint32)minor(rdev) <= 0xFFu)
- flags |= XMIT_RDEV_MINOR_IS_SMALL;
+ if (protocol_version < 30 && (uint32)minor(rdev) <= 0xFFu)
+ flags |= XMIT_RDEV_MINOR_8_pre30;
}
} else if (protocol_version < 28)
rdev = MAKEDEV(0, 0);
if (flags & XMIT_SAME_NAME)
write_byte(f, l1);
if (flags & XMIT_LONG_NAME)
- write_abbrevint30(f, l2);
+ write_varint30(f, l2);
else
write_byte(f, l2);
write_buf(f, fname + l1, l2);
if (first_hlink_ndx >= 0) {
- write_abbrevint30(f, first_hlink_ndx);
+ write_varint30(f, first_hlink_ndx);
goto the_end;
}
- write_longint(f, F_LENGTH(file));
- if (!(flags & XMIT_SAME_TIME))
- write_int(f, modtime);
+ write_varlong30(f, F_LENGTH(file), 3);
+ if (!(flags & XMIT_SAME_TIME)) {
+ if (protocol_version >= 30)
+ write_varlong(f, modtime, 4);
+ else
+ write_int(f, modtime);
+ }
if (!(flags & XMIT_SAME_MODE))
write_int(f, to_wire_mode(mode));
if (preserve_uid && !(flags & XMIT_SAME_UID)) {
- write_abbrevint30(f, uid);
- if (flags & XMIT_USER_NAME_FOLLOWS) {
- int len = strlen(user_name);
- write_byte(f, len);
- write_buf(f, user_name, len);
+ if (protocol_version < 30)
+ write_int(f, uid);
+ else {
+ write_varint(f, uid);
+ if (flags & XMIT_USER_NAME_FOLLOWS) {
+ int len = strlen(user_name);
+ write_byte(f, len);
+ write_buf(f, user_name, len);
+ }
}
}
if (preserve_gid && !(flags & XMIT_SAME_GID)) {
- write_abbrevint30(f, gid);
- if (flags & XMIT_GROUP_NAME_FOLLOWS) {
- int len = strlen(group_name);
- write_byte(f, len);
- write_buf(f, group_name, len);
+ if (protocol_version < 30)
+ write_int(f, gid);
+ else {
+ write_varint(f, gid);
+ if (flags & XMIT_GROUP_NAME_FOLLOWS) {
+ int len = strlen(group_name);
+ write_byte(f, len);
+ write_buf(f, group_name, len);
+ }
}
}
if ((preserve_devices && IS_DEVICE(mode))
write_int(f, (int)rdev);
} else {
if (!(flags & XMIT_SAME_RDEV_MAJOR))
- write_int(f, major(rdev));
- if (flags & XMIT_RDEV_MINOR_IS_SMALL)
+ write_varint30(f, major(rdev));
+ if (protocol_version >= 30)
+ write_varint(f, minor(rdev));
+ else if (flags & XMIT_RDEV_MINOR_8_pre30)
write_byte(f, minor(rdev));
else
write_int(f, minor(rdev));
if (preserve_links && S_ISLNK(mode)) {
const char *sl = F_SYMLINK(file);
int len = strlen(sl);
- write_abbrevint30(f, len);
+ write_varint30(f, len);
write_buf(f, sl, len);
}
#endif
l1 = read_byte(f);
if (flags & XMIT_LONG_NAME)
- l2 = read_abbrevint30(f);
+ l2 = read_varint30(f);
else
l2 = read_byte(f);
if (protocol_version >= 30
&& BITS_SETnUNSET(flags, XMIT_HLINKED, XMIT_HLINK_FIRST)) {
struct file_struct *first;
- first_hlink_ndx = read_abbrevint30(f);
+ first_hlink_ndx = read_varint30(f);
if (first_hlink_ndx < 0 || first_hlink_ndx >= flist->count) {
rprintf(FERROR,
"hard-link reference out of range: %d (%d)\n",
|| (preserve_specials && IS_SPECIAL(mode))) {
uint32 *devp = F_RDEV_P(first);
rdev = MAKEDEV(DEV_MAJOR(devp), DEV_MINOR(devp));
+ extra_len += 2 * EXTRA_LEN;
}
if (preserve_links && S_ISLNK(mode))
linkname_len = strlen(F_SYMLINK(first)) + 1;
}
#endif
- file_length = read_longint(f);
- if (!(flags & XMIT_SAME_TIME))
- modtime = (time_t)read_int(f);
+ file_length = read_varlong30(f, 3);
+ if (!(flags & XMIT_SAME_TIME)) {
+ if (protocol_version >= 30)
+ modtime = (time_t)read_varlong(f, 4);
+ else
+ modtime = (time_t)read_int(f);
+ }
if (!(flags & XMIT_SAME_MODE))
mode = from_wire_mode(read_int(f));
mode = tweak_mode(mode, chmod_modes);
if (preserve_uid && !(flags & XMIT_SAME_UID)) {
- uid = (uid_t)read_abbrevint30(f);
- if (flags & XMIT_USER_NAME_FOLLOWS)
- uid = recv_user_name(f, uid);
- else if (inc_recurse && am_root && !numeric_ids)
- uid = match_uid(uid);
+ if (protocol_version < 30)
+ uid = (uid_t)read_int(f);
+ else {
+ uid = (uid_t)read_varint(f);
+ if (flags & XMIT_USER_NAME_FOLLOWS)
+ uid = recv_user_name(f, uid);
+ else if (inc_recurse && am_root && !numeric_ids)
+ uid = match_uid(uid);
+ }
}
if (preserve_gid && !(flags & XMIT_SAME_GID)) {
- gid = (gid_t)read_abbrevint30(f);
- if (flags & XMIT_GROUP_NAME_FOLLOWS)
- gid = recv_group_name(f, gid);
- else if (inc_recurse && (!am_root || !numeric_ids))
- gid = match_gid(gid);
+ if (protocol_version < 30)
+ gid = (gid_t)read_int(f);
+ else {
+ gid = (gid_t)read_varint(f);
+ if (flags & XMIT_GROUP_NAME_FOLLOWS)
+ gid = recv_group_name(f, gid);
+ else if (inc_recurse && (!am_root || !numeric_ids))
+ gid = match_gid(gid);
+ }
}
if ((preserve_devices && IS_DEVICE(mode))
} else {
uint32 rdev_minor;
if (!(flags & XMIT_SAME_RDEV_MAJOR))
- rdev_major = read_int(f);
- if (flags & XMIT_RDEV_MINOR_IS_SMALL)
+ rdev_major = read_varint30(f);
+ if (protocol_version >= 30)
+ rdev_minor = read_varint(f);
+ else if (flags & XMIT_RDEV_MINOR_8_pre30)
rdev_minor = read_byte(f);
else
rdev_minor = read_int(f);
#ifdef SUPPORT_LINKS
if (preserve_links && S_ISLNK(mode)) {
- linkname_len = read_abbrevint30(f) + 1; /* count the '\0' */
+ linkname_len = read_varint30(f) + 1; /* count the '\0' */
if (linkname_len <= 0 || linkname_len > MAXPATHLEN) {
rprintf(FERROR, "overflow: linkname_len=%d\n",
linkname_len - 1);
if (preserve_acls && !S_ISLNK(mode))
receive_acl(file, f);
#endif
+#ifdef SUPPORT_XATTRS
+ if (preserve_xattrs)
+ receive_xattr(file, f );
+#endif
if (S_ISREG(mode) || S_ISLNK(mode))
stats.total_size += file_length;
int flags, int filter_flags)
{
struct file_struct *file;
-#ifdef SUPPORT_ACLS
+#if defined SUPPORT_ACLS || defined SUPPORT_XATTRS
statx sx;
#endif
return NULL;
}
#endif
+#ifdef SUPPORT_XATTRS
+ if (preserve_xattrs && f >= 0) {
+ sx.xattr = NULL;
+ if (get_xattr(fname, &sx) < 0)
+ return NULL;
+ }
+#endif
maybe_emit_filelist_progress(flist->count + flist_count_offset);
send_acl(&sx, f);
free_acl(&sx);
}
+#endif
+#ifdef SUPPORT_XATTRS
+ if (preserve_xattrs) {
+ F_XATTR(file) = send_xattr(&sx, f);
+ free_xattr(&sx);
+ }
#endif
}
return file;
int64 start_write;
int future_cnt, save_io_error = io_error;
- if (send_dir_ndx < 0)
+ if (flist_eof)
return;
/* Keep sending data until we have the requested number of
disable_buffering = io_start_buffering_out(f);
if (filesfrom_fd >= 0) {
if (argv[0] && !push_dir(argv[0], 0)) {
- rsyserr(FERROR, errno, "push_dir %s failed",
- full_fname(argv[0]));
+ rsyserr(FERROR, errno, "push_dir %s failed in %s",
+ full_fname(argv[0]), curr_dir);
exit_cleanup(RERR_FILESELECT);
}
use_ff_fd = 1;
&& (len == 1 || fbuf[len-2] == '/');
}
- if (link_stat(fbuf, &st, copy_dirlinks) != 0) {
- io_error |= IOERR_GENERAL;
- rsyserr(FERROR, errno, "link_stat %s failed",
- full_fname(fbuf));
- continue;
- }
-
- if (S_ISDIR(st.st_mode) && !xfer_dirs) {
- rprintf(FINFO, "skipping directory %s\n", fbuf);
- continue;
- }
-
dir = NULL;
if (!relative_paths) {
} else if (!push_flist_dir(lastdir, lastdir_len)) {
push_error:
io_error |= IOERR_GENERAL;
- rsyserr(FERROR, errno, "push_dir %s failed",
- full_fname(dir));
+ rsyserr(FERROR, errno, "push_dir %s failed in %s",
+ full_fname(dir), curr_dir);
continue;
}
}
if (fn != fbuf)
memmove(fbuf, fn, len + 1);
+ if (link_stat(fbuf, &st, copy_dirlinks) != 0) {
+ io_error |= IOERR_GENERAL;
+ rsyserr(FERROR, errno, "link_stat %s failed",
+ full_fname(fbuf));
+ continue;
+ }
+
+ if (S_ISDIR(st.st_mode) && !xfer_dirs) {
+ rprintf(FINFO, "skipping directory %s\n", fbuf);
+ continue;
+ }
+
if (implied_dirs && (p=strrchr(fbuf,'/')) && p != fbuf) {
/* Send the implied directories at the start of the
* source spec, so we get their permissions right. */
if (inc_recurse) {
add_dirs_to_tree(-1, 0, dir_flist->count - 1);
- if (file_total == 1) {
+ if (send_dir_ndx < 0) {
+ write_ndx(f, NDX_FLIST_EOF);
+ flist_eof = 1;
+ }
+ else if (file_total == 1) {
/* If we're creating incremental file-lists and there
* was just 1 item in the first file-list, send 1 more
* file-list to check if this is a 1-file xfer. */
- if (send_dir_ndx < 0)
- write_ndx(f, NDX_DONE);
- else
- send_extra_file_list(f, 1);
+ send_extra_file_list(f, 1);
}
}
{
struct file_list *flist;
int ndx = read_ndx(f);
- if (ndx == NDX_DONE) {
+ if (ndx == NDX_FLIST_EOF) {
flist_eof = 1;
change_local_filter_dir(NULL, 0, 0);
} else {