I committed a variation on this suggested change.
[rsync/rsync-patches.git] / xattrs.diff
CommitLineData
39c135f9
WD
1This patch adds backward-compatibility support for the --xattrs option.
2Since the main release has never had xattr support, the trunk doesn't
3need this code. If you want to make rsync 3.0.x communicate with an
4older (patched) release, use this.
bbdff76a 5
03019e41 6To use this patch, run these commands for a successful build:
bbdff76a 7
39c135f9 8 patch -p1 <patches/acls.diff
03019e41 9 patch -p1 <patches/xattrs.diff
39c135f9 10 ./configure (optional if already run)
bbdff76a
WD
11 make
12
fdf967c7
WD
13--- old/compat.c
14+++ new/compat.c
99650e0d
WD
15@@ -144,16 +144,6 @@ void setup_protocol(int f_out,int f_in)
16 exit_cleanup(RERR_PROTOCOL);
17 }
18
19- if (protocol_version < 30) {
8a38e00a 20- if (preserve_xattrs && !local_server) {
39c135f9
WD
21- rprintf(FERROR,
22- "--xattrs requires protocol 30 or higher"
23- " (negotiated %d).\n",
24- protocol_version);
25- exit_cleanup(RERR_PROTOCOL);
26- }
99650e0d
WD
27- }
28-
64e98de1 29 if (delete_mode && !(delete_before+delete_during+delete_after)) {
99650e0d
WD
30 if (protocol_version < 30)
31 delete_before = 1;
39c135f9
WD
32--- old/xattrs.c
33+++ new/xattrs.c
34@@ -20,6 +20,7 @@
35 */
64e98de1 36
39c135f9
WD
37 #include "rsync.h"
38+#include "io.h"
39 #include "lib/sysxattrs.h"
40
41 #ifdef SUPPORT_XATTRS
99650e0d 42@@ -32,6 +33,7 @@ extern int read_only;
39c135f9 43 extern int list_only;
99650e0d 44 extern int preserve_xattrs;
39c135f9
WD
45 extern int checksum_seed;
46+extern int protocol_version;
47
48 #define RSYNC_XAL_INITIAL 5
49 #define RSYNC_XAL_LIST_INITIAL 100
99650e0d 50@@ -232,7 +234,7 @@ static int rsync_xal_get(const char *fna
39c135f9
WD
51 if (!(ptr = get_xattr_data(fname, name, &datum_len, 0)))
52 return -1;
3fbc83e8 53
39c135f9
WD
54- if (datum_len > MAX_FULL_DATUM) {
55+ if (datum_len > MAX_FULL_DATUM && protocol_version >= 30) {
56 /* For large datums, we store a flag and a checksum. */
57 name_offset = 1 + MAX_DIGEST_LEN;
58 sum_init(checksum_seed);
99650e0d 59@@ -296,7 +298,7 @@ static int find_matching_xattr(item_list
39c135f9
WD
60 || rxas1[j].datum_len != rxas2[j].datum_len
61 || strcmp(rxas1[j].name, rxas2[j].name))
62 break;
63- if (rxas1[j].datum_len > MAX_FULL_DATUM) {
64+ if (rxas1[j].datum_len > MAX_FULL_DATUM && protocol_version >= 30) {
65 if (memcmp(rxas1[j].datum + 1,
66 rxas2[j].datum + 1,
67 MAX_DIGEST_LEN) != 0)
99650e0d 68@@ -333,34 +335,43 @@ int send_xattr(statx *sxp, int f)
3fbc83e8 69 {
39c135f9
WD
70 int ndx = find_matching_xattr(sxp->xattr);
71
72- /* Send 0 (-1 + 1) to indicate that literal xattr data follows. */
9e5b47fc 73- write_varint(f, ndx + 1);
39c135f9 74+ if (protocol_version < 30) {
e30b4e2e
WD
75+ if (ndx < 0)
76+ write_byte(f, 'X');
77+ else {
39c135f9
WD
78+ write_byte(f, 'x');
79+ write_int(f, ndx);
64e98de1 80+ }
77a7a0f0 81+ } else {
39c135f9 82+ /* Send 0 (-1 + 1) to indicate that literal xattr data follows. */
9e5b47fc 83+ write_varint(f, ndx + 1);
77a7a0f0 84+ }
64e98de1 85
39c135f9
WD
86 if (ndx < 0) {
87 rsync_xa *rxa;
88 int count = sxp->xattr->count;
9e5b47fc
WD
89- write_varint(f, count);
90+ write_varint30(f, count);
39c135f9
WD
91 for (rxa = sxp->xattr->items; count--; rxa++) {
92 #ifdef HAVE_LINUX_XATTRS
9e5b47fc
WD
93- write_varint(f, rxa->name_len);
94- write_varint(f, rxa->datum_len);
95+ write_varint30(f, rxa->name_len);
96+ write_varint30(f, rxa->datum_len);
39c135f9
WD
97 write_buf(f, rxa->name, rxa->name_len);
98 #else
99 /* We strip the rsync prefix from disguised namespaces
100 * and put everything else in the user namespace. */
101 if (HAS_PREFIX(rxa->name, RSYNC_PREFIX)
102 && rxa->name[RPRE_LEN] != '%') {
9e5b47fc
WD
103- write_varint(f, rxa->name_len - RPRE_LEN);
104- write_varint(f, rxa->datum_len);
105+ write_varint30(f, rxa->name_len - RPRE_LEN);
106+ write_varint30(f, rxa->datum_len);
39c135f9
WD
107 write_buf(f, rxa->name + RPRE_LEN, rxa->name_len - RPRE_LEN);
108 } else {
9e5b47fc
WD
109- write_varint(f, rxa->name_len + UPRE_LEN);
110- write_varint(f, rxa->datum_len);
111+ write_varint30(f, rxa->name_len + UPRE_LEN);
112+ write_varint30(f, rxa->datum_len);
39c135f9
WD
113 write_buf(f, USER_PREFIX, UPRE_LEN);
114 write_buf(f, rxa->name, rxa->name_len);
3e6568cf 115 }
64e98de1 116 #endif
39c135f9
WD
117- if (rxa->datum_len > MAX_FULL_DATUM)
118+ if (rxa->datum_len > MAX_FULL_DATUM && protocol_version >= 30)
119 write_buf(f, rxa->datum + 1, MAX_DIGEST_LEN);
3e6568cf 120 else
39c135f9 121 write_buf(f, rxa->datum, rxa->datum_len);
99650e0d 122@@ -410,7 +421,7 @@ int xattr_diff(struct file_struct *file,
39c135f9
WD
123 cmp = rec_cnt ? strcmp(snd_rxa->name, rec_rxa->name) : -1;
124 if (cmp > 0)
125 same = 0;
126- else if (snd_rxa->datum_len > MAX_FULL_DATUM) {
127+ else if (snd_rxa->datum_len > MAX_FULL_DATUM && protocol_version >= 30) {
128 same = cmp == 0 && snd_rxa->datum_len == rec_rxa->datum_len
129 && memcmp(snd_rxa->datum + 1, rec_rxa->datum + 1,
130 MAX_DIGEST_LEN) == 0;
99650e0d 131@@ -453,6 +464,9 @@ void send_xattr_request(const char *fnam
39c135f9
WD
132 int j, cnt, prior_req = -1;
133 rsync_xa *rxa;
134
135+ if (protocol_version < 30)
3fbc83e8
WD
136+ return;
137+
39c135f9
WD
138 lst += F_XATTR(file);
139 cnt = lst->count;
140 for (rxa = lst->items, j = 0; j < cnt; rxa++, j++) {
99650e0d 141@@ -524,6 +538,9 @@ void recv_xattr_request(struct file_stru
39c135f9
WD
142 rsync_xa *rxa;
143 int rel_pos, cnt;
144
145+ if (protocol_version < 30)
64e98de1 146+ return;
bbdff76a 147+
39c135f9
WD
148 if (F_XATTR(file) < 0) {
149 rprintf(FERROR, "recv_xattr_request: internal data error!\n");
150 exit_cleanup(RERR_STREAMIO);
99650e0d 151@@ -570,7 +587,22 @@ void receive_xattr(struct file_struct *f
39c135f9
WD
152 {
153 static item_list temp_xattr = EMPTY_ITEM_LIST;
154 int count;
9e5b47fc 155- int ndx = read_varint(f);
0f6fb3c8 156+ int ndx;
bbdff76a 157+
39c135f9 158+ if (protocol_version >= 30)
9e5b47fc 159+ ndx = read_varint(f);
39c135f9
WD
160+ else {
161+ int tag = read_byte(f);
162+ if (tag == 'x')
163+ ndx = read_int(f) + 1;
164+ else if (tag == 'X')
165+ ndx = 0;
166+ else {
167+ rprintf(FERROR, "receive_xattr: unknown extended attribute"
168+ " type tag (%02x) for %s\n", tag, f_name(file, NULL));
169+ exit_cleanup(RERR_STREAMIO);
526184b9
WD
170+ }
171+ }
39c135f9
WD
172
173 if (ndx < 0 || (size_t)ndx > rsync_xal_l.count) {
174 rprintf(FERROR, "receive_xattr: xa index %d out of"
99650e0d 175@@ -583,7 +615,7 @@ void receive_xattr(struct file_struct *f
39c135f9
WD
176 return;
177 }
178
9e5b47fc
WD
179- if ((count = read_varint(f)) != 0) {
180+ if ((count = read_varint30(f)) != 0) {
39c135f9
WD
181 (void)EXPAND_ITEM_LIST(&temp_xattr, rsync_xa, count);
182 temp_xattr.count = 0;
183 }
99650e0d 184@@ -591,9 +623,10 @@ void receive_xattr(struct file_struct *f
39c135f9
WD
185 while (count--) {
186 char *ptr, *name;
187 rsync_xa *rxa;
9e5b47fc
WD
188- size_t name_len = read_varint(f);
189- size_t datum_len = read_varint(f);
39c135f9 190- size_t dget_len = datum_len > MAX_FULL_DATUM ? 1 + MAX_DIGEST_LEN : datum_len;
9e5b47fc
WD
191+ size_t name_len = read_varint30(f);
192+ size_t datum_len = read_varint30(f);
39c135f9
WD
193+ size_t dget_len = datum_len > MAX_FULL_DATUM && protocol_version >= 30
194+ ? 1 + MAX_DIGEST_LEN : datum_len;
12b04b40
WD
195 size_t extra_len = MIGHT_NEED_RPRE ? RPRE_LEN : 0;
196 if (dget_len + extra_len < dget_len)
197 out_of_memory("receive_xattr"); /* overflow */