]>
Commit | Line | Data |
---|---|---|
1 | --- coreutils-6.2.orig/configure.ac | |
2 | +++ coreutils-6.2/configure.ac | |
3 | @@ -246,6 +246,9 @@ AC_CHECK_DECLS([strtoimax, strtoumax]) | |
4 | ||
5 | cu_LIB_CHECK | |
6 | ||
7 | +# Extended attribute copying. | |
8 | +AC_FUNC_XATTR | |
9 | + | |
10 | AM_GNU_GETTEXT([external], [need-formatstring-macros]) | |
11 | AM_GNU_GETTEXT_VERSION([0.15]) | |
12 | ||
13 | --- /dev/null | |
14 | +++ coreutils-6.2/m4/xattr.m4 | |
15 | @@ -0,0 +1,38 @@ | |
16 | +# xattr.m4 - check for Extended Attributes (Linux) | |
17 | + | |
18 | +# Copyright (C) 2003 Free Software Foundation, Inc. | |
19 | + | |
20 | +# This program is free software; you can redistribute it and/or modify | |
21 | +# it under the terms of the GNU General Public License as published by | |
22 | +# the Free Software Foundation; either version 2, or (at your option) | |
23 | +# any later version. | |
24 | + | |
25 | +# This program is distributed in the hope that it will be useful, | |
26 | +# but WITHOUT ANY WARRANTY; without even the implied warranty of | |
27 | +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
28 | +# GNU General Public License for more details. | |
29 | + | |
30 | +# You should have received a copy of the GNU General Public License | |
31 | +# along with this program; if not, write to the Free Software Foundation, | |
32 | +# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ | |
33 | + | |
34 | +# Written by Andreas Gruenbacher. | |
35 | + | |
36 | +AC_DEFUN([AC_FUNC_XATTR], | |
37 | +[ | |
38 | + AC_CHECK_HEADERS(attr/error_context.h attr/libattr.h) | |
39 | + if test "$ac_cv_header_attr_libattr_h" = yes \ | |
40 | + && test "$ac_cv_header_attr_error_context_h" = yes; then | |
41 | + use_xattr=1 | |
42 | + else | |
43 | + use_xattr=0 | |
44 | + fi | |
45 | + AC_DEFINE_UNQUOTED(USE_XATTR, $use_xattr, | |
46 | + [Define if you want extended attribute support.]) | |
47 | + xattr_saved_LIBS=$LIBS | |
48 | + AC_SEARCH_LIBS(attr_copy_file, attr, | |
49 | + [test "$ac_cv_search_attr_copy_file" = "none required" || LIB_XATTR=$ac_cv_search_attr_copy_file]) | |
50 | + AC_SUBST(LIB_XATTR) | |
51 | + AC_CHECK_FUNCS(attr_copy_file) | |
52 | + LIBS=$xattr_saved_LIBS | |
53 | +]) | |
54 | --- coreutils-6.2.orig/src/Makefile.am | |
55 | +++ coreutils-6.2/src/Makefile.am | |
56 | @@ -112,6 +112,10 @@ cp_LDADD += $(LIB_ACL) | |
57 | mv_LDADD += $(LIB_ACL) | |
58 | ginstall_LDADD += $(LIB_ACL) | |
59 | ||
60 | +cp_LDADD += $(LIB_XATTR) | |
61 | +mv_LDADD += $(LIB_XATTR) | |
62 | +ginstall_LDADD += $(LIB_XATTR) | |
63 | + | |
64 | $(PROGRAMS): ../lib/libcoreutils.a | |
65 | ||
66 | SUFFIXES = .sh | |
67 | --- coreutils-6.2.orig/src/copy.c | |
68 | +++ coreutils-6.2/src/copy.c | |
69 | @@ -53,6 +53,12 @@ | |
70 | #include "xreadlink.h" | |
71 | #include "yesno.h" | |
72 | ||
73 | +#if USE_XATTR | |
74 | +# include <stdarg.h> | |
75 | +# include <attr/error_context.h> | |
76 | +# include <attr/libattr.h> | |
77 | +#endif | |
78 | + | |
79 | #ifndef HAVE_FCHOWN | |
80 | # define HAVE_FCHOWN false | |
81 | # define fchown(fd, uid, gid) (-1) | |
82 | @@ -118,6 +124,98 @@ is_ancestor (const struct stat *sb, cons | |
83 | return false; | |
84 | } | |
85 | ||
86 | +#if USE_XATTR | |
87 | +static void | |
88 | +copy_xattr_error (struct error_context *ctx, const char *fmt, ...) | |
89 | +{ | |
90 | + int err = errno; | |
91 | + va_list ap; | |
92 | + int len; | |
93 | + char *buffer; | |
94 | + | |
95 | + /* There is no error function that takes a va_list argument, | |
96 | + so we print the message in a buffer first. */ | |
97 | + | |
98 | + va_start (ap, fmt); | |
99 | + len = vsnprintf (NULL, 0, fmt, ap); | |
100 | + va_end (ap); | |
101 | + if (len > 0) | |
102 | + { | |
103 | + buffer = xmalloc (len + 1); | |
104 | + va_start (ap, fmt); | |
105 | + vsnprintf (buffer, len + 1, fmt, ap); | |
106 | + va_end (ap); | |
107 | + error (0, err, "%s", buffer); | |
108 | + free (buffer); | |
109 | + } | |
110 | +} | |
111 | + | |
112 | +static const char * | |
113 | +copy_xattr_quote (struct error_context *ctx, const char *str) | |
114 | +{ | |
115 | + return xstrdup (quote (str)); | |
116 | +} | |
117 | + | |
118 | +static void | |
119 | +copy_xattr_free (struct error_context *ctx, const char *str) | |
120 | +{ | |
121 | + free ((void *) str); | |
122 | +} | |
123 | + | |
124 | +struct copy_xattr_context { | |
125 | + struct error_context ctx; | |
126 | + struct cp_options *x; | |
127 | +}; | |
128 | + | |
129 | +static int | |
130 | +copy_xattr_filter (const char *name, struct error_context *ctx) | |
131 | +{ | |
132 | + struct copy_xattr_context *copy_ctx = (struct copy_xattr_context *) ctx; | |
133 | + int action; | |
134 | + | |
135 | + /* We handle POSIX ACLs separately. */ | |
136 | + if (!strcmp(name, "system.posix_acl_access") | |
137 | + || !strcmp(name, "system.posix_acl_default")) | |
138 | + return 0; | |
139 | + | |
140 | + action = attr_copy_action(name, ctx); | |
141 | + return (action != ATTR_ACTION_SKIP && | |
142 | + (!copy_ctx->x->preserve_mode | |
143 | + || action != ATTR_ACTION_PERMISSIONS)); | |
144 | +} | |
145 | +#endif /* USE_XATTR */ | |
146 | + | |
147 | +static bool | |
148 | +copy_xattrs (const char *src_path, int source_desc, const char *dst_path, | |
149 | + int dest_desc, const struct cp_options *x) | |
150 | +{ | |
151 | + struct copy_xattr_context copy_xattr_ctx = { | |
152 | + { copy_xattr_error, | |
153 | + copy_xattr_quote, | |
154 | + copy_xattr_free }, | |
155 | + x | |
156 | + }; | |
157 | + | |
158 | +#if USE_XATTR | |
159 | + if (x->preserve_xattrs) | |
160 | + { | |
161 | + int ret; | |
162 | + | |
163 | + if (source_desc != -1 && dest_desc != -1) | |
164 | + ret = attr_copy_fd(src_path, source_desc, dst_path, dest_desc, | |
165 | + copy_xattr_filter, ©_xattr_ctx.ctx); | |
166 | + else | |
167 | + ret = attr_copy_file (src_path, dst_path, | |
168 | + copy_xattr_filter, ©_xattr_ctx.ctx); | |
169 | + return ret == 0 || !x->require_preserve; | |
170 | + } | |
171 | + else | |
172 | + return true; | |
173 | +#else /* USE_XATTR */ | |
174 | + return true; | |
175 | +#endif /* USE_XATTR */ | |
176 | +} | |
177 | + | |
178 | /* Read the contents of the directory SRC_NAME_IN, and recursively | |
179 | copy the contents to DST_NAME_IN. NEW_DST is true if | |
180 | DST_NAME_IN is a directory that was created previously in the | |
181 | @@ -509,6 +607,9 @@ copy_reg (char const *src_name, char con | |
182 | } | |
183 | } | |
184 | ||
185 | + if (!copy_xattrs (src_name, source_desc, dst_name, dest_desc, x)) | |
186 | + return_val = false; | |
187 | + | |
188 | set_author (dst_name, dest_desc, src_sb); | |
189 | ||
190 | if (x->preserve_mode || x->move_mode) | |
191 | @@ -1755,6 +1856,9 @@ copy_internal (char const *src_name, cha | |
192 | return false; | |
193 | } | |
194 | ||
195 | + if (!copy_xattrs (src_name, -1, dst_name, -1, x)) | |
196 | + delayed_ok = false; | |
197 | + | |
198 | set_author (dst_name, -1, &src_sb); | |
199 | ||
200 | if (x->preserve_mode || x->move_mode) | |
201 | --- coreutils-6.2.orig/src/copy.h | |
202 | +++ coreutils-6.2/src/copy.h | |
203 | @@ -128,6 +128,9 @@ struct cp_options | |
204 | bool preserve_mode; | |
205 | bool preserve_timestamps; | |
206 | ||
207 | + /* If true, attempt to copy extended attributes. */ | |
208 | + bool preserve_xattrs; | |
209 | + | |
210 | /* Enabled for mv, and for cp by the --preserve=links option. | |
211 | If true, attempt to preserve in the destination files any | |
212 | logical hard links between the source files. If used with cp's | |
213 | --- coreutils-6.2.orig/src/cp.c | |
214 | +++ coreutils-6.2/src/cp.c | |
215 | @@ -191,7 +191,7 @@ Mandatory arguments to long options are | |
216 | -p same as --preserve=mode,ownership,timestamps\n\ | |
217 | --preserve[=ATTR_LIST] preserve the specified attributes (default:\n\ | |
218 | mode,ownership,timestamps), if possible\n\ | |
219 | - additional attributes: links, all\n\ | |
220 | + additional attributes: links, xattrs, all\n\ | |
221 | "), stdout); | |
222 | fputs (_("\ | |
223 | --no-preserve=ATTR_LIST don't preserve the specified attributes\n\ | |
224 | @@ -724,6 +724,7 @@ cp_option_init (struct cp_options *x) | |
225 | x->preserve_links = false; | |
226 | x->preserve_mode = false; | |
227 | x->preserve_timestamps = false; | |
228 | + x->preserve_xattrs = false; | |
229 | ||
230 | x->require_preserve = false; | |
231 | x->recursive = false; | |
232 | @@ -752,18 +753,21 @@ decode_preserve_arg (char const *arg, st | |
233 | PRESERVE_TIMESTAMPS, | |
234 | PRESERVE_OWNERSHIP, | |
235 | PRESERVE_LINK, | |
236 | + PRESERVE_XATTRS, | |
237 | PRESERVE_ALL | |
238 | }; | |
239 | static enum File_attribute const preserve_vals[] = | |
240 | { | |
241 | PRESERVE_MODE, PRESERVE_TIMESTAMPS, | |
242 | - PRESERVE_OWNERSHIP, PRESERVE_LINK, PRESERVE_ALL | |
243 | + PRESERVE_OWNERSHIP, PRESERVE_LINK, | |
244 | + PRESERVE_XATTRS, PRESERVE_ALL | |
245 | }; | |
246 | /* Valid arguments to the `--preserve' option. */ | |
247 | static char const* const preserve_args[] = | |
248 | { | |
249 | "mode", "timestamps", | |
250 | - "ownership", "links", "all", NULL | |
251 | + "ownership", "links", | |
252 | + "xattrs", "all", NULL | |
253 | }; | |
254 | ARGMATCH_VERIFY (preserve_args, preserve_vals); | |
255 | ||
256 | @@ -799,11 +803,16 @@ decode_preserve_arg (char const *arg, st | |
257 | x->preserve_links = on_off; | |
258 | break; | |
259 | ||
260 | + case PRESERVE_XATTRS: | |
261 | + x->preserve_xattrs = on_off; | |
262 | + break; | |
263 | + | |
264 | case PRESERVE_ALL: | |
265 | x->preserve_mode = on_off; | |
266 | x->preserve_timestamps = on_off; | |
267 | x->preserve_ownership = on_off; | |
268 | x->preserve_links = on_off; | |
269 | + x->preserve_xattrs = on_off; | |
270 | break; | |
271 | ||
272 | default: | |
273 | --- coreutils-6.2.orig/src/install.c | |
274 | +++ coreutils-6.2/src/install.c | |
275 | @@ -154,6 +154,7 @@ cp_option_init (struct cp_options *x) | |
276 | x->preserve_links = false; | |
277 | x->preserve_mode = false; | |
278 | x->preserve_timestamps = false; | |
279 | + x->preserve_xattrs = false; | |
280 | x->require_preserve = false; | |
281 | x->recursive = false; | |
282 | x->sparse_mode = SPARSE_AUTO; | |
283 | --- coreutils-6.2.orig/src/mv.c | |
284 | +++ coreutils-6.2/src/mv.c | |
285 | @@ -125,6 +125,7 @@ cp_option_init (struct cp_options *x) | |
286 | x->preserve_links = true; | |
287 | x->preserve_mode = true; | |
288 | x->preserve_timestamps = true; | |
289 | + x->preserve_xattrs = true; | |
290 | x->require_preserve = false; /* FIXME: maybe make this an option */ | |
291 | x->recursive = true; | |
292 | x->sparse_mode = SPARSE_AUTO; /* FIXME: maybe make this an option */ | |
293 | --- coreutils-6.2.orig/doc/coreutils.texi | |
294 | +++ coreutils-6.2/doc/coreutils.texi | |
295 | @@ -6948,6 +6948,8 @@ Preserve in the destination files | |
296 | any links between corresponding source files. | |
297 | @c Give examples illustrating how hard links are preserved. | |
298 | @c Also, show how soft links map to hard links with -L and -H. | |
299 | +@itemx xattrs | |
300 | +Preserve extended attributes. (See /etc/xattr.conf.) | |
301 | @itemx all | |
302 | Preserve all file attributes. | |
303 | Equivalent to specifying all of the above. |