A minor tweak to the compatibility code.
[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
39c135f9 15@@ -115,13 +115,6 @@ void setup_protocol(int f_out,int f_in)
64e98de1
WD
16 protocol_version);
17 exit_cleanup(RERR_PROTOCOL);
18 }
39c135f9
WD
19- if (preserve_xattrs) {
20- rprintf(FERROR,
21- "--xattrs requires protocol 30 or higher"
22- " (negotiated %d).\n",
23- protocol_version);
24- exit_cleanup(RERR_PROTOCOL);
25- }
64e98de1
WD
26 }
27
28 if (delete_mode && !(delete_before+delete_during+delete_after)) {
39c135f9
WD
29--- old/testsuite/xattrs.test
30+++ new/testsuite/xattrs.test
31@@ -9,10 +9,6 @@
bbdff76a 32
39c135f9 33 $RSYNC --version | grep ", xattrs" >/dev/null || test_skipped "Rsync is configured without xattr support"
a2f9a486 34
39c135f9
WD
35-case "$RSYNC" in
36-*protocol=29*) test_skipped "xattr support requires protocol 30" ;;
37-esac
38-
39 case "`xattr 2>&1`" in
40 *--list:*)
41 xset() {
42--- old/xattrs.c
43+++ new/xattrs.c
44@@ -20,6 +20,7 @@
45 */
64e98de1 46
39c135f9
WD
47 #include "rsync.h"
48+#include "io.h"
49 #include "lib/sysxattrs.h"
50
51 #ifdef SUPPORT_XATTRS
52@@ -31,6 +32,7 @@ extern int am_generator;
53 extern int read_only;
54 extern int list_only;
55 extern int checksum_seed;
56+extern int protocol_version;
57
58 #define RSYNC_XAL_INITIAL 5
59 #define RSYNC_XAL_LIST_INITIAL 100
60@@ -222,7 +224,7 @@ static int rsync_xal_get(const char *fna
61 if (!(ptr = get_xattr_data(fname, name, &datum_len, 0)))
62 return -1;
3fbc83e8 63
39c135f9
WD
64- if (datum_len > MAX_FULL_DATUM) {
65+ if (datum_len > MAX_FULL_DATUM && protocol_version >= 30) {
66 /* For large datums, we store a flag and a checksum. */
67 name_offset = 1 + MAX_DIGEST_LEN;
68 sum_init(checksum_seed);
69@@ -278,7 +280,7 @@ static int find_matching_xattr(item_list
70 || rxas1[j].datum_len != rxas2[j].datum_len
71 || strcmp(rxas1[j].name, rxas2[j].name))
72 break;
73- if (rxas1[j].datum_len > MAX_FULL_DATUM) {
74+ if (rxas1[j].datum_len > MAX_FULL_DATUM && protocol_version >= 30) {
75 if (memcmp(rxas1[j].datum + 1,
76 rxas2[j].datum + 1,
77 MAX_DIGEST_LEN) != 0)
e30b4e2e 78@@ -315,34 +317,43 @@ int send_xattr(statx *sxp, int f)
3fbc83e8 79 {
39c135f9
WD
80 int ndx = find_matching_xattr(sxp->xattr);
81
82- /* Send 0 (-1 + 1) to indicate that literal xattr data follows. */
83- write_abbrevint(f, ndx + 1);
84+ if (protocol_version < 30) {
e30b4e2e
WD
85+ if (ndx < 0)
86+ write_byte(f, 'X');
87+ else {
39c135f9
WD
88+ write_byte(f, 'x');
89+ write_int(f, ndx);
64e98de1 90+ }
77a7a0f0 91+ } else {
39c135f9
WD
92+ /* Send 0 (-1 + 1) to indicate that literal xattr data follows. */
93+ write_abbrevint(f, ndx + 1);
77a7a0f0 94+ }
64e98de1 95
39c135f9
WD
96 if (ndx < 0) {
97 rsync_xa *rxa;
98 int count = sxp->xattr->count;
99- write_abbrevint(f, count);
e30b4e2e 100+ write_abbrevint30(f, count);
39c135f9
WD
101 for (rxa = sxp->xattr->items; count--; rxa++) {
102 #ifdef HAVE_LINUX_XATTRS
103- write_abbrevint(f, rxa->name_len);
104- write_abbrevint(f, rxa->datum_len);
105+ write_abbrevint30(f, rxa->name_len);
106+ write_abbrevint30(f, rxa->datum_len);
107 write_buf(f, rxa->name, rxa->name_len);
108 #else
109 /* We strip the rsync prefix from disguised namespaces
110 * and put everything else in the user namespace. */
111 if (HAS_PREFIX(rxa->name, RSYNC_PREFIX)
112 && rxa->name[RPRE_LEN] != '%') {
113- write_abbrevint(f, rxa->name_len - RPRE_LEN);
114- write_abbrevint(f, rxa->datum_len);
115+ write_abbrevint30(f, rxa->name_len - RPRE_LEN);
116+ write_abbrevint30(f, rxa->datum_len);
117 write_buf(f, rxa->name + RPRE_LEN, rxa->name_len - RPRE_LEN);
118 } else {
119- write_abbrevint(f, rxa->name_len + UPRE_LEN);
120- write_abbrevint(f, rxa->datum_len);
121+ write_abbrevint30(f, rxa->name_len + UPRE_LEN);
122+ write_abbrevint30(f, rxa->datum_len);
123 write_buf(f, USER_PREFIX, UPRE_LEN);
124 write_buf(f, rxa->name, rxa->name_len);
3e6568cf 125 }
64e98de1 126 #endif
39c135f9
WD
127- if (rxa->datum_len > MAX_FULL_DATUM)
128+ if (rxa->datum_len > MAX_FULL_DATUM && protocol_version >= 30)
129 write_buf(f, rxa->datum + 1, MAX_DIGEST_LEN);
3e6568cf 130 else
39c135f9 131 write_buf(f, rxa->datum, rxa->datum_len);
e30b4e2e 132@@ -392,7 +403,7 @@ int xattr_diff(struct file_struct *file,
39c135f9
WD
133 cmp = rec_cnt ? strcmp(snd_rxa->name, rec_rxa->name) : -1;
134 if (cmp > 0)
135 same = 0;
136- else if (snd_rxa->datum_len > MAX_FULL_DATUM) {
137+ else if (snd_rxa->datum_len > MAX_FULL_DATUM && protocol_version >= 30) {
138 same = cmp == 0 && snd_rxa->datum_len == rec_rxa->datum_len
139 && memcmp(snd_rxa->datum + 1, rec_rxa->datum + 1,
140 MAX_DIGEST_LEN) == 0;
e30b4e2e 141@@ -435,6 +446,9 @@ void send_xattr_request(const char *fnam
39c135f9
WD
142 int j, cnt, prior_req = -1;
143 rsync_xa *rxa;
144
145+ if (protocol_version < 30)
3fbc83e8
WD
146+ return;
147+
39c135f9
WD
148 lst += F_XATTR(file);
149 cnt = lst->count;
150 for (rxa = lst->items, j = 0; j < cnt; rxa++, j++) {
e30b4e2e 151@@ -506,6 +520,9 @@ void recv_xattr_request(struct file_stru
39c135f9
WD
152 rsync_xa *rxa;
153 int rel_pos, cnt;
154
155+ if (protocol_version < 30)
64e98de1 156+ return;
bbdff76a 157+
39c135f9
WD
158 if (F_XATTR(file) < 0) {
159 rprintf(FERROR, "recv_xattr_request: internal data error!\n");
160 exit_cleanup(RERR_STREAMIO);
e30b4e2e 161@@ -552,7 +569,22 @@ void receive_xattr(struct file_struct *f
39c135f9
WD
162 {
163 static item_list temp_xattr = EMPTY_ITEM_LIST;
164 int count;
165- int ndx = read_abbrevint(f);
0f6fb3c8 166+ int ndx;
bbdff76a 167+
39c135f9
WD
168+ if (protocol_version >= 30)
169+ ndx = read_abbrevint(f);
170+ else {
171+ int tag = read_byte(f);
172+ if (tag == 'x')
173+ ndx = read_int(f) + 1;
174+ else if (tag == 'X')
175+ ndx = 0;
176+ else {
177+ rprintf(FERROR, "receive_xattr: unknown extended attribute"
178+ " type tag (%02x) for %s\n", tag, f_name(file, NULL));
179+ exit_cleanup(RERR_STREAMIO);
526184b9
WD
180+ }
181+ }
39c135f9
WD
182
183 if (ndx < 0 || (size_t)ndx > rsync_xal_l.count) {
184 rprintf(FERROR, "receive_xattr: xa index %d out of"
e30b4e2e 185@@ -565,7 +597,7 @@ void receive_xattr(struct file_struct *f
39c135f9
WD
186 return;
187 }
188
189- if ((count = read_abbrevint(f)) != 0) {
190+ if ((count = read_abbrevint30(f)) != 0) {
191 (void)EXPAND_ITEM_LIST(&temp_xattr, rsync_xa, count);
192 temp_xattr.count = 0;
193 }
e30b4e2e 194@@ -573,9 +605,10 @@ void receive_xattr(struct file_struct *f
39c135f9
WD
195 while (count--) {
196 char *ptr, *name;
197 rsync_xa *rxa;
198- size_t name_len = read_abbrevint(f);
199- size_t datum_len = read_abbrevint(f);
200- size_t dget_len = datum_len > MAX_FULL_DATUM ? 1 + MAX_DIGEST_LEN : datum_len;
201+ size_t name_len = read_abbrevint30(f);
202+ size_t datum_len = read_abbrevint30(f);
203+ size_t dget_len = datum_len > MAX_FULL_DATUM && protocol_version >= 30
204+ ? 1 + MAX_DIGEST_LEN : datum_len;
205 #ifdef HAVE_LINUX_XATTRS
206 size_t extra_len = 0;
207 #else