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