The patches for 3.0.0pre10.
[rsync/rsync-patches.git] / xattrs.diff
... / ...
CommitLineData
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.
5
6To use this patch, run these commands for a successful build:
7
8 patch -p1 <patches/acls.diff
9 patch -p1 <patches/xattrs.diff
10 ./configure (optional if already run)
11 make
12
13diff --git a/compat.c b/compat.c
14--- a/compat.c
15+++ b/compat.c
16@@ -187,13 +187,6 @@ void setup_protocol(int f_out,int f_in)
17 if (protocol_version < 30) {
18 if (append_mode == 1)
19 append_mode = 2;
20- if (preserve_xattrs && !local_server) {
21- rprintf(FERROR,
22- "--xattrs requires protocol 30 or higher"
23- " (negotiated %d).\n",
24- protocol_version);
25- exit_cleanup(RERR_PROTOCOL);
26- }
27 }
28
29 if (delete_mode && !(delete_before+delete_during+delete_after)) {
30diff --git a/xattrs.c b/xattrs.c
31--- a/xattrs.c
32+++ b/xattrs.c
33@@ -21,6 +21,7 @@
34
35 #include "rsync.h"
36 #include "ifuncs.h"
37+#include "io.h"
38 #include "lib/sysxattrs.h"
39
40 #ifdef SUPPORT_XATTRS
41@@ -33,6 +34,7 @@ extern int read_only;
42 extern int list_only;
43 extern int preserve_xattrs;
44 extern int checksum_seed;
45+extern int protocol_version;
46
47 #define RSYNC_XAL_INITIAL 5
48 #define RSYNC_XAL_LIST_INITIAL 100
49@@ -239,7 +241,7 @@ static int rsync_xal_get(const char *fname, item_list *xalp)
50 if (!(ptr = get_xattr_data(fname, name, &datum_len, 0)))
51 return -1;
52
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);
58@@ -307,7 +309,7 @@ static int find_matching_xattr(item_list *xalp)
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)
67@@ -344,34 +346,43 @@ int send_xattr(stat_x *sxp, int f)
68 {
69 int ndx = find_matching_xattr(sxp->xattr);
70
71- /* Send 0 (-1 + 1) to indicate that literal xattr data follows. */
72- write_varint(f, ndx + 1);
73+ if (protocol_version < 30) {
74+ if (ndx < 0)
75+ write_byte(f, 'X');
76+ else {
77+ write_byte(f, 'x');
78+ write_int(f, ndx);
79+ }
80+ } else {
81+ /* Send 0 (-1 + 1) to indicate that literal xattr data follows. */
82+ write_varint(f, ndx + 1);
83+ }
84
85 if (ndx < 0) {
86 rsync_xa *rxa;
87 int count = sxp->xattr->count;
88- write_varint(f, count);
89+ write_varint30(f, count);
90 for (rxa = sxp->xattr->items; count--; rxa++) {
91 #ifdef HAVE_LINUX_XATTRS
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);
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] != '%') {
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);
106 write_buf(f, rxa->name + RPRE_LEN, rxa->name_len - RPRE_LEN);
107 } else {
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);
112 write_buf(f, USER_PREFIX, UPRE_LEN);
113 write_buf(f, rxa->name, rxa->name_len);
114 }
115 #endif
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);
119 else
120 write_buf(f, rxa->datum, rxa->datum_len);
121@@ -421,7 +432,7 @@ int xattr_diff(struct file_struct *file, stat_x *sxp, int find_all)
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;
130@@ -464,6 +475,9 @@ void send_xattr_request(const char *fname, struct file_struct *file, int f_out)
131 int cnt, prior_req = 0;
132 rsync_xa *rxa;
133
134+ if (protocol_version < 30)
135+ return;
136+
137 lst += F_XATTR(file);
138 for (rxa = lst->items, cnt = lst->count; cnt--; rxa++) {
139 if (rxa->datum_len <= MAX_FULL_DATUM)
140@@ -518,6 +532,9 @@ int recv_xattr_request(struct file_struct *file, int f_in)
141 rsync_xa *rxa;
142 int rel_pos, cnt, num, got_xattr_data = 0;
143
144+ if (protocol_version < 30)
145+ return 0;
146+
147 if (F_XATTR(file) < 0) {
148 rprintf(FERROR, "recv_xattr_request: internal data error!\n");
149 exit_cleanup(RERR_STREAMIO);
150@@ -574,7 +591,22 @@ void receive_xattr(struct file_struct *file, int f)
151 {
152 static item_list temp_xattr = EMPTY_ITEM_LIST;
153 int count, num;
154- int ndx = read_varint(f);
155+ int ndx;
156+
157+ if (protocol_version >= 30)
158+ ndx = read_varint(f);
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);
169+ }
170+ }
171
172 if (ndx < 0 || (size_t)ndx > rsync_xal_l.count) {
173 rprintf(FERROR, "receive_xattr: xa index %d out of"
174@@ -587,7 +619,7 @@ void receive_xattr(struct file_struct *file, int f)
175 return;
176 }
177
178- if ((count = read_varint(f)) != 0) {
179+ if ((count = read_varint30(f)) != 0) {
180 (void)EXPAND_ITEM_LIST(&temp_xattr, rsync_xa, count);
181 temp_xattr.count = 0;
182 }
183@@ -595,9 +627,10 @@ void receive_xattr(struct file_struct *file, int f)
184 for (num = 1; num <= count; num++) {
185 char *ptr, *name;
186 rsync_xa *rxa;
187- size_t name_len = read_varint(f);
188- size_t datum_len = read_varint(f);
189- size_t dget_len = datum_len > MAX_FULL_DATUM ? 1 + MAX_DIGEST_LEN : datum_len;
190+ size_t name_len = read_varint30(f);
191+ size_t datum_len = read_varint30(f);
192+ size_t dget_len = datum_len > MAX_FULL_DATUM && protocol_version >= 30
193+ ? 1 + MAX_DIGEST_LEN : datum_len;
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 */