int use_safe_inc_flist = 0;
int want_xattr_optim = 0;
int proper_seed_order = 0;
+int inplace_partial = 0;
extern int am_server;
extern int am_sender;
extern int append_mode;
extern int fuzzy_basis;
extern int read_batch;
+extern int write_batch;
extern int delay_updates;
extern int checksum_seed;
extern int basis_dir_cnt;
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;
extern char *dest_option;
extern char *files_from;
extern char *filesfrom_host;
+extern char *checksum_choice;
extern filter_rule_list filter_list;
extern int need_unsorted_flist;
#ifdef ICONV_OPTION
extern iconv_t ic_send, ic_recv;
extern char *iconv_opt;
#endif
+extern const char *negotiated_csum_name;
/* These index values are for the file-list's extra-attribute array. */
int pathname_ndx, depth_ndx, atimes_ndx, uid_ndx, gid_ndx, acls_ndx, xattrs_ndx, unsort_ndx;
#define CF_SAFE_FLIST (1<<3)
#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;
void setup_protocol(int f_out,int f_in)
{
+ int csum_exchange = 0;
+
assert(file_extra_cnt == 0);
assert(EXTRA64_CNT == 2 || EXTRA64_CNT == 1);
compat_flags |= CF_AVOID_XATTR_OPTIM;
if (local_server || strchr(client_info, 'C') != NULL)
compat_flags |= CF_CHKSUM_SEED_FIX;
- write_byte(f_out, compat_flags);
- } else
- compat_flags = read_byte(f_in);
+ if (local_server || strchr(client_info, 'I') != NULL)
+ compat_flags |= CF_INPLACE_PARTIAL_DIR;
+ if (local_server || strchr(client_info, 'v') != NULL) {
+ if (!write_batch || protocol_version >= 30) {
+ csum_exchange = 1;
+ compat_flags |= CF_VARINT_FLIST_FLAGS;
+ }
+ }
+ if (strchr(client_info, 'V') != NULL) { /* Support a pre-release 'V' that got superseded */
+ if (!write_batch)
+ compat_flags |= CF_VARINT_FLIST_FLAGS;
+ write_byte(f_out, compat_flags);
+ } else
+ write_varint(f_out, compat_flags);
+ } else { /* read_varint() is compatible with the older write_byte() when the 0x80 bit isn't on. */
+ compat_flags = read_varint(f_in);
+ if (compat_flags & CF_VARINT_FLIST_FLAGS)
+ csum_exchange = 1;
+ }
/* The inc_recurse var MUST be set to 0 or 1. */
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
}
use_safe_inc_flist = (compat_flags & CF_SAFE_FLIST) || protocol_version >= 31;
need_messages_from_generator = 1;
+ if (compat_flags & CF_INPLACE_PARTIAL_DIR)
+ inplace_partial = 1;
#ifdef CAN_SET_SYMLINK_TIMES
} else if (!am_sender) {
receiver_symlink_times = 1;
}
#endif
+ if (!checksum_choice) {
+ const char *rcl = getenv("RSYNC_CHECKSUM_LIST");
+ int saw_fail = rcl && strstr(rcl, "FAIL");
+ if (csum_exchange)
+ negotiate_checksum(f_in, f_out, rcl, saw_fail);
+ else if (!am_server && saw_fail) {
+ rprintf(FERROR, "Remote rsync is too old for checksum negotation\n");
+ exit_cleanup(RERR_UNSUPPORTED);
+ }
+ }
+
if (am_server) {
if (!checksum_seed)
checksum_seed = time(NULL) ^ (getpid() << 6);
init_flist();
}
+
+void maybe_write_checksum(int batch_fd)
+{
+ assert(negotiated_csum_name != NULL);
+ if (compat_flags & CF_VARINT_FLIST_FLAGS)
+ write_vstring(batch_fd, negotiated_csum_name, strlen(negotiated_csum_name));
+}