The patches for 3.0.1 and 3.0.2.
[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
c0c7984e 49@@ -245,7 +247,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);
c0c7984e 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)
c0c7984e 67@@ -342,13 +344,22 @@ 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 90 for (rxa = sxp->xattr->items; count--; rxa++) {
c0c7984e
WD
91 size_t name_len = rxa->name_len;
92 const char *name = rxa->name;
93@@ -367,8 +378,8 @@ int send_xattr(stat_x *sxp, int f)
94 name_len += UPRE_LEN;
95 }
96 #endif
97- write_varint(f, name_len);
9e5b47fc 98- write_varint(f, rxa->datum_len);
c0c7984e 99+ write_varint30(f, name_len);
9e5b47fc 100+ write_varint30(f, rxa->datum_len);
c0c7984e
WD
101 #ifndef HAVE_LINUX_XATTRS
102 if (name_len > rxa->name_len) {
39c135f9 103 write_buf(f, USER_PREFIX, UPRE_LEN);
c0c7984e 104@@ -376,7 +387,7 @@ int send_xattr(stat_x *sxp, int f)
3e6568cf 105 }
64e98de1 106 #endif
c0c7984e 107 write_buf(f, name, name_len);
39c135f9
WD
108- if (rxa->datum_len > MAX_FULL_DATUM)
109+ if (rxa->datum_len > MAX_FULL_DATUM && protocol_version >= 30)
110 write_buf(f, rxa->datum + 1, MAX_DIGEST_LEN);
3e6568cf 111 else
39c135f9 112 write_buf(f, rxa->datum, rxa->datum_len);
c0c7984e 113@@ -426,7 +437,7 @@ int xattr_diff(struct file_struct *file, stat_x *sxp, int find_all)
39c135f9
WD
114 cmp = rec_cnt ? strcmp(snd_rxa->name, rec_rxa->name) : -1;
115 if (cmp > 0)
116 same = 0;
117- else if (snd_rxa->datum_len > MAX_FULL_DATUM) {
118+ else if (snd_rxa->datum_len > MAX_FULL_DATUM && protocol_version >= 30) {
119 same = cmp == 0 && snd_rxa->datum_len == rec_rxa->datum_len
120 && memcmp(snd_rxa->datum + 1, rec_rxa->datum + 1,
121 MAX_DIGEST_LEN) == 0;
c0c7984e 122@@ -469,6 +480,9 @@ void send_xattr_request(const char *fname, struct file_struct *file, int f_out)
4c15e800 123 int cnt, prior_req = 0;
39c135f9
WD
124 rsync_xa *rxa;
125
126+ if (protocol_version < 30)
3fbc83e8
WD
127+ return;
128+
39c135f9 129 lst += F_XATTR(file);
4c15e800
WD
130 for (rxa = lst->items, cnt = lst->count; cnt--; rxa++) {
131 if (rxa->datum_len <= MAX_FULL_DATUM)
c0c7984e 132@@ -523,6 +537,9 @@ int recv_xattr_request(struct file_struct *file, int f_in)
39c135f9 133 rsync_xa *rxa;
4c15e800 134 int rel_pos, cnt, num, got_xattr_data = 0;
39c135f9
WD
135
136+ if (protocol_version < 30)
cc3e685d 137+ return 0;
bbdff76a 138+
39c135f9
WD
139 if (F_XATTR(file) < 0) {
140 rprintf(FERROR, "recv_xattr_request: internal data error!\n");
141 exit_cleanup(RERR_STREAMIO);
c0c7984e
WD
142@@ -584,7 +601,22 @@ void receive_xattr(struct file_struct *file, int f)
143 #else
144 int need_sort = 1;
145 #endif
9e5b47fc 146- int ndx = read_varint(f);
0f6fb3c8 147+ int ndx;
bbdff76a 148+
39c135f9 149+ if (protocol_version >= 30)
9e5b47fc 150+ ndx = read_varint(f);
39c135f9
WD
151+ else {
152+ int tag = read_byte(f);
153+ if (tag == 'x')
154+ ndx = read_int(f) + 1;
155+ else if (tag == 'X')
156+ ndx = 0;
157+ else {
158+ rprintf(FERROR, "receive_xattr: unknown extended attribute"
159+ " type tag (%02x) for %s\n", tag, f_name(file, NULL));
160+ exit_cleanup(RERR_STREAMIO);
526184b9
WD
161+ }
162+ }
39c135f9
WD
163
164 if (ndx < 0 || (size_t)ndx > rsync_xal_l.count) {
165 rprintf(FERROR, "receive_xattr: xa index %d out of"
c0c7984e 166@@ -597,7 +629,7 @@ void receive_xattr(struct file_struct *file, int f)
39c135f9
WD
167 return;
168 }
169
9e5b47fc
WD
170- if ((count = read_varint(f)) != 0) {
171+ if ((count = read_varint30(f)) != 0) {
39c135f9
WD
172 (void)EXPAND_ITEM_LIST(&temp_xattr, rsync_xa, count);
173 temp_xattr.count = 0;
174 }
c0c7984e 175@@ -605,9 +637,10 @@ void receive_xattr(struct file_struct *file, int f)
4c15e800 176 for (num = 1; num <= count; num++) {
39c135f9
WD
177 char *ptr, *name;
178 rsync_xa *rxa;
9e5b47fc
WD
179- size_t name_len = read_varint(f);
180- size_t datum_len = read_varint(f);
39c135f9 181- size_t dget_len = datum_len > MAX_FULL_DATUM ? 1 + MAX_DIGEST_LEN : datum_len;
9e5b47fc
WD
182+ size_t name_len = read_varint30(f);
183+ size_t datum_len = read_varint30(f);
39c135f9
WD
184+ size_t dget_len = datum_len > MAX_FULL_DATUM && protocol_version >= 30
185+ ? 1 + MAX_DIGEST_LEN : datum_len;
12b04b40
WD
186 size_t extra_len = MIGHT_NEED_RPRE ? RPRE_LEN : 0;
187 if (dget_len + extra_len < dget_len)
188 out_of_memory("receive_xattr"); /* overflow */