]> git.pld-linux.org Git - packages/rsync.git/blame - rsync-xattr.patch
- updated for 2.6.7
[packages/rsync.git] / rsync-xattr.patch
CommitLineData
6f953aec
AM
1Common subdirectories: rsync-2.6.4pre2-prexattr/autom4te.cache and rsync-2.6.4pre2/autom4te.cache
2diff -u -N rsync-2.6.4pre2-prexattr/backup.c rsync-2.6.4pre2/backup.c
3--- rsync-2.6.4pre2-prexattr/backup.c 2005-03-02 20:15:48.000000000 -0500
4+++ rsync-2.6.4pre2/backup.c 2005-03-02 20:20:46.000000000 -0500
5@@ -136,6 +136,7 @@
6 do_lchown(fullpath, st.st_uid, st.st_gid);
7 do_chmod(fullpath, st.st_mode);
8 (void)DUP_ACL(end, fullpath, st.st_mode);
9+ (void)DUP_XATTR(end, fullpath );
10 }
11 }
12 *p = '/';
13@@ -189,6 +190,7 @@
14 return 0;
15
16 PUSH_KEEP_BACKUP_ACL(file, fname, buf);
17+ PUSH_KEEP_BACKUP_XATTR( file, fname, buf );
18
19 /* Check to see if this is a device file, or link */
20 if (IS_DEVICE(file->mode)) {
21@@ -264,6 +266,7 @@
22 }
23 set_perms(buf, file, NULL, 0);
24 CLEANUP_KEEP_BACKUP_ACL();
25+ CLEANUP_KEEP_BACKUP_XATTR();
26 free(file);
27
28 if (verbose > 1) {
29diff -u -N rsync-2.6.4pre2-prexattr/configure.in rsync-2.6.4pre2/configure.in
30--- rsync-2.6.4pre2-prexattr/configure.in 2005-03-02 20:15:48.000000000 -0500
31+++ rsync-2.6.4pre2/configure.in 2005-03-02 20:20:46.000000000 -0500
32@@ -789,6 +789,30 @@
33 AC_MSG_RESULT(no)
34 )
35
36+AC_CHECK_HEADERS(attr/xattr.h)
37++AC_MSG_CHECKING(whether to support extended attributes)
38+AC_ARG_WITH(xattr-support,
39+[ --with-xattr-support Include extended attribute support (default=no)],
40+[ case "$withval" in
41+ yes)
42+ case "$host_os" in
43+ *linux*)
44+ AC_MSG_RESULT(Using Linux xattrs)
45+ AC_DEFINE(HAVE_LINUX_XATTRS, 1, [True if you have Linux xattrs])
46+ ;;
47+ *)
48+ AC_MSG_RESULT(Xattrs requested but not linux. Good luck)
49+ ;;
50+ esac
51+ ;;
52+ *)
53+ AC_MSG_RESULT(no)
54+ AC_DEFINE(HAVE_NA_XATTRS, 1, [True if you don't have extended attributes])
55+ esac ],
56+ AC_MSG_RESULT(no)
57+ AC_DEFINE(HAVE_NO_XATTRL, 1, [True if you don't have extended attributes])
58+)
59+
60 AC_CONFIG_FILES([Makefile lib/dummy zlib/dummy popt/dummy shconfig])
61 AC_OUTPUT
62
63diff -u -N rsync-2.6.4pre2-prexattr/options.c rsync-2.6.4pre2/options.c
64--- rsync-2.6.4pre2-prexattr/options.c 2005-03-02 20:15:48.000000000 -0500
65+++ rsync-2.6.4pre2/options.c 2005-03-02 20:31:22.000000000 -0500
66@@ -45,6 +45,7 @@
67 int preserve_links = 0;
68 int preserve_hard_links = 0;
69 int preserve_acls = 0;
70+int preserve_xattrs = 0;
71 int preserve_perms = 0;
72 int preserve_devices = 0;
73 int preserve_uid = 0;
74@@ -180,6 +181,7 @@
75 char const *have_inplace = "no ";
76 char const *hardlinks = "no ";
77 char const *acls = "no ";
78+ char const *xattrs = "no ";
79 char const *links = "no ";
80 char const *ipv6 = "no ";
81 STRUCT_STAT *dumstat;
82@@ -199,7 +201,9 @@
83 #ifdef SUPPORT_ACLS
84 acls = "";
85 #endif
86-
87+#if SUPPORT_XATTRS
88+ xattrs = "";
89+#endif
90 #ifdef SUPPORT_LINKS
91 links = "";
92 #endif
93@@ -214,9 +218,9 @@
94 "Copyright (C) 1996-2005 by Andrew Tridgell and others\n");
95 rprintf(f, "<http://rsync.samba.org/>\n");
96 rprintf(f, "Capabilities: %d-bit files, %ssocketpairs, "
97- "%shard links, %sACLs, %ssymlinks, batchfiles, \n",
98+ "%shard links, %sACLs, %sxattrs, %ssymlinks, batchfiles, \n",
99 (int) (sizeof (OFF_T) * 8),
100- got_socketpair, hardlinks, acls, links);
101+ got_socketpair, hardlinks, acls, xattrs, links);
102
103 /* Note that this field may not have type ino_t. It depends
104 * on the complicated interaction between largefile feature
105@@ -287,6 +291,7 @@
106 rprintf(F," -K, --keep-dirlinks treat symlinked dir on receiver as dir\n");
107 rprintf(F," -p, --perms preserve permissions\n");
108 rprintf(F," -A, --acls preserve ACLs (implies --perms)\n");
109+ rprintf(F," -X, --xattrs preserve extended attributes (implies --perms)\n");
110 rprintf(F," -o, --owner preserve owner (root only)\n");
111 rprintf(F," -g, --group preserve group\n");
112 rprintf(F," -D, --devices preserve devices (root only)\n");
113@@ -410,6 +415,7 @@
114 {"copy-unsafe-links",0, POPT_ARG_NONE, &copy_unsafe_links, 0, 0, 0 },
115 {"perms", 'p', POPT_ARG_NONE, &preserve_perms, 0, 0, 0 },
116 {"acls", 'A', POPT_ARG_NONE, 0, 'A', 0, 0 },
117+ {"xattrs", 'X', POPT_ARG_NONE, 0, 'X', 0, 0 },
118 {"owner", 'o', POPT_ARG_NONE, &preserve_uid, 0, 0, 0 },
119 {"group", 'g', POPT_ARG_NONE, &preserve_gid, 0, 0, 0 },
120 {"devices", 'D', POPT_ARG_NONE, &preserve_devices, 0, 0, 0 },
121@@ -879,6 +885,17 @@
122 #endif /* SUPPORT_ACLS */
123 break;
124
125+ case 'X':
126+#if SUPPORT_XATTRS
127+ preserve_xattrs = 1;
128+ preserve_perms = 1;
129+#else
130+ snprintf(err_buf,sizeof(err_buf),
131+ "extended attributes are not supported on this %s\n",
132+ am_server ? "server" : "client");
133+ return 0;
134+#endif /* SUPPORT_XATTRS */
135+ break;
136
137 default:
138 /* A large opt value means that set_refuse_options()
139@@ -1289,6 +1306,8 @@
140 argstr[x++] = 'H';
141 if (preserve_acls)
142 argstr[x++] = 'A';
143+ if ( preserve_xattrs )
144+ argstr[x++] = 'X';
145 if (preserve_uid)
146 argstr[x++] = 'o';
147 if (preserve_gid)
148Common subdirectories: rsync-2.6.4pre2-prexattr/packaging and rsync-2.6.4pre2/packaging
149Common subdirectories: rsync-2.6.4pre2-prexattr/patches and rsync-2.6.4pre2/patches
150Common subdirectories: rsync-2.6.4pre2-prexattr/popt and rsync-2.6.4pre2/popt
151diff -u -N rsync-2.6.4pre2-prexattr/rsync.c rsync-2.6.4pre2/rsync.c
152--- rsync-2.6.4pre2-prexattr/rsync.c 2005-03-02 20:15:48.000000000 -0500
153+++ rsync-2.6.4pre2/rsync.c 2005-03-02 20:31:22.000000000 -0500
154@@ -145,6 +145,14 @@
155 if (SET_ACL(fname, file) == 0)
156 updated = 1;
157 }
158+ /* If this is a directory, SET_XATTR() will be called on the cleanup
159+ * receive_generator() pass--if we called it here, we might clobber
160+ * writability on the directory (SELinux security contexts are stored
161+ * in xattrs). everything else is OK to do now. */
162+ if (!S_ISDIR(st->st_mode)) {
163+ if (SET_XATTR(fname, file) == 0)
164+ updated = 1;
165+ }
166
167 if (verbose > 1 && flags & PERMS_REPORT) {
168 enum logcode code = daemon_log_format_has_i || dry_run
169diff -u -N rsync-2.6.4pre2-prexattr/rsync.h rsync-2.6.4pre2/rsync.h
170--- rsync-2.6.4pre2-prexattr/rsync.h 2005-03-02 20:15:48.000000000 -0500
171+++ rsync-2.6.4pre2/rsync.h 2005-03-02 20:32:39.000000000 -0500
172@@ -662,6 +662,36 @@
173 #endif /* SUPPORT_ACLS */
174 #include "smb_acls.h"
175
176+#define SUPPORT_XATTRS HAVE_LINUX_XATTRS
177+
178+#if SUPPORT_XATTRS
179+#ifdef HAVE_ATTR_XATTR_H
180+#include <attr/xattr.h>
181+#endif
182+#define MAKE_XATTR(file, fname) make_xattr(file, fname)
183+#define SEND_XATTR(file, f) send_xattr(file, f)
184+#define RECEIVE_XATTR(file, f) receive_xattr(file, f)
185+#define SORT_FILE_XATTR_INDEX_LISTS() sort_file_xattr_index_lists()
186+#define SET_XATTR(fname, file) set_xattr(fname, file)
187+#define NEXT_XATTR_UID() next_xattr_uid()
188+#define XATTR_UID_MAP(uid) xattr_uid_map(uid)
189+#define PUSH_KEEP_BACKUP_XATTR(file, orig, dest) \
190+ push_keep_backup_xattr(file, orig, dest)
191+#define CLEANUP_KEEP_BACKUP_XATTR() cleanup_keep_backup_xattr()
192+#define DUP_XATTR(orig, dest) dup_xattr(orig, dest)
193+#else /* SUPPORT_XATTRS */
194+#define MAKE_XATTR(file, fname) 1 /* checked return value */
195+#define SEND_XATTR(file, f)
196+#define RECEIVE_XATTR(file, f)
197+#define SORT_FILE_XATTR_INDEX_LISTS()
198+#define SET_XATTR(fname, file) 0 /* checked return value */
199+#define NEXT_XATTR_UID()
200+#define XATTR_UID_MAP(uid)
201+#define PUSH_KEEP_BACKUP_XATTR(file, orig, dest)
202+#define CLEANUP_KEEP_BACKUP_XATTR()
203+#define DUP_XATTR(src, orig) 0 /* checked return value */
204+#endif /* SUPPORT_XATTRS */
205+
206 #include "proto.h"
207
208 /* We have replacement versions of these if they're missing. */
209diff -u -N rsync-2.6.4pre2-prexattr/rsync.yo rsync-2.6.4pre2/rsync.yo
210--- rsync-2.6.4pre2-prexattr/rsync.yo 2005-03-02 20:15:48.000000000 -0500
211+++ rsync-2.6.4pre2/rsync.yo 2005-03-02 20:33:53.000000000 -0500
212@@ -318,6 +318,7 @@
213 -K, --keep-dirlinks treat symlinked dir on receiver as dir
214 -p, --perms preserve permissions
215 -A, --acls preserve ACLs (implies -p) [local option]
216+ -X, --xattrs preserve extended attributes (implies -p) [local option]
217 -o, --owner preserve owner (root only)
218 -g, --group preserve group
219 -D, --devices preserve devices (root only)
220@@ -630,6 +631,11 @@
221 remote machine's rsync supports this option also. This is a non-standard
222 option.
223
224+dit(bf(-X, --xattrs)) This option causes rsync to update the remote
225+extended attributes to be the same as the local ones. This will work
226+only if the remote machine's rsync supports this option also. This is
227+a non-standard option.
228+
229 dit(bf(-o, --owner)) This option causes rsync to set the owner of the
230 destination file to be the same as the source file. On most systems,
231 only the super-user can set file ownership. By default, the preservation
232Common subdirectories: rsync-2.6.4pre2-prexattr/support and rsync-2.6.4pre2/support
233diff -u -N rsync-2.6.4pre2-prexattr/lib/sysxattr.c rsync-2.6.4pre2/sysxattr.c
234--- rsync-2.6.4pre2-prexattr/lib/sysxattr.c 1969-12-31 19:00:00.000000000 -0500
235+++ rsync-2.6.4pre2/lib/sysxattr.c 2005-03-02 20:34:10.000000000 -0500
236@@ -0,0 +1,41 @@
237+/* Extended attribute support for rsync. */
238+/* This file Copyright (C) 2004 Red Hat, Inc. */
239+/* Written by Jay Fenlason */
240+
241+/* This program is free software; you can redistribute it and/or modify
242+ it under the terms of the GNU General Public License as published by
243+ the Free Software Foundation; either version 2 of the License, or
244+ (at your option) any later version.
245+
246+ This program is distributed in the hope that it will be useful,
247+ but WITHOUT ANY WARRANTY; without even the implied warranty of
248+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
249+ GNU General Public License for more details.
250+
251+ You should have received a copy of the GNU General Public License
252+ along with this program; if not, write to the Free Software
253+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
254+*/
255+
256+#include "rsync.h"
257+
258+#if defined(HAVE_LINUX_XATTRS)
259+
260+ssize_t sys_lgetxattr ( const char *path, const char *name, void *value, size_t size )
261+{
262+ return lgetxattr ( path, name, value, size );
263+}
264+
265+int sys_lsetxattr ( const char *path, const char *name, const void *value, size_t size, int flags )
266+{
267+ return lsetxattr ( path, name, value, size, flags );
268+}
269+
270+ssize_t sys_llistxattr ( const char *path, char *list, size_t size )
271+{
272+ return llistxattr ( path, list, size );
273+}
274+
275+#else
276+
277+#endif /* No xattrs */
278Common subdirectories: rsync-2.6.4pre2-prexattr/testhelp and rsync-2.6.4pre2/testhelp
279Common subdirectories: rsync-2.6.4pre2-prexattr/testsuite and rsync-2.6.4pre2/testsuite
280diff -u -N rsync-2.6.4pre2-prexattr/xattr.c rsync-2.6.4pre2/xattr.c
281--- rsync-2.6.4pre2-prexattr/xattr.c 1969-12-31 19:00:00.000000000 -0500
282+++ rsync-2.6.4pre2/xattr.c 2005-03-02 20:34:47.000000000 -0500
283@@ -0,0 +1,556 @@
284+/* Extended Attribute support for rsync */
285+/* Copyright (C) 2004 Red Hat, Inc */
286+/* Written by Jay Fenlason, vaguely based on the ACLs patch */
287+
288+/* This program is free software; you can redistribute it and/or modify
289+ it under the terms of the GNU General Public License as published by
290+ the Free Software Foundation; either version 2 of the License, or
291+ (at your option) any later version.
292+
293+ This program is distributed in the hope that it will be useful,
294+ but WITHOUT ANY WARRANTY; without even the implied warranty of
295+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
296+ GNU General Public License for more details.
297+
298+ You should have received a copy of the GNU General Public License
299+ along with this program; if not, write to the Free Software
300+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
301+*/
302+
303+#include "rsync.h"
304+
305+#if SUPPORT_XATTRS
306+
307+extern int preserve_xattrs;
308+extern int dry_run;
309+
310+#define RSYNC_XAL_INITIAL 5
311+#define RSYNC_XAL_LIST_INITIAL 100
312+
313+
314+typedef struct {
315+ size_t name_len;
316+ char *name;
317+ size_t datum_len;
318+ char *datum;
319+} rsync_xa;
320+
321+typedef struct {
322+ size_t count;
323+ size_t alloc;
324+ rsync_xa *rxas;
325+} rsync_xal;
326+
327+typedef struct {
328+ size_t count;
329+ size_t alloc;
330+ rsync_xal *rxals;
331+} rsync_xal_list;
332+
333+static size_t namebuf_len = 0;
334+static char *namebuf = NULL;
335+
336+static size_t datumbuf_len = 0;
337+static char *datumbuf = NULL;
338+
339+static rsync_xal curr_rsync_xal = { 0, 0, NULL };
340+static rsync_xal_list rsync_xal_l = { 0, 0, NULL };
341+
342+
343+/* ------------------------------------------------------------------------- */
344+\f
345+/* the below stuff is only used by the receiver */
346+
347+/* structure to hold index to rsync_xal_l member corresponding to
348+ * flist->files[i] */
349+
350+typedef struct {
351+ const struct file_struct *file;
352+ int xalidx;
353+} file_xal_index;
354+
355+typedef struct {
356+ size_t count;
357+ size_t alloc;
358+ file_xal_index *filexalidxs;
359+} file_xal_index_list;
360+
361+static file_xal_index_list fxil = {0, 0, NULL };
362+
363+/* stuff for redirecting calls to set_acl() from set_perms()
364+ * for keep_backup() */
365+static const struct file_struct *backup_orig_file = NULL;
366+static const char null_string[] = "";
367+static const char *backup_orig_fname = null_string;
368+static const char *backup_dest_fname = null_string;
369+static rsync_xal backup_xal;
370+
371+/* ------------------------------------------------------------------------- */
372+
373+static void rsync_xal_free ( rsync_xal *x ) {
374+ size_t i;
375+
376+ for ( i = 0; i < x->count; i++ ) {
377+ free ( x->rxas[i].name );
378+ /* free ( x->rxas[i].value ); */
379+ }
380+ x->count = 0;
381+}
382+
383+static int rsync_xal_compare_names ( const void *x1, const void *x2 ) {
384+ const rsync_xa *xa1;
385+ const rsync_xa *xa2;
386+
387+ xa1 = x1;
388+ xa2 = x2;
389+ return strcmp ( xa1->name, xa2->name );
390+}
391+
392+static BOOL rsync_xal_get ( const char *fname, rsync_xal *x ) {
393+ ssize_t name_size;
394+ ssize_t datum_size;
395+ ssize_t left;
396+ char *name;
397+ size_t len;
398+ char *ptr;
399+
400+ if ( ! namebuf ) {
401+ namebuf_len = 100;
402+ namebuf = malloc ( 100 );
403+ datumbuf_len = 100;
404+ datumbuf = malloc ( 100 );
405+ if ( ! namebuf || ! datumbuf ) {
406+ rprintf(FERROR, "%s: rsync_xal_get: allocate intial buffers failed: %s\n",
407+ fname, strerror(errno));
408+ return False;
409+ }
410+ }
411+
412+ name_size = sys_llistxattr ( fname, namebuf, namebuf_len );
413+ if ( name_size > namebuf_len ) {
414+ name_size = -1;
415+ errno = ERANGE;
416+ }
417+ if ( name_size < 0 ) {
418+ if ( errno == ENOTSUP )
419+ return False;
420+ if ( errno == ERANGE ) {
421+ name_size = sys_llistxattr ( fname, NULL, 0 );
422+ if ( name_size < 0 ) {
423+ rprintf ( FERROR, "%s: rsync_xal_get: llistxattr: %s\n",
424+ fname, strerror(errno) );
425+ return False;
426+ }
427+ namebuf = realloc ( namebuf, name_size + 1 );
428+ if ( ! namebuf ) {
429+ rprintf ( FERROR, "%s: rsync_xal_get: reallocate namebuf to %lu failed: %s\n",
430+ fname, (unsigned long)name_size, strerror(errno) );
431+ return False;
432+ }
433+ namebuf_len = name_size;
434+ name_size = sys_llistxattr ( fname, namebuf, namebuf_len );
435+ if ( name_size < 0 ) {
436+ rprintf ( FERROR, "%s: rsync_xal_get: re-llistxattr failed: %s\n",
437+ fname, strerror(errno) );
438+ return False;
439+ }
440+ } else {
441+ rprintf(FERROR, "%s: rsync_xal_get: llistxattr failed: %s\n",
442+ fname, strerror(errno));
443+ return False;
444+ }
445+ }
446+ rsync_xal_free ( x );
447+ if ( name_size == 0 )
448+ return True;
449+ for ( left = name_size, name = namebuf; left > 0 ; left -= len, name += len ) {
450+ len = strlen ( name ) + 1;
451+
452+ if ( x->count >= x->alloc ) {
453+ size_t new_alloc;
454+ size_t new_size;
455+ rsync_xa *new_rxas;
456+
457+ new_alloc = ( x->alloc < RSYNC_XAL_INITIAL ) ? RSYNC_XAL_INITIAL : x->alloc * 2;
458+ new_size = new_alloc * sizeof(rsync_xa);
459+ new_rxas = x->alloc ? realloc ( x->rxas, new_size ) : malloc ( new_size );
460+ if ( new_rxas == NULL ) {
461+ rprintf(FERROR, "%s: rsync_xal_get: allocate %lufailed: %s\n",
462+ fname, (unsigned long)new_size, strerror(errno));
463+ return False;
464+ }
465+ x->alloc = new_alloc;
466+ x->rxas = new_rxas;
467+ }
468+ datum_size = sys_lgetxattr ( fname, name, datumbuf, datumbuf_len );
469+ if ( datum_size > datumbuf_len ) {
470+ datum_size = -1;
471+ errno = ERANGE;
472+ }
473+ if ( datum_size < 0 ) {
474+ if ( errno == ENOTSUP )
475+ return False;
476+ if ( errno == ERANGE ) {
477+ datum_size = sys_lgetxattr ( fname, name, NULL, 0 );
478+ if ( datum_size < 0 ) {
479+ rprintf ( FERROR, "%s: rsync_xal_get: lgetxattr %s failed: %s\n",
480+ fname, name, strerror(errno) );
481+ return False;
482+ }
483+ datumbuf = realloc ( datumbuf, datum_size + 1 );
484+ if ( ! datumbuf ) {
485+ rprintf(FERROR, "%s: rsync_xal_get: allocate %lu for datumbuf failed: %s\n",
486+ fname, (unsigned long)(datum_size + 1), strerror(errno));
487+ return False;
488+ }
489+ datumbuf_len = datum_size;
490+ datum_size = sys_lgetxattr ( fname, name, datumbuf, datumbuf_len );
491+ if ( datum_size < 0 ) {
492+ rprintf ( FERROR, "%s: rsync_xal_get: re-lgetxattr of %s failed: %s\n",
493+ name, fname, strerror(errno) );
494+ return False;
495+ }
496+ } else {
497+ rprintf(FERROR, "%s: rsync_xal_get: lgetxattr %s failed: %s\n",
498+ fname, name, strerror(errno));
499+ return False;
500+ }
501+ }
502+ ptr = malloc ( len + datum_size );
503+ strcpy ( ptr, name );
504+ if ( datum_size )
505+ memcpy ( ptr + len, datumbuf, datum_size );
506+ x->rxas[curr_rsync_xal.count].name_len = len;
507+ x->rxas[curr_rsync_xal.count].name = ptr;
508+ x->rxas[curr_rsync_xal.count].datum_len = datum_size;
509+ x->rxas[curr_rsync_xal.count].datum = ptr + len;
510+ x->count++;
511+ }
512+ if ( x->count > 1 ) {
513+ qsort ( x->rxas, x->count, sizeof(rsync_xa), rsync_xal_compare_names );
514+ }
515+ return True;
516+}
517+
518+
519+/* generate the xattr(s) for this flist entry;
520+ * xattr(s) are either sent or cleaned-up by send_xattr() below */
521+
522+BOOL make_xattr(const struct file_struct *file, const char *fname)
523+{
524+ if (!preserve_xattrs)
525+ return True;
526+
527+ rsync_xal_get ( fname, &curr_rsync_xal );
528+ return True;
529+}
530+
531+static ssize_t rsync_xal_find_matching ( void ) {
532+ size_t i;
533+ size_t j;
534+
535+ for ( i = 0; i < rsync_xal_l.count; i++ ) {
536+ /* Wrong number of elements? */
537+ if ( rsync_xal_l.rxals[i].count != curr_rsync_xal.count )
538+ continue;
539+ /* any elements different? */
540+ for ( j = 0; j < curr_rsync_xal.count; j++ ) {
541+ if (
542+ rsync_xal_l.rxals[i].rxas[j].name_len != curr_rsync_xal.rxas[j].name_len
543+ || rsync_xal_l.rxals[i].rxas[j].datum_len != curr_rsync_xal.rxas[j].datum_len
544+ || strcmp ( rsync_xal_l.rxals[i].rxas[j].name, curr_rsync_xal.rxas[j].name )
545+ || memcmp ( rsync_xal_l.rxals[i].rxas[j].datum, curr_rsync_xal.rxas[j].datum, curr_rsync_xal.rxas[j].datum_len ) )
546+ break;
547+ }
548+ /* no differences found. This is The One! */
549+ if ( j == curr_rsync_xal.count )
550+ break;
551+ }
552+ if ( i < rsync_xal_l.count )
553+ return i;
554+ return (ssize_t)-1;
555+}
556+
557+/* Store curr_rsync_xal on the end of rsync_xal_l */
558+static void rsync_xal_store ( void ) {
559+ if ( rsync_xal_l.count <= rsync_xal_l.alloc ) {
560+ size_t new_alloc;
561+ size_t new_size;
562+ void *new_xal;
563+
564+ new_alloc = ( rsync_xal_l.count < RSYNC_XAL_LIST_INITIAL ) ? RSYNC_XAL_LIST_INITIAL : rsync_xal_l.count * 2;
565+ new_size = new_alloc * sizeof(rsync_xal);
566+ new_xal = rsync_xal_l.count ? realloc ( rsync_xal_l.rxals, new_size ) : malloc ( new_size );
567+ if ( new_xal == NULL ) {
568+ rprintf ( FERROR, "rsync_xal_store: allocate %lu for new_xal failed\n", (unsigned long)new_size );
569+ exit_cleanup(RERR_STREAMIO );
570+ }
571+ rsync_xal_l.alloc = new_alloc;
572+ rsync_xal_l.rxals = new_xal;
573+ }
574+ rsync_xal_l.rxals[rsync_xal_l.count] = curr_rsync_xal;
575+ rsync_xal_l.count++;
576+ curr_rsync_xal.count = 0;
577+ curr_rsync_xal.alloc = 0;
578+}
579+
580+/* send the make_xattr()-generated xattr list for this flist entry,
581+ * or clean up after an flist entry that's not being sent (f == -1) */
582+
583+void send_xattr ( const struct file_struct *file, int f )
584+{
585+ ssize_t index;
586+
587+ if ( ! preserve_xattrs )
588+ return;
589+
590+ if (f == -1) {
591+ rsync_xal_free ( &curr_rsync_xal );
592+ return;
593+ }
594+ index = rsync_xal_find_matching ( );
595+ if ( index != -1) {
596+ write_byte(f, 'x' );
597+ write_int(f, index);
598+ rsync_xal_free ( &curr_rsync_xal );
599+ } else {
600+ rsync_xa *rxa;
601+ size_t count;
602+
603+ count = curr_rsync_xal.count;
604+ write_byte(f, 'X' );
605+ write_int(f, count);
606+ for (rxa = curr_rsync_xal.rxas; count--; rxa++) {
607+ write_int( f, rxa->name_len );
608+ write_int ( f, rxa->datum_len );
609+ write_buf ( f, rxa->name, rxa->name_len );
610+ write_buf ( f, rxa->datum, rxa->datum_len );
611+ }
612+ rsync_xal_store();
613+ }
614+}
615+
616+
617+/* ------------------------------------------------------------------------- */
618+/* receive and build the rsync_xattr_lists */
619+
620+void receive_xattr(struct file_struct *file, int f)
621+{
622+ char *fname;
623+ int tag;
624+
625+ if ( ! preserve_xattrs )
626+ return;
627+ fname = f_name(file);
628+ tag = read_byte(f);
629+ if (tag != 'X' && tag != 'x') {
630+ rprintf(FERROR, "%s: receive_xattr: unknown extended attribute type tag: %c\n",
631+ fname, tag);
632+ exit_cleanup(RERR_STREAMIO);
633+ }
634+
635+ if ( fxil.alloc <= fxil.count) {
636+ void *new_ptr;
637+ size_t new_alloc;
638+ size_t new_size;
639+
640+ if ( fxil.count < RSYNC_XAL_LIST_INITIAL )
641+ new_alloc = fxil.alloc + RSYNC_XAL_LIST_INITIAL;
642+ else
643+ new_alloc = fxil.alloc * 2;
644+ new_size = new_alloc * sizeof(file_xal_index);
645+ if ( fxil.alloc )
646+ new_ptr = realloc ( fxil.filexalidxs, new_size );
647+ else
648+ new_ptr = malloc ( new_size );
649+ if (!new_ptr)
650+ out_of_memory("receive_xattr");
651+ if (verbose >= 3) {
652+ rprintf(FINFO, "receive_xattr to %lu bytes, %s move\n",
653+ (unsigned long) new_size,
654+ fxil.filexalidxs == new_ptr ? "did not" : "did");
655+ }
656+
657+ fxil.filexalidxs = new_ptr;
658+ fxil.alloc = new_alloc;
659+ }
660+
661+ fxil.filexalidxs[fxil.count].file = file;
662+ if (tag == 'X' ) {
663+ size_t count;
664+ size_t i;
665+
666+ fxil.filexalidxs[fxil.count].xalidx = rsync_xal_l.count;
667+
668+ count = read_int ( f );
669+ curr_rsync_xal.count = count;
670+ curr_rsync_xal.alloc = count;
671+ curr_rsync_xal.rxas = malloc ( count * sizeof(rsync_xa) );
672+ if ( curr_rsync_xal.rxas == NULL ) {
673+ rprintf(FERROR, "%s: receive_xattr: allocate %lu xas failed\n",
674+ fname, (unsigned long)count );
675+ exit_cleanup(RERR_STREAMIO);
676+ }
677+ for ( i = 0; i < count; i++ ) {
678+ size_t name_len;
679+ size_t datum_len;
680+ char *ptr;
681+
682+ name_len = read_int ( f );
683+ datum_len = read_int ( f );
684+ ptr = malloc ( name_len + datum_len );
685+ read_buf ( f, ptr, name_len );
686+ read_buf ( f, ptr + name_len, datum_len );
687+ curr_rsync_xal.rxas[i].name_len = name_len;
688+ curr_rsync_xal.rxas[i].datum_len = datum_len;
689+ curr_rsync_xal.rxas[i].name = ptr;
690+ curr_rsync_xal.rxas[i].datum = ptr + name_len;
691+ }
692+ rsync_xal_store();
693+ } else {
694+ size_t index;
695+
696+ index = read_int(f);
697+ if ( index >= rsync_xal_l.count) {
698+ rprintf(FERROR, "%s: receive_xattr: xa index %lu out of range\n",
699+fname, (unsigned long)index );
700+ exit_cleanup(RERR_STREAMIO);
701+ }
702+ fxil.filexalidxs[fxil.count].xalidx = index;
703+ }
704+ fxil.count++;
705+}
706+
707+static BOOL rsync_xal_set ( const char *fname, rsync_xal *x ) {
708+ size_t i;
709+ int status;
710+ BOOL ret;
711+
712+ ret = True;
713+ for ( i = 0; i < x->count; i++ ) {
714+ status = sys_lsetxattr ( fname, x->rxas[i].name, x->rxas[i].datum, x->rxas[i].datum_len, 0 );
715+ if ( status < 0 ) {
716+ rprintf(FERROR, "%s: rsync_xal_set: lsetxattr %s failed: %s\n",
717+ fname, x->rxas[i].name, strerror(errno));
718+ ret = False;
719+ }
720+ }
721+ return ret;
722+}
723+
724+/* for duplicating xattrs on backups when using backup_dir */
725+
726+int dup_xattr ( const char *orig, const char *bak )
727+{
728+ int ret;
729+
730+ ret = 0;
731+ if (!preserve_xattrs)
732+ return ret;
733+
734+ ret = rsync_xal_get ( orig, &backup_xal );
735+ if ( ret == True )
736+ ret = rsync_xal_set ( bak, &backup_xal );
737+ rsync_xal_free ( &backup_xal );
738+ return ret;
739+}
740+
741+void push_keep_backup_xattr ( const struct file_struct *file, const char *orig, const char *dest )
742+{
743+ if ( ! preserve_xattrs )
744+ return;
745+
746+ backup_orig_file = file;
747+ backup_orig_fname = orig;
748+ backup_dest_fname = dest;
749+ rsync_xal_get ( orig, &backup_xal );
750+}
751+
752+static int set_keep_backup_xal ( void ) {
753+ if ( ! preserve_xattrs )
754+ return 0;
755+ return rsync_xal_set ( backup_dest_fname, &backup_xal );
756+}
757+
758+void cleanup_keep_backup_xattr ( void )
759+{
760+ if ( ! preserve_xattrs)
761+ return;
762+
763+ backup_orig_file = NULL;
764+ backup_orig_fname = null_string;
765+ backup_dest_fname = null_string;
766+ rsync_xal_free ( &backup_xal );
767+}
768+
769+static int file_xal_index_compare ( const void *x1, const void *x2 ) {
770+ const file_xal_index *xa1;
771+ const file_xal_index *xa2;
772+
773+ xa1 = x1;
774+ xa2 = x2;
775+ return ( xa1->file == xa2->file) ? 0 :
776+ ( ( xa1->file < xa2->file ) ? -1: 1 );
777+}
778+void sort_file_xattr_index_lists ( void )
779+{
780+ if ( ! preserve_xattrs )
781+ return;
782+ qsort ( fxil.filexalidxs, fxil.count, sizeof(file_xal_index),
783+ file_xal_index_compare );
784+}
785+
786+
787+static int find_file_xal_index( const struct file_struct *file) {
788+ int low = 0, high = fxil.count;
789+ const struct file_struct *file_mid;
790+
791+ if ( ! high-- ) {
792+ rprintf(FERROR, "find_file_xal_index: no entries\n");
793+ exit_cleanup(RERR_STREAMIO);
794+ return -1;
795+ }
796+ do {
797+ int mid = (high + low) / 2;
798+ file_mid = fxil.filexalidxs[mid].file;
799+ if (file_mid == file)
800+ return fxil.filexalidxs[mid].xalidx;
801+ if (file_mid > file)
802+ high = mid - 1;
803+ else
804+ low = mid + 1;
805+ } while (low < high);
806+ if (low == high) {
807+ file_mid = fxil.filexalidxs[low].file;
808+ if (file_mid == file)
809+ return fxil.filexalidxs[low].xalidx;
810+ }
811+ rprintf(FERROR,
812+ "find_file_xal_index: can't find entry for file in list\n");
813+ exit_cleanup(RERR_STREAMIO);
814+ return -1;
815+}
816+
817+
818+/* set extended attributes on rsync-ed or keep_backup-ed file */
819+
820+int set_xattr ( const char *fname, const struct file_struct *file )
821+{
822+ int updated;
823+ int xalidx;
824+ rsync_xal *x;
825+
826+ updated = 0;
827+ if ( dry_run || ! preserve_xattrs )
828+ return 0;
829+ if (file == backup_orig_file) {
830+ if (!strcmp(fname, backup_dest_fname))
831+ return set_keep_backup_xal();
832+ }
833+ xalidx = find_file_xal_index( file );
834+ x = &(rsync_xal_l.rxals[xalidx]);
835+ updated = rsync_xal_set ( fname, x );
836+ return updated;
837+}
838+
839+#endif /* SUPPORT_XATTRS */
840Common subdirectories: rsync-2.6.4pre2-prexattr/zlib and rsync-2.6.4pre2/zlib
841--- rsync-2.6.4/generator.c.xattr 2005-03-31 09:49:39.000000000 -0500
842+++ rsync-2.6.4/generator.c 2005-03-31 09:59:22.000000000 -0500
843@@ -715,6 +715,10 @@
844 if (f_out == -1)
845 SET_ACL(fname, file);
846 #endif
847+#if SUPPORT_XATTRS
848+ if ( f_out == -1 )
849+ SET_XATTR( fname, file );
850+#endif
851 if (delete_during && f_out != -1 && !phase && dry_run < 2
852 && (file->flags & FLAG_DEL_HERE))
853 delete_in_dir(the_file_list, fname, file);
854--- rsync-2.6.5/flist.c.xattr 2005-06-02 14:26:25.000000000 -0400
855+++ rsync-2.6.5/flist.c 2005-06-02 14:33:02.000000000 -0400
856@@ -976,6 +976,8 @@
857 return NULL;
858 if (!MAKE_ACL(file, fname))
859 return NULL;
860+ if ( ! MAKE_XATTR(file, fname ) )
861+ return;
862
863 maybe_emit_filelist_progress(flist->count + flist_count_offset);
864
865@@ -985,9 +987,11 @@
866 flist->files[flist->count++] = file;
867 send_file_entry(file, f, base_flags);
868 SEND_ACL(file, f);
869+ SEND_XATTR ( file, f );
870 } else {
871 /* Cleanup unsent ACL(s). */
872 SEND_ACL(file, -1);
873+ SEND_XATTR( file, -1 );
874 }
875 return file;
876 }
877@@ -1325,6 +1329,7 @@
878 file = receive_file_entry(flist, flags, f);
879
880 RECEIVE_ACL(file, f);
881+ RECEIVE_XATTR(file, f );
882
883 if (S_ISREG(file->mode))
884 stats.total_size += file->length;
885@@ -1349,6 +1354,7 @@
886 clean_flist(flist, relative_paths, 1);
887
888 SORT_FILE_ACL_INDEX_LISTS();
889+ SORT_FILE_XATTR_INDEX_LISTS();
890
891 if (f >= 0) {
892 /* Now send the uid/gid list. This was introduced in
893--- rsync-2.6.6/Makefile.in.xattr 2005-07-28 16:16:07.000000000 -0400
894+++ rsync-2.6.6/Makefile.in 2005-07-28 16:18:13.000000000 -0400
895@@ -27,13 +27,13 @@
896
897 HEADERS=byteorder.h config.h errcode.h proto.h rsync.h smb_acls.h lib/pool_alloc.h
898 LIBOBJ=lib/wildmatch.o lib/compat.o lib/snprintf.o lib/mdfour.o \
899- lib/permstring.o lib/pool_alloc.o lib/sysacls.o @LIBOBJS@
900+ lib/permstring.o lib/pool_alloc.o lib/sysacls.o lib/sysxattr.o @LIBOBJS@
901 ZLIBOBJ=zlib/deflate.o zlib/inffast.o zlib/inflate.o zlib/inftrees.o \
902 zlib/trees.o zlib/zutil.o zlib/adler32.o zlib/compress.o zlib/crc32.o
903 OBJS1=rsync.o generator.o receiver.o cleanup.o sender.o exclude.o util.o \
904 main.o checksum.o match.o syscall.o log.o backup.o
905 OBJS2=options.o flist.o io.o compat.o hlink.o token.o uidlist.o socket.o \
906- fileio.o batch.o clientname.o acls.o
907+ fileio.o batch.o clientname.o acls.o xattr.o
908 OBJS3=progress.o pipe.o
909 DAEMON_OBJ = params.o loadparm.o clientserver.o access.o connection.o authenticate.o
910 popt_OBJS=popt/findme.o popt/popt.o popt/poptconfig.o \
This page took 0.51578 seconds and 4 git commands to generate.