extern int preserve_atimes;
extern int preserve_acls;
extern int preserve_xattrs;
+extern int xfer_flags_as_varint;
extern int need_messages_from_generator;
extern int delete_mode, delete_before, delete_during, delete_after;
extern char *shell_cmd;
#define CF_AVOID_XATTR_OPTIM (1<<4)
#define CF_CHKSUM_SEED_FIX (1<<5)
#define CF_INPLACE_PARTIAL_DIR (1<<6)
+#define CF_VARINT_FLIST_FLAGS (1<<7)
static const char *client_info;
compat_flags |= CF_CHKSUM_SEED_FIX;
if (local_server || strchr(client_info, 'I') != NULL)
compat_flags |= CF_INPLACE_PARTIAL_DIR;
+ if (local_server || strchr(client_info, 'V') != NULL)
+ compat_flags |= CF_VARINT_FLIST_FLAGS;
write_byte(f_out, compat_flags);
} else
compat_flags = read_byte(f_in);
inc_recurse = compat_flags & CF_INC_RECURSE ? 1 : 0;
want_xattr_optim = protocol_version >= 31 && !(compat_flags & CF_AVOID_XATTR_OPTIM);
proper_seed_order = compat_flags & CF_CHKSUM_SEED_FIX ? 1 : 0;
+ xfer_flags_as_varint = compat_flags & CF_VARINT_FLIST_FLAGS ? 1 : 0;
if (am_sender) {
receiver_symlink_times = am_server
? strchr(client_info, 'L') != NULL
int file_total = 0; /* total of all active items over all file-lists */
int file_old_total = 0; /* total of active items that will soon be gone */
int flist_eof = 0; /* all the file-lists are now known */
+int xfer_flags_as_varint = 0;
#define NORMAL_NAME 0
#define SLASH_ENDING_NAME 1
if (l2 > 255)
xflags |= XMIT_LONG_NAME;
- /* We must make sure we don't send a zero flag byte or the
- * other end will terminate the flist transfer. Note that
- * the use of XMIT_TOP_DIR on a non-dir has no meaning, so
- * it's harmless way to add a bit to the first flag byte. */
- if (protocol_version >= 28) {
+ /* We must avoid sending a flag value of 0 (or an initial byte of
+ * 0 for the older xflags protocol) or it will signal the end of
+ * the list. Note that the use of XMIT_TOP_DIR on a non-dir has
+ * no meaning, so it's a harmless way to add a bit to the first
+ * flag byte. */
+ if (xfer_flags_as_varint)
+ write_varint(f, xflags ? xflags : XMIT_EXTENDED_FLAGS);
+ else if (protocol_version >= 28) {
if (!xflags && !S_ISDIR(mode))
xflags |= XMIT_TOP_DIR;
if ((xflags & 0xFF00) || !xflags) {
free(relname_list);
}
+static void write_end_of_flist(int f, int send_io_error)
+{
+ if (xfer_flags_as_varint) {
+ write_varint(f, 0);
+ write_varint(f, send_io_error ? io_error : 0);
+ } else if (send_io_error) {
+ write_shortint(f, XMIT_EXTENDED_FLAGS|XMIT_IO_ERROR_ENDLIST);
+ write_varint(f, io_error);
+ } else
+ write_byte(f, 0);
+}
+
void send_extra_file_list(int f, int at_least)
{
struct file_list *flist;
}
if (io_error == save_io_error || ignore_errors)
- write_byte(f, 0);
+ write_end_of_flist(f, 0);
else if (use_safe_inc_flist) {
- write_shortint(f, XMIT_EXTENDED_FLAGS|XMIT_IO_ERROR_ENDLIST);
- write_varint(f, io_error);
+ write_end_of_flist(f, 1);
} else {
if (delete_during)
fatal_unsafe_io_error();
- write_byte(f, 0);
+ write_end_of_flist(f, 0);
}
if (need_unsorted_flist) {
/* Indicate end of file list */
if (io_error == 0 || ignore_errors)
- write_byte(f, 0);
- else if (use_safe_inc_flist) {
- write_shortint(f, XMIT_EXTENDED_FLAGS|XMIT_IO_ERROR_ENDLIST);
- write_varint(f, io_error);
- } else {
+ write_end_of_flist(f, 0);
+ else if (use_safe_inc_flist)
+ write_end_of_flist(f, 1);
+ else {
if (delete_during && inc_recurse)
fatal_unsafe_io_error();
- write_byte(f, 0);
+ write_end_of_flist(f, 0);
}
#ifdef SUPPORT_HARD_LINKS
dstart = 0;
}
- while ((flags = read_byte(f)) != 0) {
+ while (1) {
struct file_struct *file;
- if (protocol_version >= 28 && (flags & XMIT_EXTENDED_FLAGS))
- flags |= read_byte(f) << 8;
+ if (xfer_flags_as_varint) {
+ if ((flags = read_varint(f)) == 0) {
+ int err = read_varint(f);
+ if (!ignore_errors)
+ io_error |= err;
+ break;
+ }
+ } else {
+ if ((flags = read_byte(f)) == 0)
+ break;
+
+ if (protocol_version >= 28 && (flags & XMIT_EXTENDED_FLAGS))
+ flags |= read_byte(f) << 8;
- if (flags == (XMIT_EXTENDED_FLAGS|XMIT_IO_ERROR_ENDLIST)) {
- int err;
- if (!use_safe_inc_flist) {
- rprintf(FERROR, "Invalid flist flag: %x\n", flags);
- exit_cleanup(RERR_PROTOCOL);
+ if (flags == (XMIT_EXTENDED_FLAGS|XMIT_IO_ERROR_ENDLIST)) {
+ int err;
+ if (!use_safe_inc_flist) {
+ rprintf(FERROR, "Invalid flist flag: %x\n", flags);
+ exit_cleanup(RERR_PROTOCOL);
+ }
+ err = read_varint(f);
+ if (!ignore_errors)
+ io_error |= err;
+ break;
}
- err = read_varint(f);
- if (!ignore_errors)
- io_error |= err;
- break;
}
flist_expand(flist, 1);
#define XMIT_SAME_NAME (1<<5)
#define XMIT_LONG_NAME (1<<6)
#define XMIT_SAME_TIME (1<<7)
+
#define XMIT_SAME_RDEV_MAJOR (1<<8) /* protocols 28 - now (devices only) */
#define XMIT_NO_CONTENT_DIR (1<<8) /* protocols 30 - now (dirs only) */
#define XMIT_HLINKED (1<<9) /* protocols 28 - now (non-dirs) */
#define XMIT_HLINK_FIRST (1<<12) /* protocols 30 - now (HLINKED files only) */
#define XMIT_IO_ERROR_ENDLIST (1<<12) /* protocols 31*- now (w/XMIT_EXTENDED_FLAGS) (also protocol 30 w/'f' compat flag) */
#define XMIT_MOD_NSEC (1<<13) /* protocols 31 - now */
-#define XMIT_SAME_ATIME (1<<14) /* protocols ?? - now */
+#define XMIT_SAME_ATIME (1<<14) /* any protocol - restricted by command-line option */
+#define XMIT_RESERVED_15 (1<<15) /* reserved for future use */
+
+/* The following XMIT flags require an rsync that uses a varint for the flag values */
+
+#define XMIT_RESERVED_16 (1<<16) /* reserved for future use */
/* These flags are used in the live flist data. */