- Added the inode number to the .rsyncsum file.
[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
13--- old/compat.c
14+++ new/compat.c
15@@ -144,16 +144,6 @@ void setup_protocol(int f_out,int f_in)
16 exit_cleanup(RERR_PROTOCOL);
17 }
18
19- if (protocol_version < 30) {
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)) {
30 if (protocol_version < 30)
31 delete_before = 1;
32--- old/xattrs.c
33+++ new/xattrs.c
34@@ -20,6 +20,7 @@
35 */
36
37 #include "rsync.h"
38+#include "io.h"
39 #include "lib/sysxattrs.h"
40
41 #ifdef SUPPORT_XATTRS
42@@ -32,6 +33,7 @@ extern int read_only;
43 extern int list_only;
44 extern int preserve_xattrs;
45 extern int checksum_seed;
46+extern int protocol_version;
47
48 #define RSYNC_XAL_INITIAL 5
49 #define RSYNC_XAL_LIST_INITIAL 100
50@@ -232,7 +234,7 @@ static int rsync_xal_get(const char *fna
51 if (!(ptr = get_xattr_data(fname, name, &datum_len, 0)))
52 return -1;
53
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);
59@@ -296,7 +298,7 @@ static int find_matching_xattr(item_list
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)
68@@ -333,34 +335,43 @@ int send_xattr(statx *sxp, int f)
69 {
70 int ndx = find_matching_xattr(sxp->xattr);
71
72- /* Send 0 (-1 + 1) to indicate that literal xattr data follows. */
73- write_varint(f, ndx + 1);
74+ if (protocol_version < 30) {
75+ if (ndx < 0)
76+ write_byte(f, 'X');
77+ else {
78+ write_byte(f, 'x');
79+ write_int(f, ndx);
80+ }
81+ } else {
82+ /* Send 0 (-1 + 1) to indicate that literal xattr data follows. */
83+ write_varint(f, ndx + 1);
84+ }
85
86 if (ndx < 0) {
87 rsync_xa *rxa;
88 int count = sxp->xattr->count;
89- write_varint(f, count);
90+ write_varint30(f, count);
91 for (rxa = sxp->xattr->items; count--; rxa++) {
92 #ifdef HAVE_LINUX_XATTRS
93- write_varint(f, rxa->name_len);
94- write_varint(f, rxa->datum_len);
95+ write_varint30(f, rxa->name_len);
96+ write_varint30(f, rxa->datum_len);
97 write_buf(f, rxa->name, rxa->name_len);
98 #else
99 /* We strip the rsync prefix from disguised namespaces
100 * and put everything else in the user namespace. */
101 if (HAS_PREFIX(rxa->name, RSYNC_PREFIX)
102 && rxa->name[RPRE_LEN] != '%') {
103- write_varint(f, rxa->name_len - RPRE_LEN);
104- write_varint(f, rxa->datum_len);
105+ write_varint30(f, rxa->name_len - RPRE_LEN);
106+ write_varint30(f, rxa->datum_len);
107 write_buf(f, rxa->name + RPRE_LEN, rxa->name_len - RPRE_LEN);
108 } else {
109- write_varint(f, rxa->name_len + UPRE_LEN);
110- write_varint(f, rxa->datum_len);
111+ write_varint30(f, rxa->name_len + UPRE_LEN);
112+ write_varint30(f, rxa->datum_len);
113 write_buf(f, USER_PREFIX, UPRE_LEN);
114 write_buf(f, rxa->name, rxa->name_len);
115 }
116 #endif
117- if (rxa->datum_len > MAX_FULL_DATUM)
118+ if (rxa->datum_len > MAX_FULL_DATUM && protocol_version >= 30)
119 write_buf(f, rxa->datum + 1, MAX_DIGEST_LEN);
120 else
121 write_buf(f, rxa->datum, rxa->datum_len);
122@@ -410,7 +421,7 @@ int xattr_diff(struct file_struct *file,
123 cmp = rec_cnt ? strcmp(snd_rxa->name, rec_rxa->name) : -1;
124 if (cmp > 0)
125 same = 0;
126- else if (snd_rxa->datum_len > MAX_FULL_DATUM) {
127+ else if (snd_rxa->datum_len > MAX_FULL_DATUM && protocol_version >= 30) {
128 same = cmp == 0 && snd_rxa->datum_len == rec_rxa->datum_len
129 && memcmp(snd_rxa->datum + 1, rec_rxa->datum + 1,
130 MAX_DIGEST_LEN) == 0;
131@@ -453,6 +464,9 @@ void send_xattr_request(const char *fnam
132 int j, cnt, prior_req = -1;
133 rsync_xa *rxa;
134
135+ if (protocol_version < 30)
136+ return;
137+
138 lst += F_XATTR(file);
139 cnt = lst->count;
140 for (rxa = lst->items, j = 0; j < cnt; rxa++, j++) {
141@@ -524,6 +538,9 @@ void recv_xattr_request(struct file_stru
142 rsync_xa *rxa;
143 int rel_pos, cnt;
144
145+ if (protocol_version < 30)
146+ return;
147+
148 if (F_XATTR(file) < 0) {
149 rprintf(FERROR, "recv_xattr_request: internal data error!\n");
150 exit_cleanup(RERR_STREAMIO);
151@@ -570,7 +587,22 @@ void receive_xattr(struct file_struct *f
152 {
153 static item_list temp_xattr = EMPTY_ITEM_LIST;
154 int count;
155- int ndx = read_varint(f);
156+ int ndx;
157+
158+ if (protocol_version >= 30)
159+ ndx = read_varint(f);
160+ else {
161+ int tag = read_byte(f);
162+ if (tag == 'x')
163+ ndx = read_int(f) + 1;
164+ else if (tag == 'X')
165+ ndx = 0;
166+ else {
167+ rprintf(FERROR, "receive_xattr: unknown extended attribute"
168+ " type tag (%02x) for %s\n", tag, f_name(file, NULL));
169+ exit_cleanup(RERR_STREAMIO);
170+ }
171+ }
172
173 if (ndx < 0 || (size_t)ndx > rsync_xal_l.count) {
174 rprintf(FERROR, "receive_xattr: xa index %d out of"
175@@ -583,7 +615,7 @@ void receive_xattr(struct file_struct *f
176 return;
177 }
178
179- if ((count = read_varint(f)) != 0) {
180+ if ((count = read_varint30(f)) != 0) {
181 (void)EXPAND_ITEM_LIST(&temp_xattr, rsync_xa, count);
182 temp_xattr.count = 0;
183 }
184@@ -591,9 +623,10 @@ void receive_xattr(struct file_struct *f
185 while (count--) {
186 char *ptr, *name;
187 rsync_xa *rxa;
188- size_t name_len = read_varint(f);
189- size_t datum_len = read_varint(f);
190- size_t dget_len = datum_len > MAX_FULL_DATUM ? 1 + MAX_DIGEST_LEN : datum_len;
191+ size_t name_len = read_varint30(f);
192+ size_t datum_len = read_varint30(f);
193+ size_t dget_len = datum_len > MAX_FULL_DATUM && protocol_version >= 30
194+ ? 1 + MAX_DIGEST_LEN : datum_len;
195 size_t extra_len = MIGHT_NEED_RPRE ? RPRE_LEN : 0;
196 if (dget_len + extra_len < dget_len)
197 out_of_memory("receive_xattr"); /* overflow */