Use "use warnings" rather than -w on the #! line.
[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@@ -190,13 +190,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@@ -246,7 +248,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@@ -348,7 +350,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@@ -385,13 +387,22 @@ 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 size_t name_len = rxa->name_len;
92 const char *name = rxa->name;
93@@ -410,8 +421,8 @@ int send_xattr(stat_x *sxp, int f)
94 name_len += UPRE_LEN;
95 }
96 #endif
97- write_varint(f, name_len);
98- write_varint(f, rxa->datum_len);
99+ write_varint30(f, name_len);
100+ write_varint30(f, rxa->datum_len);
101 #ifndef HAVE_LINUX_XATTRS
102 if (name_len > rxa->name_len) {
103 write_buf(f, USER_PREFIX, UPRE_LEN);
104@@ -419,7 +430,7 @@ int send_xattr(stat_x *sxp, int f)
105 }
106 #endif
107 write_buf(f, name, name_len);
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);
111 else
112 write_buf(f, rxa->datum, rxa->datum_len);
113@@ -469,7 +480,7 @@ int xattr_diff(struct file_struct *file, stat_x *sxp, int find_all)
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;
122@@ -514,6 +525,9 @@ void send_xattr_request(const char *fname, struct file_struct *file, int f_out)
123 int cnt, prior_req = 0;
124 rsync_xa *rxa;
125
126+ if (protocol_version < 30)
127+ return;
128+
129 lst += F_XATTR(file);
130 for (rxa = lst->items, cnt = lst->count; cnt--; rxa++) {
131 if (rxa->datum_len <= MAX_FULL_DATUM)
132@@ -570,6 +584,9 @@ int recv_xattr_request(struct file_struct *file, int f_in)
133 rsync_xa *rxa;
134 int rel_pos, cnt, num, got_xattr_data = 0;
135
136+ if (protocol_version < 30)
137+ return 0;
138+
139 if (F_XATTR(file) < 0) {
140 rprintf(FERROR, "recv_xattr_request: internal data error!\n");
141 exit_cleanup(RERR_STREAMIO);
142@@ -632,7 +649,22 @@ void receive_xattr(struct file_struct *file, int f)
143 #else
144 int need_sort = 1;
145 #endif
146- int ndx = read_varint(f);
147+ int ndx;
148+
149+ if (protocol_version >= 30)
150+ ndx = read_varint(f);
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);
161+ }
162+ }
163
164 if (ndx < 0 || (size_t)ndx > rsync_xal_l.count) {
165 rprintf(FERROR, "receive_xattr: xa index %d out of"
166@@ -645,7 +677,7 @@ void receive_xattr(struct file_struct *file, int f)
167 return;
168 }
169
170- if ((count = read_varint(f)) != 0) {
171+ if ((count = read_varint30(f)) != 0) {
172 (void)EXPAND_ITEM_LIST(&temp_xattr, rsync_xa, count);
173 temp_xattr.count = 0;
174 }
175@@ -653,9 +685,10 @@ void receive_xattr(struct file_struct *file, int f)
176 for (num = 1; num <= count; num++) {
177 char *ptr, *name;
178 rsync_xa *rxa;
179- size_t name_len = read_varint(f);
180- size_t datum_len = read_varint(f);
181- size_t dget_len = datum_len > MAX_FULL_DATUM ? 1 + MAX_DIGEST_LEN : datum_len;
182+ size_t name_len = read_varint30(f);
183+ size_t datum_len = read_varint30(f);
184+ size_t dget_len = datum_len > MAX_FULL_DATUM && protocol_version >= 30
185+ ? 1 + MAX_DIGEST_LEN : datum_len;
186 size_t extra_len = MIGHT_NEED_RPRE ? RPRE_LEN : 0;
187 if ((dget_len + extra_len < dget_len)
188 || (dget_len + extra_len + name_len < dget_len))