Updated patches to work with the current trunk.
[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
13based-on: patch/master/acls
14diff --git a/compat.c b/compat.c
15--- a/compat.c
16+++ b/compat.c
17@@ -191,13 +191,6 @@ void setup_protocol(int f_out,int f_in)
18 if (protocol_version < 30) {
19 if (append_mode == 1)
20 append_mode = 2;
21- if (preserve_xattrs && !local_server) {
22- rprintf(FERROR,
23- "--xattrs requires protocol 30 or higher"
24- " (negotiated %d).\n",
25- protocol_version);
26- exit_cleanup(RERR_PROTOCOL);
27- }
28 }
29
30 if (delete_mode && !(delete_before+delete_during+delete_after)) {
31diff --git a/xattrs.c b/xattrs.c
32--- a/xattrs.c
33+++ b/xattrs.c
34@@ -22,6 +22,7 @@
35 #include "rsync.h"
36 #include "ifuncs.h"
37 #include "inums.h"
38+#include "io.h"
39 #include "lib/sysxattrs.h"
40
41 #ifdef SUPPORT_XATTRS
42@@ -34,6 +35,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@@ -249,7 +251,7 @@ static int rsync_xal_get(const char *fname, item_list *xalp)
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@@ -365,7 +367,7 @@ static int find_matching_xattr(item_list *xalp)
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@@ -402,13 +404,22 @@ int send_xattr(int f, stat_x *sxp)
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 size_t name_len = rxa->name_len;
93 const char *name = rxa->name;
94@@ -427,8 +438,8 @@ int send_xattr(int f, stat_x *sxp)
95 name_len += UPRE_LEN;
96 }
97 #endif
98- write_varint(f, name_len);
99- write_varint(f, rxa->datum_len);
100+ write_varint30(f, name_len);
101+ write_varint30(f, rxa->datum_len);
102 #ifndef HAVE_LINUX_XATTRS
103 if (name_len > rxa->name_len) {
104 write_buf(f, USER_PREFIX, UPRE_LEN);
105@@ -436,7 +447,7 @@ int send_xattr(int f, stat_x *sxp)
106 }
107 #endif
108 write_buf(f, name, name_len);
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);
112 else
113 write_buf(f, rxa->datum, rxa->datum_len);
114@@ -486,7 +497,7 @@ int xattr_diff(struct file_struct *file, stat_x *sxp, int find_all)
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;
123@@ -531,6 +542,9 @@ void send_xattr_request(const char *fname, struct file_struct *file, int f_out)
124 int cnt, prior_req = 0;
125 rsync_xa *rxa;
126
127+ if (protocol_version < 30)
128+ return;
129+
130 lst += F_XATTR(file);
131 for (rxa = lst->items, cnt = lst->count; cnt--; rxa++) {
132 if (rxa->datum_len <= MAX_FULL_DATUM)
133@@ -587,6 +601,9 @@ int recv_xattr_request(struct file_struct *file, int f_in)
134 rsync_xa *rxa;
135 int rel_pos, cnt, num, got_xattr_data = 0;
136
137+ if (protocol_version < 30)
138+ return 0;
139+
140 if (F_XATTR(file) < 0) {
141 rprintf(FERROR, "recv_xattr_request: internal data error!\n");
142 exit_cleanup(RERR_PROTOCOL);
143@@ -649,7 +666,22 @@ void receive_xattr(int f, struct file_struct *file)
144 #else
145 int need_sort = 1;
146 #endif
147- int ndx = read_varint(f);
148+ int ndx;
149+
150+ if (protocol_version >= 30)
151+ ndx = read_varint(f);
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);
162+ }
163+ }
164
165 if (ndx < 0 || (size_t)ndx > rsync_xal_l.count) {
166 rprintf(FERROR, "receive_xattr: xa index %d out of"
167@@ -662,7 +694,7 @@ void receive_xattr(int f, struct file_struct *file)
168 return;
169 }
170
171- if ((count = read_varint(f)) != 0) {
172+ if ((count = read_varint30(f)) != 0) {
173 (void)EXPAND_ITEM_LIST(&temp_xattr, rsync_xa, count);
174 temp_xattr.count = 0;
175 }
176@@ -670,9 +702,10 @@ void receive_xattr(int f, struct file_struct *file)
177 for (num = 1; num <= count; num++) {
178 char *ptr, *name;
179 rsync_xa *rxa;
180- size_t name_len = read_varint(f);
181- size_t datum_len = read_varint(f);
182- size_t dget_len = datum_len > MAX_FULL_DATUM ? 1 + MAX_DIGEST_LEN : datum_len;
183+ size_t name_len = read_varint30(f);
184+ size_t datum_len = read_varint30(f);
185+ size_t dget_len = datum_len > MAX_FULL_DATUM && protocol_version >= 30
186+ ? 1 + MAX_DIGEST_LEN : datum_len;
187 size_t extra_len = MIGHT_NEED_RPRE ? RPRE_LEN : 0;
188 if ((dget_len + extra_len < dget_len)
189 || (dget_len + extra_len + name_len < dget_len))