]>
Commit | Line | Data |
---|---|---|
5e993f12 | 1 | --- coreutils-6.11/configure.ac |
2 | +++ coreutils-6.11/configure.ac | |
3 | @@ -249,6 +249,9 @@ | |
4 | AC_SUBST([CONFIG_STATUS_DEPENDENCIES]) | |
5 | ############################################################################ | |
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 | --- coreutils-6.11/m4/xattr.m4 | |
14 | +++ coreutils-6.11/m4/xattr.m4 | |
15 | @@ -0,0 +1,44 @@ | |
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_ARG_ENABLE(xattr, | |
39 | + [ --disable-xattr turn off support for extended attributes], | |
40 | + use_xattr=$enableval, use_xattr=yes) | |
41 | + | |
42 | + if test "$use_xattr" = "yes"; then | |
43 | + AC_CHECK_HEADERS(attr/error_context.h attr/libattr.h) | |
44 | + if test "$ac_cv_header_attr_libattr_h" = yes \ | |
45 | + && test "$ac_cv_header_attr_error_context_h" = yes; then | |
46 | + use_xattr=1 | |
47 | + else | |
48 | + use_xattr=0 | |
49 | + fi | |
50 | + AC_DEFINE_UNQUOTED(USE_XATTR, $use_xattr, | |
51 | + [Define if you want extended attribute support.]) | |
52 | + xattr_saved_LIBS=$LIBS | |
53 | + AC_SEARCH_LIBS(attr_copy_file, attr, | |
54 | + [test "$ac_cv_search_attr_copy_file" = "none required" || LIB_XATTR=$ac_cv_search_attr_copy_file]) | |
55 | + AC_SUBST(LIB_XATTR) | |
56 | + AC_CHECK_FUNCS(attr_copy_file) | |
57 | + LIBS=$xattr_saved_LIBS | |
58 | + fi | |
59 | +]) | |
60 | --- coreutils-6.11/src/copy.c | |
61 | +++ coreutils-6.11/src/copy.c | |
62 | @@ -53,6 +53,12 @@ | |
63 | #include "areadlink.h" | |
64 | #include "yesno.h" | |
65 | ||
66 | +#if USE_XATTR | |
67 | +# include <stdarg.h> | |
68 | +# include <attr/error_context.h> | |
69 | +# include <attr/libattr.h> | |
70 | +#endif | |
71 | + | |
72 | #ifndef HAVE_FCHOWN | |
73 | # define HAVE_FCHOWN false | |
74 | # define fchown(fd, uid, gid) (-1) | |
75 | @@ -118,6 +124,98 @@ is_ancestor (const struct stat *sb, cons | |
76 | return false; | |
77 | } | |
78 | ||
79 | +#if USE_XATTR | |
80 | +static void | |
81 | +copy_xattr_error (struct error_context *ctx, const char *fmt, ...) | |
82 | +{ | |
83 | + int err = errno; | |
84 | + va_list ap; | |
85 | + int len; | |
86 | + char *buffer; | |
87 | + | |
88 | + /* There is no error function that takes a va_list argument, | |
89 | + so we print the message in a buffer first. */ | |
90 | + | |
91 | + va_start (ap, fmt); | |
92 | + len = vsnprintf (NULL, 0, fmt, ap); | |
93 | + va_end (ap); | |
94 | + if (len > 0) | |
95 | + { | |
96 | + buffer = xmalloc (len + 1); | |
97 | + va_start (ap, fmt); | |
98 | + vsnprintf (buffer, len + 1, fmt, ap); | |
99 | + va_end (ap); | |
100 | + error (0, err, "%s", buffer); | |
101 | + free (buffer); | |
102 | + } | |
103 | +} | |
104 | + | |
105 | +static const char * | |
106 | +copy_xattr_quote (struct error_context *ctx, const char *str) | |
107 | +{ | |
108 | + return xstrdup (quote (str)); | |
109 | +} | |
110 | + | |
111 | +static void | |
112 | +copy_xattr_free (struct error_context *ctx, const char *str) | |
113 | +{ | |
114 | + free ((void *) str); | |
115 | +} | |
116 | + | |
117 | +struct copy_xattr_context { | |
118 | + struct error_context ctx; | |
119 | + struct cp_options *x; | |
120 | +}; | |
121 | + | |
122 | +static int | |
123 | +copy_xattr_filter (const char *name, struct error_context *ctx) | |
124 | +{ | |
125 | + struct copy_xattr_context *copy_ctx = (struct copy_xattr_context *) ctx; | |
126 | + int action; | |
127 | + | |
128 | + /* We handle POSIX ACLs separately. */ | |
129 | + if (!strcmp(name, "system.posix_acl_access") | |
130 | + || !strcmp(name, "system.posix_acl_default")) | |
131 | + return 0; | |
132 | + | |
133 | + action = attr_copy_action(name, ctx); | |
134 | + return (action != ATTR_ACTION_SKIP && | |
135 | + (!copy_ctx->x->preserve_mode | |
136 | + || action != ATTR_ACTION_PERMISSIONS)); | |
137 | +} | |
138 | +#endif /* USE_XATTR */ | |
139 | + | |
140 | +static bool | |
141 | +copy_xattrs (const char *src_path, int source_desc, const char *dst_path, | |
142 | + int dest_desc, const struct cp_options *x) | |
143 | +{ | |
144 | + struct copy_xattr_context copy_xattr_ctx = { | |
145 | + { copy_xattr_error, | |
146 | + copy_xattr_quote, | |
147 | + copy_xattr_free }, | |
148 | + x | |
149 | + }; | |
150 | + | |
151 | +#if USE_XATTR | |
152 | + if (x->preserve_xattrs) | |
153 | + { | |
154 | + int ret; | |
155 | + | |
156 | + if (source_desc != -1 && dest_desc != -1) | |
157 | + ret = attr_copy_fd(src_path, source_desc, dst_path, dest_desc, | |
158 | + copy_xattr_filter, ©_xattr_ctx.ctx); | |
159 | + else | |
160 | + ret = attr_copy_file (src_path, dst_path, | |
161 | + copy_xattr_filter, ©_xattr_ctx.ctx); | |
162 | + return ret == 0 || !x->require_preserve; | |
163 | + } | |
164 | + else | |
165 | + return true; | |
166 | +#else /* USE_XATTR */ | |
167 | + return true; | |
168 | +#endif /* USE_XATTR */ | |
169 | +} | |
170 | + | |
171 | /* Read the contents of the directory SRC_NAME_IN, and recursively | |
172 | copy the contents to DST_NAME_IN. NEW_DST is true if | |
173 | DST_NAME_IN is a directory that was created previously in the | |
174 | @@ -509,6 +607,9 @@ copy_reg (char const *src_name, char con | |
175 | } | |
176 | } | |
177 | ||
178 | + if (!copy_xattrs (src_name, source_desc, dst_name, dest_desc, x)) | |
179 | + return_val = false; | |
180 | + | |
181 | set_author (dst_name, dest_desc, src_sb); | |
182 | ||
183 | if (x->preserve_mode || x->move_mode) | |
184 | @@ -1755,6 +1856,9 @@ copy_internal (char const *src_name, cha | |
185 | } | |
186 | } | |
187 | ||
188 | + if (!copy_xattrs (src_name, -1, dst_name, -1, x)) | |
189 | + delayed_ok = false; | |
190 | + | |
191 | set_author (dst_name, -1, &src_sb); | |
192 | ||
193 | if (x->preserve_mode || x->move_mode) | |
194 | --- coreutils-6.11/src/copy.h | |
195 | +++ coreutils-6.11/src/copy.h | |
196 | @@ -128,6 +128,9 @@ struct cp_options | |
197 | bool preserve_mode; | |
198 | bool preserve_timestamps; | |
199 | ||
200 | + /* If true, attempt to copy extended attributes. */ | |
201 | + bool preserve_xattrs; | |
202 | + | |
203 | /* Enabled for mv, and for cp by the --preserve=links option. | |
204 | If true, attempt to preserve in the destination files any | |
205 | logical hard links between the source files. If used with cp's | |
206 | --- coreutils-6.11/src/cp.c | |
207 | +++ coreutils-6.11/src/cp.c | |
208 | @@ -191,7 +191,7 @@ Mandatory arguments to long options are | |
209 | -p same as --preserve=mode,ownership,timestamps\n\ | |
210 | --preserve[=ATTR_LIST] preserve the specified attributes (default:\n\ | |
211 | mode,ownership,timestamps), if possible\n\ | |
212 | - additional attributes: context, links, all\n\ | |
213 | + additional attributes: context, links, xattrs, all\n\ | |
214 | "), stdout); | |
215 | fputs (_("\ | |
216 | --no-preserve=ATTR_LIST don't preserve the specified attributes\n\ | |
217 | @@ -724,6 +724,7 @@ cp_option_init (struct cp_options *x) | |
218 | x->preserve_timestamps = false; | |
219 | x->preserve_security_context = false; | |
220 | x->require_preserve_context = false; | |
221 | + x->preserve_xattrs = false; | |
222 | ||
223 | x->require_preserve = false; | |
224 | x->recursive = false; | |
225 | @@ -752,18 +753,21 @@ decode_preserve_arg (char const *arg, st | |
226 | PRESERVE_OWNERSHIP, | |
227 | PRESERVE_LINK, | |
228 | PRESERVE_CONTEXT, | |
229 | + PRESERVE_XATTRS, | |
230 | PRESERVE_ALL | |
231 | }; | |
232 | static enum File_attribute const preserve_vals[] = | |
233 | { | |
234 | PRESERVE_MODE, PRESERVE_TIMESTAMPS, | |
235 | - PRESERVE_OWNERSHIP, PRESERVE_LINK, PRESERVE_CONTEXT, PRESERVE_ALL | |
236 | + PRESERVE_OWNERSHIP, PRESERVE_LINK, PRESERVE_CONTEXT, | |
237 | + PRESERVE_XATTRS, PRESERVE_ALL | |
238 | }; | |
239 | /* Valid arguments to the `--preserve' option. */ | |
240 | static char const* const preserve_args[] = | |
241 | { | |
242 | "mode", "timestamps", | |
243 | - "ownership", "links", "context", "all", NULL | |
244 | + "ownership", "links", "context", | |
245 | + "xattrs", "all", NULL | |
246 | }; | |
247 | ARGMATCH_VERIFY (preserve_args, preserve_vals); | |
248 | ||
249 | @@ -799,13 +803,18 @@ decode_preserve_arg (char const *arg, st | |
250 | x->require_preserve_context = on_off; | |
251 | break; | |
252 | ||
253 | + case PRESERVE_XATTRS: | |
254 | + x->preserve_xattrs = on_off; | |
255 | + break; | |
256 | + | |
257 | case PRESERVE_ALL: | |
258 | x->preserve_mode = on_off; | |
259 | x->preserve_timestamps = on_off; | |
260 | x->preserve_ownership = on_off; | |
261 | x->preserve_links = on_off; | |
262 | if (selinux_enabled) | |
263 | x->preserve_security_context = on_off; | |
264 | + x->preserve_xattrs = on_off; | |
265 | break; | |
266 | ||
267 | default: | |
268 | --- coreutils-6.11/src/install.c | |
269 | +++ coreutils-6.11/src/install.c | |
270 | @@ -154,6 +154,7 @@ cp_option_init (struct cp_options *x) | |
271 | x->preserve_links = false; | |
272 | x->preserve_mode = false; | |
273 | x->preserve_timestamps = false; | |
274 | + x->preserve_xattrs = false; | |
275 | x->require_preserve = false; | |
276 | x->require_preserve_context = false; | |
277 | x->recursive = false; | |
278 | --- coreutils-6.11/src/mv.c | |
279 | +++ coreutils-6.11/src/mv.c | |
280 | @@ -125,6 +125,7 @@ cp_option_init (struct cp_options *x) | |
281 | x->preserve_mode = true; | |
282 | x->preserve_timestamps = true; | |
283 | x->preserve_security_context = selinux_enabled; | |
284 | + x->preserve_xattrs = true; | |
285 | x->require_preserve = false; /* FIXME: maybe make this an option */ | |
286 | x->require_preserve_context = false; | |
287 | x->recursive = true; | |
288 | --- coreutils-6.11/doc/coreutils.texi | |
289 | +++ coreutils-6.11/doc/coreutils.texi | |
290 | @@ -6948,6 +6948,8 @@ Preserve in the destination files | |
291 | any links between corresponding source files. | |
292 | @c Give examples illustrating how hard links are preserved. | |
293 | @c Also, show how soft links map to hard links with -L and -H. | |
294 | +@itemx xattrs | |
295 | +Preserve extended attributes. (See /etc/xattr.conf.) | |
296 | @itemx all | |
297 | Preserve all file attributes. | |
298 | Equivalent to specifying all of the above. | |
299 | --- coreutils-6.11/src/Makefile.am | |
300 | +++ coreutils-6.11/src/Makefile.am | |
301 | @@ -107,9 +107,9 @@ | |
302 | dir_LDADD += $(LIB_ACL) | |
303 | ls_LDADD += $(LIB_ACL) | |
304 | vdir_LDADD += $(LIB_ACL) | |
305 | -cp_LDADD += $(LIB_ACL) | |
306 | -mv_LDADD += $(LIB_ACL) | |
307 | -ginstall_LDADD += $(LIB_ACL) | |
308 | +cp_LDADD += $(LIB_ACL) $(LIB_XATTR) | |
309 | +mv_LDADD += $(LIB_ACL) $(LIB_XATTR) | |
310 | +ginstall_LDADD += $(LIB_ACL) $(LIB_XATTR) | |
311 | ||
312 | stat_LDADD = $(LDADD) $(LIB_SELINUX) | |
313 |