This patch makes rsync talk an xattr protocol that is compatible with
[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)
78@@ -315,34 +317,46 @@ 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) {
85+ if (ndx >= 0) {
86+ write_byte(f, 'x');
87+ write_int(f, ndx);
64e98de1 88+ }
77a7a0f0 89+ } else {
39c135f9
WD
90+ /* Send 0 (-1 + 1) to indicate that literal xattr data follows. */
91+ write_abbrevint(f, ndx + 1);
77a7a0f0 92+ }
64e98de1 93
39c135f9
WD
94 if (ndx < 0) {
95 rsync_xa *rxa;
96 int count = sxp->xattr->count;
97- write_abbrevint(f, count);
98+ if (protocol_version >= 30)
99+ write_abbrevint(f, count);
100+ else {
101+ write_byte(f, 'X');
102+ write_int(f, count);
103+ }
104 for (rxa = sxp->xattr->items; count--; rxa++) {
105 #ifdef HAVE_LINUX_XATTRS
106- write_abbrevint(f, rxa->name_len);
107- write_abbrevint(f, rxa->datum_len);
108+ write_abbrevint30(f, rxa->name_len);
109+ write_abbrevint30(f, rxa->datum_len);
110 write_buf(f, rxa->name, rxa->name_len);
111 #else
112 /* We strip the rsync prefix from disguised namespaces
113 * and put everything else in the user namespace. */
114 if (HAS_PREFIX(rxa->name, RSYNC_PREFIX)
115 && rxa->name[RPRE_LEN] != '%') {
116- write_abbrevint(f, rxa->name_len - RPRE_LEN);
117- write_abbrevint(f, rxa->datum_len);
118+ write_abbrevint30(f, rxa->name_len - RPRE_LEN);
119+ write_abbrevint30(f, rxa->datum_len);
120 write_buf(f, rxa->name + RPRE_LEN, rxa->name_len - RPRE_LEN);
121 } else {
122- write_abbrevint(f, rxa->name_len + UPRE_LEN);
123- write_abbrevint(f, rxa->datum_len);
124+ write_abbrevint30(f, rxa->name_len + UPRE_LEN);
125+ write_abbrevint30(f, rxa->datum_len);
126 write_buf(f, USER_PREFIX, UPRE_LEN);
127 write_buf(f, rxa->name, rxa->name_len);
3e6568cf 128 }
64e98de1 129 #endif
39c135f9
WD
130- if (rxa->datum_len > MAX_FULL_DATUM)
131+ if (rxa->datum_len > MAX_FULL_DATUM && protocol_version >= 30)
132 write_buf(f, rxa->datum + 1, MAX_DIGEST_LEN);
3e6568cf 133 else
39c135f9
WD
134 write_buf(f, rxa->datum, rxa->datum_len);
135@@ -392,7 +406,7 @@ int xattr_diff(struct file_struct *file,
136 cmp = rec_cnt ? strcmp(snd_rxa->name, rec_rxa->name) : -1;
137 if (cmp > 0)
138 same = 0;
139- else if (snd_rxa->datum_len > MAX_FULL_DATUM) {
140+ else if (snd_rxa->datum_len > MAX_FULL_DATUM && protocol_version >= 30) {
141 same = cmp == 0 && snd_rxa->datum_len == rec_rxa->datum_len
142 && memcmp(snd_rxa->datum + 1, rec_rxa->datum + 1,
143 MAX_DIGEST_LEN) == 0;
144@@ -435,6 +449,9 @@ void send_xattr_request(const char *fnam
145 int j, cnt, prior_req = -1;
146 rsync_xa *rxa;
147
148+ if (protocol_version < 30)
3fbc83e8
WD
149+ return;
150+
39c135f9
WD
151 lst += F_XATTR(file);
152 cnt = lst->count;
153 for (rxa = lst->items, j = 0; j < cnt; rxa++, j++) {
154@@ -506,6 +523,9 @@ void recv_xattr_request(struct file_stru
155 rsync_xa *rxa;
156 int rel_pos, cnt;
157
158+ if (protocol_version < 30)
64e98de1 159+ return;
bbdff76a 160+
39c135f9
WD
161 if (F_XATTR(file) < 0) {
162 rprintf(FERROR, "recv_xattr_request: internal data error!\n");
163 exit_cleanup(RERR_STREAMIO);
164@@ -552,7 +572,22 @@ void receive_xattr(struct file_struct *f
165 {
166 static item_list temp_xattr = EMPTY_ITEM_LIST;
167 int count;
168- int ndx = read_abbrevint(f);
0f6fb3c8 169+ int ndx;
bbdff76a 170+
39c135f9
WD
171+ if (protocol_version >= 30)
172+ ndx = read_abbrevint(f);
173+ else {
174+ int tag = read_byte(f);
175+ if (tag == 'x')
176+ ndx = read_int(f) + 1;
177+ else if (tag == 'X')
178+ ndx = 0;
179+ else {
180+ rprintf(FERROR, "receive_xattr: unknown extended attribute"
181+ " type tag (%02x) for %s\n", tag, f_name(file, NULL));
182+ exit_cleanup(RERR_STREAMIO);
526184b9
WD
183+ }
184+ }
39c135f9
WD
185
186 if (ndx < 0 || (size_t)ndx > rsync_xal_l.count) {
187 rprintf(FERROR, "receive_xattr: xa index %d out of"
188@@ -565,7 +600,7 @@ void receive_xattr(struct file_struct *f
189 return;
190 }
191
192- if ((count = read_abbrevint(f)) != 0) {
193+ if ((count = read_abbrevint30(f)) != 0) {
194 (void)EXPAND_ITEM_LIST(&temp_xattr, rsync_xa, count);
195 temp_xattr.count = 0;
196 }
197@@ -573,9 +608,10 @@ void receive_xattr(struct file_struct *f
198 while (count--) {
199 char *ptr, *name;
200 rsync_xa *rxa;
201- size_t name_len = read_abbrevint(f);
202- size_t datum_len = read_abbrevint(f);
203- size_t dget_len = datum_len > MAX_FULL_DATUM ? 1 + MAX_DIGEST_LEN : datum_len;
204+ size_t name_len = read_abbrevint30(f);
205+ size_t datum_len = read_abbrevint30(f);
206+ size_t dget_len = datum_len > MAX_FULL_DATUM && protocol_version >= 30
207+ ? 1 + MAX_DIGEST_LEN : datum_len;
208 #ifdef HAVE_LINUX_XATTRS
209 size_t extra_len = 0;
210 #else