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