My improved version of a connection-timeout patch.
[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
7e420a3e 15@@ -163,13 +163,6 @@ void setup_protocol(int f_out,int f_in)
5ba66156
WD
16 if (protocol_version < 30) {
17 if (append_mode == 1)
18 append_mode = 2;
8a38e00a 19- if (preserve_xattrs && !local_server) {
39c135f9
WD
20- rprintf(FERROR,
21- "--xattrs requires protocol 30 or higher"
22- " (negotiated %d).\n",
23- protocol_version);
24- exit_cleanup(RERR_PROTOCOL);
25- }
5ba66156
WD
26 }
27
64e98de1 28 if (delete_mode && !(delete_before+delete_during+delete_after)) {
39c135f9
WD
29--- old/xattrs.c
30+++ new/xattrs.c
7e420a3e 31@@ -21,6 +21,7 @@
64e98de1 32
39c135f9 33 #include "rsync.h"
7e420a3e 34 #include "ifuncs.h"
39c135f9
WD
35+#include "io.h"
36 #include "lib/sysxattrs.h"
37
38 #ifdef SUPPORT_XATTRS
7e420a3e 39@@ -33,6 +34,7 @@ extern int read_only;
39c135f9 40 extern int list_only;
99650e0d 41 extern int preserve_xattrs;
39c135f9
WD
42 extern int checksum_seed;
43+extern int protocol_version;
44
45 #define RSYNC_XAL_INITIAL 5
46 #define RSYNC_XAL_LIST_INITIAL 100
7e420a3e 47@@ -233,7 +235,7 @@ static int rsync_xal_get(const char *fna
39c135f9
WD
48 if (!(ptr = get_xattr_data(fname, name, &datum_len, 0)))
49 return -1;
3fbc83e8 50
39c135f9
WD
51- if (datum_len > MAX_FULL_DATUM) {
52+ if (datum_len > MAX_FULL_DATUM && protocol_version >= 30) {
53 /* For large datums, we store a flag and a checksum. */
54 name_offset = 1 + MAX_DIGEST_LEN;
55 sum_init(checksum_seed);
7e420a3e 56@@ -297,7 +299,7 @@ static int find_matching_xattr(item_list
39c135f9
WD
57 || rxas1[j].datum_len != rxas2[j].datum_len
58 || strcmp(rxas1[j].name, rxas2[j].name))
59 break;
60- if (rxas1[j].datum_len > MAX_FULL_DATUM) {
61+ if (rxas1[j].datum_len > MAX_FULL_DATUM && protocol_version >= 30) {
62 if (memcmp(rxas1[j].datum + 1,
63 rxas2[j].datum + 1,
64 MAX_DIGEST_LEN) != 0)
7e420a3e 65@@ -334,34 +336,43 @@ int send_xattr(statx *sxp, int f)
3fbc83e8 66 {
39c135f9
WD
67 int ndx = find_matching_xattr(sxp->xattr);
68
69- /* Send 0 (-1 + 1) to indicate that literal xattr data follows. */
9e5b47fc 70- write_varint(f, ndx + 1);
39c135f9 71+ if (protocol_version < 30) {
e30b4e2e
WD
72+ if (ndx < 0)
73+ write_byte(f, 'X');
74+ else {
39c135f9
WD
75+ write_byte(f, 'x');
76+ write_int(f, ndx);
64e98de1 77+ }
77a7a0f0 78+ } else {
39c135f9 79+ /* Send 0 (-1 + 1) to indicate that literal xattr data follows. */
9e5b47fc 80+ write_varint(f, ndx + 1);
77a7a0f0 81+ }
64e98de1 82
39c135f9
WD
83 if (ndx < 0) {
84 rsync_xa *rxa;
85 int count = sxp->xattr->count;
9e5b47fc
WD
86- write_varint(f, count);
87+ write_varint30(f, count);
39c135f9
WD
88 for (rxa = sxp->xattr->items; count--; rxa++) {
89 #ifdef HAVE_LINUX_XATTRS
9e5b47fc
WD
90- write_varint(f, rxa->name_len);
91- write_varint(f, rxa->datum_len);
92+ write_varint30(f, rxa->name_len);
93+ write_varint30(f, rxa->datum_len);
39c135f9
WD
94 write_buf(f, rxa->name, rxa->name_len);
95 #else
96 /* We strip the rsync prefix from disguised namespaces
97 * and put everything else in the user namespace. */
98 if (HAS_PREFIX(rxa->name, RSYNC_PREFIX)
99 && rxa->name[RPRE_LEN] != '%') {
9e5b47fc
WD
100- write_varint(f, rxa->name_len - RPRE_LEN);
101- write_varint(f, rxa->datum_len);
102+ write_varint30(f, rxa->name_len - RPRE_LEN);
103+ write_varint30(f, rxa->datum_len);
39c135f9
WD
104 write_buf(f, rxa->name + RPRE_LEN, rxa->name_len - RPRE_LEN);
105 } else {
9e5b47fc
WD
106- write_varint(f, rxa->name_len + UPRE_LEN);
107- write_varint(f, rxa->datum_len);
108+ write_varint30(f, rxa->name_len + UPRE_LEN);
109+ write_varint30(f, rxa->datum_len);
39c135f9
WD
110 write_buf(f, USER_PREFIX, UPRE_LEN);
111 write_buf(f, rxa->name, rxa->name_len);
3e6568cf 112 }
64e98de1 113 #endif
39c135f9
WD
114- if (rxa->datum_len > MAX_FULL_DATUM)
115+ if (rxa->datum_len > MAX_FULL_DATUM && protocol_version >= 30)
116 write_buf(f, rxa->datum + 1, MAX_DIGEST_LEN);
3e6568cf 117 else
39c135f9 118 write_buf(f, rxa->datum, rxa->datum_len);
7e420a3e 119@@ -411,7 +422,7 @@ int xattr_diff(struct file_struct *file,
39c135f9
WD
120 cmp = rec_cnt ? strcmp(snd_rxa->name, rec_rxa->name) : -1;
121 if (cmp > 0)
122 same = 0;
123- else if (snd_rxa->datum_len > MAX_FULL_DATUM) {
124+ else if (snd_rxa->datum_len > MAX_FULL_DATUM && protocol_version >= 30) {
125 same = cmp == 0 && snd_rxa->datum_len == rec_rxa->datum_len
126 && memcmp(snd_rxa->datum + 1, rec_rxa->datum + 1,
127 MAX_DIGEST_LEN) == 0;
7e420a3e 128@@ -454,6 +465,9 @@ void send_xattr_request(const char *fnam
39c135f9
WD
129 int j, cnt, prior_req = -1;
130 rsync_xa *rxa;
131
132+ if (protocol_version < 30)
3fbc83e8
WD
133+ return;
134+
39c135f9
WD
135 lst += F_XATTR(file);
136 cnt = lst->count;
137 for (rxa = lst->items, j = 0; j < cnt; rxa++, j++) {
7e420a3e 138@@ -525,6 +539,9 @@ void recv_xattr_request(struct file_stru
39c135f9
WD
139 rsync_xa *rxa;
140 int rel_pos, cnt;
141
142+ if (protocol_version < 30)
64e98de1 143+ return;
bbdff76a 144+
39c135f9
WD
145 if (F_XATTR(file) < 0) {
146 rprintf(FERROR, "recv_xattr_request: internal data error!\n");
147 exit_cleanup(RERR_STREAMIO);
7e420a3e 148@@ -571,7 +588,22 @@ void receive_xattr(struct file_struct *f
39c135f9
WD
149 {
150 static item_list temp_xattr = EMPTY_ITEM_LIST;
151 int count;
9e5b47fc 152- int ndx = read_varint(f);
0f6fb3c8 153+ int ndx;
bbdff76a 154+
39c135f9 155+ if (protocol_version >= 30)
9e5b47fc 156+ ndx = read_varint(f);
39c135f9
WD
157+ else {
158+ int tag = read_byte(f);
159+ if (tag == 'x')
160+ ndx = read_int(f) + 1;
161+ else if (tag == 'X')
162+ ndx = 0;
163+ else {
164+ rprintf(FERROR, "receive_xattr: unknown extended attribute"
165+ " type tag (%02x) for %s\n", tag, f_name(file, NULL));
166+ exit_cleanup(RERR_STREAMIO);
526184b9
WD
167+ }
168+ }
39c135f9
WD
169
170 if (ndx < 0 || (size_t)ndx > rsync_xal_l.count) {
171 rprintf(FERROR, "receive_xattr: xa index %d out of"
7e420a3e 172@@ -584,7 +616,7 @@ void receive_xattr(struct file_struct *f
39c135f9
WD
173 return;
174 }
175
9e5b47fc
WD
176- if ((count = read_varint(f)) != 0) {
177+ if ((count = read_varint30(f)) != 0) {
39c135f9
WD
178 (void)EXPAND_ITEM_LIST(&temp_xattr, rsync_xa, count);
179 temp_xattr.count = 0;
180 }
7e420a3e 181@@ -592,9 +624,10 @@ void receive_xattr(struct file_struct *f
39c135f9
WD
182 while (count--) {
183 char *ptr, *name;
184 rsync_xa *rxa;
9e5b47fc
WD
185- size_t name_len = read_varint(f);
186- size_t datum_len = read_varint(f);
39c135f9 187- size_t dget_len = datum_len > MAX_FULL_DATUM ? 1 + MAX_DIGEST_LEN : datum_len;
9e5b47fc
WD
188+ size_t name_len = read_varint30(f);
189+ size_t datum_len = read_varint30(f);
39c135f9
WD
190+ size_t dget_len = datum_len > MAX_FULL_DATUM && protocol_version >= 30
191+ ? 1 + MAX_DIGEST_LEN : datum_len;
12b04b40
WD
192 size_t extra_len = MIGHT_NEED_RPRE ? RPRE_LEN : 0;
193 if (dget_len + extra_len < dget_len)
194 out_of_memory("receive_xattr"); /* overflow */