The patches for 3.0.0pre7.
[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
16@@ -175,13 +175,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
cc3e685d 49@@ -241,7 +243,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);
cc3e685d 58@@ -305,7 +307,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)
cc3e685d 67@@ -342,34 +344,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);
cc3e685d 121@@ -419,7 +430,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;
cc3e685d 130@@ -462,6 +473,9 @@ void send_xattr_request(const char *fname, struct file_struct *file, int f_out)
39c135f9
WD
131 int j, cnt, prior_req = -1;
132 rsync_xa *rxa;
133
134+ if (protocol_version < 30)
3fbc83e8
WD
135+ return;
136+
39c135f9
WD
137 lst += F_XATTR(file);
138 cnt = lst->count;
139 for (rxa = lst->items, j = 0; j < cnt; rxa++, j++) {
cc3e685d 140@@ -536,6 +550,9 @@ int recv_xattr_request(struct file_struct *file, int f_in)
39c135f9 141 rsync_xa *rxa;
cc3e685d 142 int rel_pos, cnt, 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);
cc3e685d 150@@ -585,7 +602,22 @@ void receive_xattr(struct file_struct *file, int f)
39c135f9
WD
151 {
152 static item_list temp_xattr = EMPTY_ITEM_LIST;
153 int count;
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"
cc3e685d 174@@ -598,7 +630,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 }
cc3e685d 183@@ -606,9 +638,10 @@ void receive_xattr(struct file_struct *file, int f)
39c135f9
WD
184 while (count--) {
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 */