Print this page
patch tsoome-feedback
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/lib/libcmdutils/common/process_xattrs.c
+++ new/usr/src/lib/libcmdutils/common/process_xattrs.c
1 1 /*
2 2 * CDDL HEADER START
3 3 *
4 4 * The contents of this file are subject to the terms of the
5 5 * Common Development and Distribution License (the "License").
6 6 * You may not use this file except in compliance with the License.
7 7 *
8 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 9 * or http://www.opensolaris.org/os/licensing.
10 10 * See the License for the specific language governing permissions
11 11 * and limitations under the License.
12 12 *
13 13 * When distributing Covered Code, include this CDDL HEADER in each
14 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 15 * If applicable, add the following below this CDDL HEADER, with the
16 16 * fields enclosed by brackets "[]" replaced with your own identifying
17 17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 18 *
19 19 * CDDL HEADER END
20 20 */
21 21
22 22 /*
23 23 * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
24 24 * Use is subject to license terms.
25 25 * Copyright 2012 Milan Jurik. All rights reserved.
26 26 */
27 27
28 28 #include "libcmdutils.h"
29 29
30 30
31 31 /*
32 32 * Gets file descriptors of attribute directories for source and target
33 33 * attribute files
34 34 */
35 35 int
36 36 get_attrdirs(int indfd, int outdfd, char *attrfile, int *sfd, int *tfd)
37 37 {
38 38 int pwdfd;
39 39 int fd1;
40 40 int fd2;
41 41
42 42 pwdfd = open(".", O_RDONLY);
43 43 if ((pwdfd != -1) && (fchdir(indfd) == 0)) {
44 44 if ((fd1 = attropen(attrfile, ".", O_RDONLY)) == -1) {
45 45 (void) fchdir(pwdfd);
46 46 (void) close(pwdfd);
47 47 return (1);
48 48 }
49 49 *sfd = fd1;
50 50 } else {
51 51 (void) fchdir(pwdfd);
52 52 (void) close(pwdfd);
53 53 return (1);
54 54 }
55 55 if (fchdir(outdfd) == 0) {
56 56 if ((fd2 = attropen(attrfile, ".", O_RDONLY)) == -1) {
57 57 (void) fchdir(pwdfd);
58 58 (void) close(pwdfd);
59 59 return (1);
60 60 }
61 61 *tfd = fd2;
62 62 } else {
63 63 (void) fchdir(pwdfd);
64 64 (void) close(pwdfd);
65 65 return (1);
66 66 }
67 67 (void) fchdir(pwdfd);
68 68 return (0);
69 69 }
70 70
71 71 /*
72 72 * mv_xattrs - Copies the content of the extended attribute files. Then
73 73 * moves the extended system attributes from the input attribute files
74 74 * to the target attribute files. Moves the extended system attributes
75 75 * from source to the target file. This function returns 0 on success
76 76 * and nonzero on error.
77 77 */
78 78 int
79 79 mv_xattrs(char *cmd, char *infile, char *outfile, int sattr, int silent)
80 80 {
81 81 int srcfd = -1;
82 82 int indfd = -1;
83 83 int outdfd = -1;
84 84 int tmpfd = -1;
85 85 int sattrfd = -1;
86 86 int tattrfd = -1;
87 87 int asfd = -1;
88 88 int atfd = -1;
89 89 DIR *dirp = NULL;
90 90 struct dirent *dp = NULL;
91 91 char *etext = NULL;
92 92 struct stat st1;
93 93 struct stat st2;
94 94 nvlist_t *response = NULL;
95 95 nvlist_t *res = NULL;
96 96
97 97 if ((srcfd = open(infile, O_RDONLY)) == -1) {
98 98 etext = dgettext(TEXT_DOMAIN, "cannot open source");
99 99 goto error;
100 100 }
101 101 if (sattr)
102 102 response = sysattr_list(cmd, srcfd, infile);
103 103
104 104 if ((indfd = openat(srcfd, ".", O_RDONLY|O_XATTR)) == -1) {
105 105 etext = dgettext(TEXT_DOMAIN, "cannot openat source");
106 106 goto error;
107 107 }
108 108 if ((outdfd = attropen(outfile, ".", O_RDONLY)) == -1) {
109 109 etext = dgettext(TEXT_DOMAIN, "cannot attropen target");
110 110 goto error;
111 111 }
112 112 if ((tmpfd = dup(indfd)) == -1) {
113 113 etext = dgettext(TEXT_DOMAIN, "cannot dup descriptor");
114 114 goto error;
115 115
116 116 }
117 117 if ((dirp = fdopendir(tmpfd)) == NULL) {
118 118 etext = dgettext(TEXT_DOMAIN, "cannot access source");
119 119 goto error;
120 120 }
121 121 while ((dp = readdir(dirp)) != NULL) {
122 122 if ((dp->d_name[0] == '.' && dp->d_name[1] == '\0') ||
123 123 (dp->d_name[0] == '.' && dp->d_name[1] == '.' &&
124 124 dp->d_name[2] == '\0') ||
125 125 (sysattr_type(dp->d_name) == _RO_SATTR) ||
126 126 (sysattr_type(dp->d_name) == _RW_SATTR))
127 127 continue;
128 128
129 129 if ((sattrfd = openat(indfd, dp->d_name,
130 130 O_RDONLY)) == -1) {
131 131 etext = dgettext(TEXT_DOMAIN,
132 132 "cannot open src attribute file");
133 133 goto error;
134 134 }
135 135 if (fstat(sattrfd, &st1) < 0) {
136 136 etext = dgettext(TEXT_DOMAIN,
137 137 "could not stat attribute file");
138 138 goto error;
139 139 }
140 140 if ((tattrfd = openat(outdfd, dp->d_name,
141 141 O_RDWR|O_CREAT|O_TRUNC, st1.st_mode)) == -1) {
142 142 etext = dgettext(TEXT_DOMAIN,
143 143 "cannot open target attribute file");
144 144 goto error;
145 145 }
146 146 if (fstat(tattrfd, &st2) < 0) {
147 147 etext = dgettext(TEXT_DOMAIN,
148 148 "could not stat attribute file");
149 149 goto error;
150 150 }
151 151 if (writefile(sattrfd, tattrfd, infile, outfile, dp->d_name,
152 152 dp->d_name, &st1, &st2) != 0) {
153 153 etext = dgettext(TEXT_DOMAIN,
154 154 "failed to copy extended attribute "
155 155 "from source to target");
156 156 goto error;
157 157 }
158 158
159 159 errno = 0;
160 160 if (sattr) {
161 161 /*
162 162 * Gets non default extended system attributes from
163 163 * source to copy to target.
164 164 */
165 165 if (dp->d_name != NULL)
166 166 res = sysattr_list(cmd, sattrfd, dp->d_name);
167 167
168 168 if (res != NULL &&
169 169 get_attrdirs(indfd, outdfd, dp->d_name, &asfd,
170 170 &atfd) != 0) {
171 171 etext = dgettext(TEXT_DOMAIN,
172 172 "Failed to open attribute files");
173 173 goto error;
174 174 }
175 175 /*
176 176 * Copy extended system attribute from source
177 177 * attribute file to target attribute file
178 178 */
179 179 if (res != NULL &&
180 180 (renameat(asfd, VIEW_READWRITE, atfd,
181 181 VIEW_READWRITE) != 0)) {
182 182 if (errno == EPERM)
183 183 etext = dgettext(TEXT_DOMAIN,
184 184 "Permission denied -"
185 185 "failed to move system attribute");
186 186 else
187 187 etext = dgettext(TEXT_DOMAIN,
188 188 "failed to move extended "
189 189 "system attribute");
190 190 goto error;
191 191 }
192 192 }
193 193 if (sattrfd != -1)
194 194 (void) close(sattrfd);
195 195 if (tattrfd != -1)
196 196 (void) close(tattrfd);
197 197 if (asfd != -1)
198 198 (void) close(asfd);
199 199 if (atfd != -1)
200 200 (void) close(atfd);
201 201 if (res != NULL) {
202 202 nvlist_free(res);
203 203 res = NULL;
204 204 }
205 205 }
206 206 errno = 0;
207 207 /* Copy extended system attribute from source to target */
208 208
209 209 if (response != NULL) {
210 210 if (renameat(indfd, VIEW_READWRITE, outdfd,
↓ open down ↓ |
210 lines elided |
↑ open up ↑ |
211 211 VIEW_READWRITE) == 0)
212 212 goto done;
213 213
214 214 if (errno == EPERM)
215 215 etext = dgettext(TEXT_DOMAIN, "Permission denied");
216 216 else
217 217 etext = dgettext(TEXT_DOMAIN,
218 218 "failed to move system attribute");
219 219 }
220 220 error:
221 - if (res != NULL)
222 - nvlist_free(res);
221 + nvlist_free(res);
223 222 if (silent == 0 && etext != NULL) {
224 223 if (!sattr)
225 224 (void) fprintf(stderr, dgettext(TEXT_DOMAIN,
226 225 "%s: %s: cannot move extended attributes, "),
227 226 cmd, infile);
228 227 else
229 228 (void) fprintf(stderr, dgettext(TEXT_DOMAIN,
230 229 "%s: %s: cannot move extended system "
231 230 "attributes, "), cmd, infile);
232 231 perror(etext);
233 232 }
234 233 done:
235 234 if (dirp)
236 235 (void) closedir(dirp);
237 236 if (sattrfd != -1)
238 237 (void) close(sattrfd);
↓ open down ↓ |
6 lines elided |
↑ open up ↑ |
239 238 if (tattrfd != -1)
240 239 (void) close(tattrfd);
241 240 if (asfd != -1)
242 241 (void) close(asfd);
243 242 if (atfd != -1)
244 243 (void) close(atfd);
245 244 if (indfd != -1)
246 245 (void) close(indfd);
247 246 if (outdfd != -1)
248 247 (void) close(outdfd);
249 - if (response != NULL)
250 - nvlist_free(response);
248 + nvlist_free(response);
251 249 if (etext != NULL)
252 250 return (1);
253 251 else
254 252 return (0);
255 253 }
256 254
257 255 /*
258 256 * The function returns non default extended system attribute list
259 257 * associated with 'fname' and returns NULL when an error has occured
260 258 * or when only extended system attributes other than archive,
261 259 * av_modified or crtime are set.
262 260 *
263 261 * The function returns system attribute list for the following cases:
264 262 *
265 263 * - any extended system attribute other than the default attributes
266 264 * ('archive', 'av_modified' and 'crtime') is set
267 265 * - nvlist has NULL name string
268 266 * - nvpair has data type of 'nvlist'
269 267 * - default data type.
270 268 */
271 269
272 270 nvlist_t *
273 271 sysattr_list(char *cmd, int fd, char *fname)
274 272 {
275 273 boolean_t value;
276 274 data_type_t type;
277 275 nvlist_t *response;
278 276 nvpair_t *pair;
279 277 f_attr_t fattr;
280 278 char *name;
281 279
282 280 if (fgetattr(fd, XATTR_VIEW_READWRITE, &response) != 0) {
283 281 (void) fprintf(stderr, dgettext(TEXT_DOMAIN,
284 282 "%s: %s: fgetattr failed\n"),
285 283 cmd, fname);
286 284 return (NULL);
287 285 }
288 286 pair = NULL;
289 287 while ((pair = nvlist_next_nvpair(response, pair)) != NULL) {
290 288
291 289 name = nvpair_name(pair);
292 290
293 291 if (name != NULL)
294 292 fattr = name_to_attr(name);
295 293 else
296 294 return (response);
297 295
298 296 type = nvpair_type(pair);
299 297 switch (type) {
300 298 case DATA_TYPE_BOOLEAN_VALUE:
301 299 if (nvpair_value_boolean_value(pair,
302 300 &value) != 0) {
303 301 (void) fprintf(stderr,
304 302 dgettext(TEXT_DOMAIN, "%s "
305 303 "nvpair_value_boolean_value "
306 304 "failed\n"), cmd);
307 305 continue;
308 306 }
309 307 if (value && fattr != F_ARCHIVE &&
310 308 fattr != F_AV_MODIFIED)
311 309 return (response);
↓ open down ↓ |
51 lines elided |
↑ open up ↑ |
312 310 break;
313 311 case DATA_TYPE_UINT64_ARRAY:
314 312 if (fattr != F_CRTIME)
315 313 return (response);
316 314 break;
317 315 case DATA_TYPE_NVLIST:
318 316 default:
319 317 return (response);
320 318 }
321 319 }
322 - if (response != NULL)
323 - nvlist_free(response);
320 + nvlist_free(response);
324 321 return (NULL);
325 322 }
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX