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