Skip to content

Commit da99012

Browse files
committed
Fix protocol compatibility: Add feature negotiation to work with version <=3.4.1
1 parent 616c84c commit da99012

File tree

4 files changed

+18
-3
lines changed

4 files changed

+18
-3
lines changed

compat.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@ int proper_seed_order = 0;
8282
int inplace_partial = 0;
8383
int do_negotiated_strings = 0;
8484
int xmit_id0_names = 0;
85+
int skip_unchanged_negotiated = 0;
8586

8687
struct name_num_item *xattr_sum_nni;
8788
int xattr_sum_len = 0;
@@ -124,6 +125,7 @@ struct name_num_obj valid_compressions = {
124125
#define CF_INPLACE_PARTIAL_DIR (1<<6)
125126
#define CF_VARINT_FLIST_FLAGS (1<<7)
126127
#define CF_ID0_NAMES (1<<8)
128+
#define CF_SKIP_UNCHANGED (1<<9)
127129

128130
static const char *client_info;
129131

@@ -727,6 +729,8 @@ void setup_protocol(int f_out,int f_in)
727729
compat_flags |= CF_INPLACE_PARTIAL_DIR;
728730
if (strchr(client_info, 'u') != NULL)
729731
compat_flags |= CF_ID0_NAMES;
732+
if (strchr(client_info, 'U') != NULL)
733+
compat_flags |= CF_SKIP_UNCHANGED;
730734
if (strchr(client_info, 'v') != NULL) {
731735
do_negotiated_strings = 1;
732736
compat_flags |= CF_VARINT_FLIST_FLAGS;
@@ -748,6 +752,9 @@ void setup_protocol(int f_out,int f_in)
748752
proper_seed_order = compat_flags & CF_CHKSUM_SEED_FIX ? 1 : 0;
749753
xfer_flags_as_varint = compat_flags & CF_VARINT_FLIST_FLAGS ? 1 : 0;
750754
xmit_id0_names = compat_flags & CF_ID0_NAMES ? 1 : 0;
755+
if (compat_flags & CF_SKIP_UNCHANGED) {
756+
skip_unchanged_negotiated = 1;
757+
}
751758
if (!xfer_flags_as_varint && preserve_crtimes) {
752759
fprintf(stderr, "Both rsync versions must be at least 3.2.0 for --crtimes.\n");
753760
exit_cleanup(RERR_PROTOCOL);

generator.c

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ extern int am_sender;
3434
extern int am_daemon;
3535
extern int inc_recurse;
3636
extern int no_i_r_skip_unchanged;
37+
extern int skip_unchanged_negotiated;
3738
extern int relative_paths;
3839
extern struct stats stats;
3940
extern int implied_dirs;
@@ -2241,7 +2242,8 @@ static void prescan_for_unchanged(const char *local_name, int f_out)
22412242
char fbuf[MAXPATHLEN];
22422243
STRUCT_STAT st;
22432244

2244-
if (!no_i_r_skip_unchanged || !cur_flist)
2245+
/* Only prescan if feature was negotiated with remote side */
2246+
if (!no_i_r_skip_unchanged || !skip_unchanged_negotiated || !cur_flist)
22452247
return;
22462248

22472249
if (DEBUG_GTE(GENR, 1))
@@ -2299,7 +2301,7 @@ static void prescan_for_unchanged(const char *local_name, int f_out)
22992301
skipped_count, active_count, (double)stats.total_size / 1024 / 1024 / 1024);
23002302

23012303
/* Send skipped count and adjusted total_size to sender for accurate progress display */
2302-
if (f_out >= 0) {
2304+
if (f_out >= 0 && skip_unchanged_negotiated) {
23032305
char buf[12];
23042306
SIVAL(buf, 0, skipped_count);
23052307
SIVAL64(buf, 4, stats.total_size);
@@ -2364,6 +2366,10 @@ void generate_files(int f_out, const char *local_name)
23642366
dflt_perms = (ACCESSPERMS & ~orig_umask);
23652367

23662368
/* Pre-scan to mark unchanged files for accurate progress reporting */
2369+
if (no_i_r_skip_unchanged && !skip_unchanged_negotiated) {
2370+
rprintf(FWARNING, "WARNING: --no-i-r-skip-unchanged requested but not supported by remote rsync.\n");
2371+
rprintf(FWARNING, " Falling back to standard --no-i-r behavior (no progress optimization).\n");
2372+
}
23672373
prescan_for_unchanged(local_name, f_out);
23682374

23692375
do {

io.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ extern int daemon_connection;
6060
extern int protocol_version;
6161
extern int remove_source_files;
6262
extern int preserve_hard_links;
63+
extern int skip_unchanged_negotiated;
6364
extern BOOL extra_flist_sending_enabled;
6465
extern BOOL flush_ok_after_signal;
6566
extern struct stats stats;
@@ -1512,7 +1513,7 @@ static void read_a_msg(void)
15121513
iobuf.in_multiplexed = 1;
15131514
break;
15141515
case MSG_FLIST_COUNT:
1515-
if (msg_bytes != 12 || !am_sender)
1516+
if (msg_bytes != 12 || !am_sender || !skip_unchanged_negotiated)
15161517
goto invalid_msg;
15171518
val = raw_read_int();
15181519
stats.num_skipped_files = val;

options.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3050,6 +3050,7 @@ int maybe_add_e_option(char *buf, int buf_len)
30503050
buf[x++] = 'I'; /* support inplace_partial behavior */
30513051
buf[x++] = 'v'; /* use varint for flist & compat flags; negotiate checksum */
30523052
buf[x++] = 'u'; /* include name of uid 0 & gid 0 in the id map */
3053+
buf[x++] = 'U'; /* support --no-i-r-skip-unchanged feature */
30533054

30543055
/* NOTE: Avoid using 'V' -- it was represented with the high bit of a write_byte() that became a write_varint(). */
30553056
}

0 commit comments

Comments
 (0)