4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
23 * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
25 * Copyright 2012 Milan Jurik. All rights reserved.
28 #include "libcmdutils.h"
32 * Gets file descriptors of attribute directories for source and target
36 get_attrdirs(int indfd
, int outdfd
, char *attrfile
, int *sfd
, int *tfd
)
42 pwdfd
= open(".", O_RDONLY
);
43 if ((pwdfd
!= -1) && (fchdir(indfd
) == 0)) {
44 if ((fd1
= attropen(attrfile
, ".", O_RDONLY
)) == -1) {
55 if (fchdir(outdfd
) == 0) {
56 if ((fd2
= attropen(attrfile
, ".", O_RDONLY
)) == -1) {
72 * mv_xattrs - Copies the content of the extended attribute files. Then
73 * moves the extended system attributes from the input attribute files
74 * to the target attribute files. Moves the extended system attributes
75 * from source to the target file. This function returns 0 on success
76 * and nonzero on error.
79 mv_xattrs(char *cmd
, char *infile
, char *outfile
, int sattr
, int silent
)
90 struct dirent
*dp
= NULL
;
94 nvlist_t
*response
= NULL
;
97 if ((srcfd
= open(infile
, O_RDONLY
)) == -1) {
98 etext
= dgettext(TEXT_DOMAIN
, "cannot open source");
102 response
= sysattr_list(cmd
, srcfd
, infile
);
104 if ((indfd
= openat(srcfd
, ".", O_RDONLY
|O_XATTR
)) == -1) {
105 etext
= dgettext(TEXT_DOMAIN
, "cannot openat source");
108 if ((outdfd
= attropen(outfile
, ".", O_RDONLY
)) == -1) {
109 etext
= dgettext(TEXT_DOMAIN
, "cannot attropen target");
112 if ((tmpfd
= dup(indfd
)) == -1) {
113 etext
= dgettext(TEXT_DOMAIN
, "cannot dup descriptor");
117 if ((dirp
= fdopendir(tmpfd
)) == NULL
) {
118 etext
= dgettext(TEXT_DOMAIN
, "cannot access source");
121 while ((dp
= readdir(dirp
)) != NULL
) {
122 if ((dp
->d_name
[0] == '.' && dp
->d_name
[1] == '\0') ||
123 (dp
->d_name
[0] == '.' && dp
->d_name
[1] == '.' &&
124 dp
->d_name
[2] == '\0') ||
125 (sysattr_type(dp
->d_name
) == _RO_SATTR
) ||
126 (sysattr_type(dp
->d_name
) == _RW_SATTR
))
129 if ((sattrfd
= openat(indfd
, dp
->d_name
,
131 etext
= dgettext(TEXT_DOMAIN
,
132 "cannot open src attribute file");
135 if (fstat(sattrfd
, &st1
) < 0) {
136 etext
= dgettext(TEXT_DOMAIN
,
137 "could not stat attribute file");
140 if ((tattrfd
= openat(outdfd
, dp
->d_name
,
141 O_RDWR
|O_CREAT
|O_TRUNC
, st1
.st_mode
)) == -1) {
142 etext
= dgettext(TEXT_DOMAIN
,
143 "cannot open target attribute file");
146 if (fstat(tattrfd
, &st2
) < 0) {
147 etext
= dgettext(TEXT_DOMAIN
,
148 "could not stat attribute file");
151 if (writefile(sattrfd
, tattrfd
, infile
, outfile
, dp
->d_name
,
152 dp
->d_name
, &st1
, &st2
) != 0) {
153 etext
= dgettext(TEXT_DOMAIN
,
154 "failed to copy extended attribute "
155 "from source to target");
162 * Gets non default extended system attributes from
163 * source to copy to target.
165 if (dp
->d_name
!= NULL
)
166 res
= sysattr_list(cmd
, sattrfd
, dp
->d_name
);
169 get_attrdirs(indfd
, outdfd
, dp
->d_name
, &asfd
,
171 etext
= dgettext(TEXT_DOMAIN
,
172 "Failed to open attribute files");
176 * Copy extended system attribute from source
177 * attribute file to target attribute file
180 (renameat(asfd
, VIEW_READWRITE
, atfd
,
181 VIEW_READWRITE
) != 0)) {
183 etext
= dgettext(TEXT_DOMAIN
,
184 "Permission denied -"
185 "failed to move system attribute");
187 etext
= dgettext(TEXT_DOMAIN
,
188 "failed to move extended "
194 (void) close(sattrfd
);
196 (void) close(tattrfd
);
207 /* Copy extended system attribute from source to target */
209 if (response
!= NULL
) {
210 if (renameat(indfd
, VIEW_READWRITE
, outdfd
,
211 VIEW_READWRITE
) == 0)
215 etext
= dgettext(TEXT_DOMAIN
, "Permission denied");
217 etext
= dgettext(TEXT_DOMAIN
,
218 "failed to move system attribute");
222 if (silent
== 0 && etext
!= NULL
) {
224 (void) fprintf(stderr
, dgettext(TEXT_DOMAIN
,
225 "%s: %s: cannot move extended attributes, "),
228 (void) fprintf(stderr
, dgettext(TEXT_DOMAIN
,
229 "%s: %s: cannot move extended system "
230 "attributes, "), cmd
, infile
);
235 (void) closedir(dirp
);
237 (void) close(sattrfd
);
239 (void) close(tattrfd
);
247 (void) close(outdfd
);
248 nvlist_free(response
);
256 * The function returns non default extended system attribute list
257 * associated with 'fname' and returns NULL when an error has occured
258 * or when only extended system attributes other than archive,
259 * av_modified or crtime are set.
261 * The function returns system attribute list for the following cases:
263 * - any extended system attribute other than the default attributes
264 * ('archive', 'av_modified' and 'crtime') is set
265 * - nvlist has NULL name string
266 * - nvpair has data type of 'nvlist'
267 * - default data type.
271 sysattr_list(char *cmd
, int fd
, char *fname
)
280 if (fgetattr(fd
, XATTR_VIEW_READWRITE
, &response
) != 0) {
281 (void) fprintf(stderr
, dgettext(TEXT_DOMAIN
,
282 "%s: %s: fgetattr failed\n"),
287 while ((pair
= nvlist_next_nvpair(response
, pair
)) != NULL
) {
289 name
= nvpair_name(pair
);
292 fattr
= name_to_attr(name
);
296 type
= nvpair_type(pair
);
298 case DATA_TYPE_BOOLEAN_VALUE
:
299 if (nvpair_value_boolean_value(pair
,
301 (void) fprintf(stderr
,
302 dgettext(TEXT_DOMAIN
, "%s "
303 "nvpair_value_boolean_value "
307 if (value
&& fattr
!= F_ARCHIVE
&&
308 fattr
!= F_AV_MODIFIED
)
311 case DATA_TYPE_UINT64_ARRAY
:
312 if (fattr
!= F_CRTIME
)
315 case DATA_TYPE_NVLIST
:
320 nvlist_free(response
);