Lines 44-49
Link Here
|
44 |
#include "xreadlink.h" |
44 |
#include "xreadlink.h" |
45 |
#include "acl.h" |
45 |
#include "acl.h" |
46 |
|
46 |
|
|
|
47 |
#ifdef USE_XATTR |
48 |
# include "regex.h" |
49 |
# include <stdarg.h> |
50 |
# include <attr/error_context.h> |
51 |
# include <attr/libattr.h> |
52 |
#endif |
53 |
|
47 |
#define DO_CHOWN(Chown, File, New_uid, New_gid) \ |
54 |
#define DO_CHOWN(Chown, File, New_uid, New_gid) \ |
48 |
(Chown (File, New_uid, New_gid) \ |
55 |
(Chown (File, New_uid, New_gid) \ |
49 |
/* If non-root uses -p, it's ok if we can't preserve ownership. \ |
56 |
/* If non-root uses -p, it's ok if we can't preserve ownership. \ |
Lines 114-119
Link Here
|
114 |
return 0; |
121 |
return 0; |
115 |
} |
122 |
} |
116 |
|
123 |
|
|
|
124 |
#if USE_XATTR |
125 |
static void |
126 |
copy_attr_error (struct error_context *ctx, const char *fmt, ...) |
127 |
{ |
128 |
int err = errno; |
129 |
va_list ap; |
130 |
int len; |
131 |
char *buffer; |
132 |
|
133 |
/* There is no error function that takes a va_list argument, |
134 |
so we print the message in a buffer first. */ |
135 |
|
136 |
va_start (ap, fmt); |
137 |
len = vsnprintf (NULL, 0, fmt, ap); |
138 |
if (len > 0) |
139 |
{ |
140 |
buffer = xmalloc (len + 1); |
141 |
vsnprintf (buffer, len + 1, fmt, ap); |
142 |
error (0, err, "%s", buffer); |
143 |
free (buffer); |
144 |
} |
145 |
va_end (ap); |
146 |
} |
147 |
|
148 |
static const char * |
149 |
copy_attr_quote (struct error_context *ctx, const char *str) |
150 |
{ |
151 |
return xstrdup (quote (str)); |
152 |
} |
153 |
|
154 |
static void |
155 |
copy_attr_free (struct error_context *ctx, const char *str) |
156 |
{ |
157 |
free ((void *) str); |
158 |
} |
159 |
|
160 |
struct copy_attr_context |
161 |
{ |
162 |
struct error_context ctx; |
163 |
const char *re_pattern; |
164 |
struct re_pattern_buffer re_compiled; |
165 |
} copy_attr_ctx = { |
166 |
{ copy_attr_error, |
167 |
copy_attr_quote, |
168 |
copy_attr_free } |
169 |
}; |
170 |
|
171 |
static int |
172 |
copy_attr_filter (const char *name, struct error_context *ctx) |
173 |
{ |
174 |
struct copy_attr_context *copy_ctx = (struct copy_attr_context *) ctx; |
175 |
|
176 |
return (attr_copy_check_permissions (name, ctx) |
177 |
&& copy_ctx->re_pattern != NULL |
178 |
&& re_search (©_ctx->re_compiled, name, strlen (name), 0, |
179 |
strlen (name), NULL) >= 0); |
180 |
} |
181 |
#endif /* USE_XATTR */ |
182 |
|
183 |
static int |
184 |
copy_extended_attributes (const char *src_path, const char *dst_path, |
185 |
const struct cp_options *x) |
186 |
{ |
187 |
#if USE_XATTR |
188 |
if (x->attr_pattern == NULL) |
189 |
return 0; |
190 |
|
191 |
if (copy_attr_ctx.re_pattern != x->attr_pattern) |
192 |
{ |
193 |
struct re_pattern_buffer *c = ©_attr_ctx.re_compiled; |
194 |
size_t len = strlen (x->attr_pattern); |
195 |
const char *err; |
196 |
|
197 |
free (c->fastmap); |
198 |
free (c->buffer); |
199 |
|
200 |
copy_attr_ctx.re_pattern = x->attr_pattern; |
201 |
c->allocated = 2 * len; |
202 |
c->buffer = xmalloc (c->allocated); |
203 |
c->fastmap = xmalloc (256); |
204 |
c->translate = 0; |
205 |
err = re_compile_pattern (x->attr_pattern, len, c); |
206 |
if (err) |
207 |
{ |
208 |
free (c->fastmap); |
209 |
free (c->buffer); |
210 |
copy_attr_ctx.re_pattern = NULL; |
211 |
error (EXIT_FAILURE, 0, _("%s: invalid regular expression: %s"), |
212 |
x->attr_pattern, err); |
213 |
} |
214 |
} |
215 |
return attr_copy_file (src_path, dst_path, |
216 |
copy_attr_filter, ©_attr_ctx.ctx); |
217 |
#else /* USE_XATTR */ |
218 |
return 0; |
219 |
#endif /* USE_XATTR */ |
220 |
} |
221 |
|
117 |
/* Read the contents of the directory SRC_PATH_IN, and recursively |
222 |
/* Read the contents of the directory SRC_PATH_IN, and recursively |
118 |
copy the contents to DST_PATH_IN. NEW_DST is nonzero if |
223 |
copy the contents to DST_PATH_IN. NEW_DST is nonzero if |
119 |
DST_PATH_IN is a directory that was created previously in the |
224 |
DST_PATH_IN is a directory that was created previously in the |
Lines 1575-1580
Link Here
|
1575 |
} |
1680 |
} |
1576 |
#endif |
1681 |
#endif |
1577 |
|
1682 |
|
|
|
1683 |
if (copy_extended_attributes (src_path, dst_path, x)) |
1684 |
delayed_fail = 1; |
1685 |
|
1578 |
if (x->preserve_mode || x->move_mode) |
1686 |
if (x->preserve_mode || x->move_mode) |
1579 |
{ |
1687 |
{ |
1580 |
if (copy_acl (src_path, dst_path, src_mode) && x->require_preserve) |
1688 |
if (copy_acl (src_path, dst_path, src_mode) && x->require_preserve) |