summaryrefslogtreecommitdiff
path: root/usr/src/lib/libcmdutils
diff options
context:
space:
mode:
Diffstat (limited to 'usr/src/lib/libcmdutils')
-rw-r--r--usr/src/lib/libcmdutils/Makefile.com8
-rw-r--r--usr/src/lib/libcmdutils/common/mapfile-vers8
-rw-r--r--usr/src/lib/libcmdutils/common/process_xattrs.c334
-rw-r--r--usr/src/lib/libcmdutils/common/sysattrs.c128
-rw-r--r--usr/src/lib/libcmdutils/common/writefile.c230
-rw-r--r--usr/src/lib/libcmdutils/libcmdutils.h57
6 files changed, 755 insertions, 10 deletions
diff --git a/usr/src/lib/libcmdutils/Makefile.com b/usr/src/lib/libcmdutils/Makefile.com
index 50ca57cedf..e12e5b07c5 100644
--- a/usr/src/lib/libcmdutils/Makefile.com
+++ b/usr/src/lib/libcmdutils/Makefile.com
@@ -19,7 +19,7 @@
# CDDL HEADER END
#
#
-# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
# ident "%Z%%M% %I% %E% SMI"
@@ -27,14 +27,14 @@
LIBRARY= libcmdutils.a
VERS= .1
-OBJECTS= avltree.o
+OBJECTS= avltree.o sysattrs.o writefile.o process_xattrs.o
include ../../Makefile.lib
include ../../Makefile.rootfs
LIBS = $(DYNLIB) $(LINTLIB)
-LDLIBS += -lc -lavl
+LDLIBS += -lc -lavl -lnvpair
SRCDIR = ../common
$(LINTLIB) := SRCS = $(SRCDIR)/$(LINTSRC)
@@ -43,7 +43,7 @@ CFLAGS += $(CCVERBOSE)
# All commands using the common avltree interfaces must
# be largefile aware.
-CPPFLAGS += -I.. -D_REENTRANT -D_FILE_OFFSET_BITS=64
+CPPFLAGS += -I.. -I../../common/inc -D_REENTRANT -D_FILE_OFFSET_BITS=64
.KEEP_STATE:
diff --git a/usr/src/lib/libcmdutils/common/mapfile-vers b/usr/src/lib/libcmdutils/common/mapfile-vers
index 48d26ca9af..295493845b 100644
--- a/usr/src/lib/libcmdutils/common/mapfile-vers
+++ b/usr/src/lib/libcmdutils/common/mapfile-vers
@@ -19,7 +19,7 @@
# CDDL HEADER END
#
#
-# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
# ident "%Z%%M% %I% %E% SMI"
@@ -30,6 +30,12 @@ SUNWprivate_1.1 {
add_tnode;
destroy_tree;
tnode_compare;
+ sysattr_type;
+ sysattr_support;
+ writefile;
+ get_attrdirs;
+ mv_xattrs;
+ sysattr_list;
local:
*;
};
diff --git a/usr/src/lib/libcmdutils/common/process_xattrs.c b/usr/src/lib/libcmdutils/common/process_xattrs.c
new file mode 100644
index 0000000000..5c8df946a1
--- /dev/null
+++ b/usr/src/lib/libcmdutils/common/process_xattrs.c
@@ -0,0 +1,334 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <c_synonyms.h>
+#include "libcmdutils.h"
+
+
+/*
+ * Gets file descriptors of attribute directories for source and target
+ * attribute files
+ */
+int
+get_attrdirs(int indfd, int outdfd, char *attrfile, int *sfd, int *tfd)
+{
+ int pwdfd;
+ int fd1;
+ int fd2;
+
+ pwdfd = open(".", O_RDONLY);
+ if ((pwdfd != -1) && (fchdir(indfd) == 0)) {
+ if ((fd1 = attropen(attrfile, ".", O_RDONLY)) == -1) {
+ (void) fchdir(pwdfd);
+ (void) close(pwdfd);
+ return (1);
+ }
+ *sfd = fd1;
+ } else {
+ (void) fchdir(pwdfd);
+ (void) close(pwdfd);
+ return (1);
+ }
+ if (fchdir(outdfd) == 0) {
+ if ((fd2 = attropen(attrfile, ".", O_RDONLY)) == -1) {
+ (void) fchdir(pwdfd);
+ (void) close(pwdfd);
+ return (1);
+ }
+ *tfd = fd2;
+ } else {
+ (void) fchdir(pwdfd);
+ (void) close(pwdfd);
+ return (1);
+ }
+ (void) fchdir(pwdfd);
+ return (0);
+}
+
+/*
+ * mv_xattrs - Copies the content of the extended attribute files. Then
+ * moves the extended system attributes from the input attribute files
+ * to the target attribute files. Moves the extended system attributes
+ * from source to the target file. This function returns 0 on success
+ * and nonzero on error.
+ */
+int
+mv_xattrs(char *cmd, char *infile, char *outfile, int sattr, int silent)
+{
+ int srcfd = -1;
+ int indfd = -1;
+ int outdfd = -1;
+ int tmpfd = -1;
+ int sattrfd = -1;
+ int tattrfd = -1;
+ int asfd = -1;
+ int atfd = -1;
+ DIR *dirp = NULL;
+ struct dirent *dp = NULL;
+ char *etext = NULL;
+ struct stat st1;
+ struct stat st2;
+ nvlist_t *response = NULL;
+ nvlist_t *res = NULL;
+
+ if ((srcfd = open(infile, O_RDONLY)) == -1) {
+ etext = dgettext(TEXT_DOMAIN, "cannot open source");
+ goto error;
+ }
+ if (sattr)
+ response = sysattr_list(cmd, srcfd, infile);
+
+ if ((indfd = openat(srcfd, ".", O_RDONLY|O_XATTR)) == -1) {
+ etext = dgettext(TEXT_DOMAIN, "cannot openat source");
+ goto error;
+ }
+ if ((outdfd = attropen(outfile, ".", O_RDONLY)) == -1) {
+ etext = dgettext(TEXT_DOMAIN, "cannot attropen target");
+ goto error;
+ }
+ if ((tmpfd = dup(indfd)) == -1) {
+ etext = dgettext(TEXT_DOMAIN, "cannot dup descriptor");
+ goto error;
+
+ }
+ if ((dirp = fdopendir(tmpfd)) == NULL) {
+ etext = dgettext(TEXT_DOMAIN, "cannot access source");
+ goto error;
+ }
+ while ((dp = readdir(dirp)) != NULL) {
+ if ((dp->d_name[0] == '.' && dp->d_name[1] == '\0') ||
+ (dp->d_name[0] == '.' && dp->d_name[1] == '.' &&
+ dp->d_name[2] == '\0') ||
+ (sysattr_type(dp->d_name) == _RO_SATTR) ||
+ (sysattr_type(dp->d_name) == _RW_SATTR))
+ continue;
+
+ if ((sattrfd = openat(indfd, dp->d_name,
+ O_RDONLY)) == -1) {
+ etext = dgettext(TEXT_DOMAIN,
+ "cannot open src attribute file");
+ goto error;
+ }
+ if (fstat(sattrfd, &st1) < 0) {
+ etext = dgettext(TEXT_DOMAIN,
+ "could not stat attribute file");
+ goto error;
+ }
+ if ((tattrfd = openat(outdfd, dp->d_name,
+ O_RDWR|O_CREAT|O_TRUNC, st1.st_mode)) == -1) {
+ etext = dgettext(TEXT_DOMAIN,
+ "cannot open target attribute file");
+ goto error;
+ }
+ if (fstat(tattrfd, &st2) < 0) {
+ etext = dgettext(TEXT_DOMAIN,
+ "could not stat attribute file");
+ goto error;
+ }
+ if (writefile(sattrfd, tattrfd, infile, outfile, dp->d_name,
+ dp->d_name, &st1, &st2) != 0) {
+ etext = dgettext(TEXT_DOMAIN,
+ "failed to copy extended attribute "
+ "from source to target");
+ goto error;
+ }
+
+ errno = 0;
+ if (sattr) {
+ /*
+ * Gets non default extended system attributes from
+ * source to copy to target.
+ */
+ if (dp->d_name != NULL)
+ res = sysattr_list(cmd, sattrfd, dp->d_name);
+
+ if (res != NULL &&
+ get_attrdirs(indfd, outdfd, dp->d_name, &asfd,
+ &atfd) != 0) {
+ etext = dgettext(TEXT_DOMAIN,
+ "Failed to open attribute files");
+ goto error;
+ }
+ /*
+ * Copy extended system attribute from source
+ * attribute file to target attribute file
+ */
+ if (res != NULL &&
+ (renameat(asfd, VIEW_READWRITE, atfd,
+ VIEW_READWRITE) != 0)) {
+ if (errno == EPERM)
+ etext = dgettext(TEXT_DOMAIN,
+ "Permission denied -"
+ "failed to move system attribute");
+ else
+ etext = dgettext(TEXT_DOMAIN,
+ "failed to move extended "
+ "system attribute");
+ goto error;
+ }
+ }
+ if (sattrfd != -1)
+ (void) close(sattrfd);
+ if (tattrfd != -1)
+ (void) close(tattrfd);
+ if (asfd != -1)
+ (void) close(asfd);
+ if (atfd != -1)
+ (void) close(atfd);
+ if (res != NULL) {
+ nvlist_free(res);
+ res = NULL;
+ }
+ }
+ errno = 0;
+ /* Copy extended system attribute from source to target */
+
+ if (response != NULL) {
+ if (renameat(indfd, VIEW_READWRITE, outdfd,
+ VIEW_READWRITE) == 0)
+ goto done;
+
+ if (errno == EPERM)
+ etext = dgettext(TEXT_DOMAIN, "Permission denied");
+ else
+ etext = dgettext(TEXT_DOMAIN,
+ "failed to move system attribute");
+ }
+error:
+ if (res != NULL)
+ nvlist_free(res);
+ if (silent == 0 && etext != NULL) {
+ if (!sattr)
+ (void) fprintf(stderr, dgettext(TEXT_DOMAIN,
+ "%s: %s: cannot move extended attributes, "),
+ cmd, infile);
+ else
+ (void) fprintf(stderr, dgettext(TEXT_DOMAIN,
+ "%s: %s: cannot move extended system "
+ "attributes, "), cmd, infile);
+ perror(etext);
+ }
+done:
+ if (dirp)
+ (void) closedir(dirp);
+ if (sattrfd != -1)
+ (void) close(sattrfd);
+ if (tattrfd != -1)
+ (void) close(tattrfd);
+ if (asfd != -1)
+ (void) close(asfd);
+ if (atfd != -1)
+ (void) close(atfd);
+ if (indfd != -1)
+ (void) close(indfd);
+ if (outdfd != -1)
+ (void) close(outdfd);
+ if (response != NULL)
+ nvlist_free(response);
+ if (etext != NULL)
+ return (1);
+ else
+ return (0);
+}
+
+/*
+ * The function returns non default extended system attribute list
+ * associated with 'fname' and returns NULL when an error has occured
+ * or when only extended system attributes other than archive,
+ * av_modified or crtime are set.
+ *
+ * The function returns system attribute list for the following cases:
+ *
+ * - any extended system attribute other than the default attributes
+ * ('archive', 'av_modified' and 'crtime') is set
+ * - nvlist has NULL name string
+ * - nvpair has data type of 'nvlist'
+ * - default data type.
+ */
+
+nvlist_t *
+sysattr_list(char *cmd, int fd, char *fname)
+{
+ boolean_t value;
+ data_type_t type;
+ nvlist_t *response;
+ nvpair_t *pair;
+ f_attr_t fattr;
+ char *name;
+
+ if (nvlist_alloc(&response, NV_UNIQUE_NAME, 0) != 0) {
+ (void) fprintf(stderr, dgettext(TEXT_DOMAIN,
+ "%s: %s: nvlist_alloc failed\n"),
+ cmd, fname);
+ return (NULL);
+ }
+ if (fgetattr(fd, XATTR_VIEW_READWRITE, &response) != 0) {
+ (void) fprintf(stderr, dgettext(TEXT_DOMAIN,
+ "%s: %s: fgetattr failed\n"),
+ cmd, fname);
+ nvlist_free(response);
+ return (NULL);
+ }
+ pair = NULL;
+ while ((pair = nvlist_next_nvpair(response, pair)) != NULL) {
+
+ name = nvpair_name(pair);
+
+ if (name != NULL)
+ fattr = name_to_attr(name);
+ else
+ return (response);
+
+ type = nvpair_type(pair);
+ switch (type) {
+ case DATA_TYPE_BOOLEAN_VALUE:
+ if (nvpair_value_boolean_value(pair,
+ &value) != 0) {
+ (void) fprintf(stderr,
+ dgettext(TEXT_DOMAIN, "%s "
+ "nvpair_value_boolean_value "
+ "failed\n"), cmd);
+ continue;
+ }
+ if (value && fattr != F_ARCHIVE &&
+ fattr != F_AV_MODIFIED)
+ return (response);
+ break;
+ case DATA_TYPE_UINT64_ARRAY:
+ if (fattr != F_CRTIME)
+ return (response);
+ break;
+ case DATA_TYPE_NVLIST:
+ default:
+ return (response);
+ break;
+ }
+ }
+ if (response != NULL)
+ nvlist_free(response);
+ return (NULL);
+}
diff --git a/usr/src/lib/libcmdutils/common/sysattrs.c b/usr/src/lib/libcmdutils/common/sysattrs.c
new file mode 100644
index 0000000000..a22e8e5e21
--- /dev/null
+++ b/usr/src/lib/libcmdutils/common/sysattrs.c
@@ -0,0 +1,128 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <c_synonyms.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <libgen.h>
+#include <attr.h>
+#include <fcntl.h>
+#include <errno.h>
+#include "libcmdutils.h"
+
+/*
+ * Returns the status of attempting to obtain the extended system
+ * attributes in the specified view.
+ *
+ * Note: If obtaining status for an extended attribute file, the caller must
+ * chdir into the hidden directory prior to calling sysattr_status().
+ *
+ * Returns 1 if the extended system attributes were obtained, otherwise
+ * returns 0.
+ */
+int
+sysattr_status(char *file, xattr_view_t view)
+{
+ nvlist_t *response;
+ int saveerrno;
+ int status;
+
+ if (nvlist_alloc(&response, NV_UNIQUE_NAME, 0) != 0) {
+ return (0);
+ }
+
+ status = getattrat(AT_FDCWD, view, file, &response);
+
+ saveerrno = errno;
+ (void) nvlist_free(response);
+ errno = saveerrno;
+
+ return (status == 0);
+}
+
+/*
+ * Returns the type of the specified in file. If the file name matches
+ * the name of either a read-only or read-write extended system attribute
+ * file then sysattr_type() returns the type of file:
+ * return value file type
+ * ------------ ---------
+ * _RO_SATTR read-only extended system attribute file
+ * _RW_SATTR read-write extended system attribute file
+ * _NOT_SATTR neither a read-only or read-write extended system
+ * attribute file.
+ */
+int
+sysattr_type(char *file)
+{
+ if (file == NULL) {
+ errno = ENOENT;
+ return (_NOT_SATTR);
+ }
+
+ if (strcmp(basename(file), file) != 0) {
+ errno = EINVAL;
+ return (_NOT_SATTR);
+ }
+
+ errno = 0;
+ if (strcmp(file, VIEW_READONLY) == 0) {
+ return (_RO_SATTR);
+ } else if (strcmp(file, VIEW_READWRITE) == 0) {
+ return (_RW_SATTR);
+ } else {
+ return (_NOT_SATTR);
+ }
+}
+
+/*
+ * Call sysattr_support() instead of pathconf(file, _PC_SATTR_ENABLED) or
+ * pathconf(file, _PC_SATTR_EXISTS) so that if pathconf() fails over NFS, we
+ * can still try to figure out if extended system attributes are supported by
+ * testing for a valid extended system attribute file.
+ *
+ * 'name' can have the values _PC_SATTR_ENABLED or _PC_SATTR_EXISTS.
+ *
+ * Returns 1 if the underlying file system supports extended system attributes,
+ * otherwise, returns -1.
+ */
+int
+sysattr_support(char *file, int name)
+{
+ int rc;
+
+ errno = 0;
+ if ((name != _PC_SATTR_ENABLED) &&
+ (name != _PC_SATTR_EXISTS)) {
+ errno = EINVAL;
+ return (-1);
+ }
+ if (((rc = pathconf(file, name)) == 1) || (errno != EINVAL)) {
+ return (rc);
+ }
+ return (sysattr_status(file, XATTR_VIEW_READONLY));
+}
diff --git a/usr/src/lib/libcmdutils/common/writefile.c b/usr/src/lib/libcmdutils/common/writefile.c
new file mode 100644
index 0000000000..3e36f90c61
--- /dev/null
+++ b/usr/src/lib/libcmdutils/common/writefile.c
@@ -0,0 +1,230 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
+/* All Rights Reserved */
+
+/*
+ * University Copyright- Copyright (c) 1982, 1986, 1988
+ * The Regents of the University of California
+ * All Rights Reserved
+ *
+ * University Acknowledgment- Portions of this document are derived from
+ * software developed by the University of California, Berkeley, and its
+ * contributors.
+ */
+/*
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <c_synonyms.h>
+#include "libcmdutils.h"
+
+
+int
+writefile(int fi, int fo, char *infile, char *outfile, char *asfile,
+ char *atfile, struct stat *s1p, struct stat *s2p)
+{
+ int mapsize, munmapsize;
+ caddr_t cp;
+ off_t filesize = s1p->st_size;
+ off_t offset;
+ int nbytes;
+ int remains;
+ int n;
+ size_t src_size;
+ size_t targ_size;
+ char *srcbuf;
+ char *targbuf;
+
+ if (asfile != NULL) {
+ src_size = strlen(infile) + strlen(asfile) +
+ strlen(dgettext(TEXT_DOMAIN, " attribute ")) + 1;
+ } else {
+ src_size = strlen(infile) + 1;
+ }
+ srcbuf = malloc(src_size);
+ if (srcbuf == NULL) {
+ (void) fprintf(stderr,
+ dgettext(TEXT_DOMAIN, "could not allocate memory"
+ " for path buffer: "));
+ return (1);
+ }
+ if (asfile != NULL) {
+ (void) snprintf(srcbuf, src_size, "%s%s%s",
+ infile, dgettext(TEXT_DOMAIN, " attribute "), asfile);
+ } else {
+ (void) snprintf(srcbuf, src_size, "%s", infile);
+ }
+
+ if (atfile != NULL) {
+ targ_size = strlen(outfile) + strlen(atfile) +
+ strlen(dgettext(TEXT_DOMAIN, " attribute ")) + 1;
+ } else {
+ targ_size = strlen(outfile) + 1;
+ }
+ targbuf = malloc(targ_size);
+ if (targbuf == NULL) {
+ (void) fprintf(stderr,
+ dgettext(TEXT_DOMAIN, "could not allocate memory"
+ " for path buffer: "));
+ return (1);
+ }
+ if (atfile != NULL) {
+ (void) snprintf(targbuf, targ_size, "%s%s%s",
+ outfile, dgettext(TEXT_DOMAIN, " attribute "), atfile);
+ } else {
+ (void) snprintf(targbuf, targ_size, "%s", outfile);
+ }
+
+ if (ISREG(*s1p) && s1p->st_size > SMALLFILESIZE) {
+ /*
+ * Determine size of initial mapping. This will determine the
+ * size of the address space chunk we work with. This initial
+ * mapping size will be used to perform munmap() in the future.
+ */
+ mapsize = MAXMAPSIZE;
+ if (s1p->st_size < mapsize) mapsize = s1p->st_size;
+ munmapsize = mapsize;
+
+ /*
+ * Mmap time!
+ */
+ if ((cp = mmap((caddr_t)NULL, mapsize, PROT_READ,
+ MAP_SHARED, fi, (off_t)0)) == MAP_FAILED)
+ mapsize = 0; /* can't mmap today */
+ } else
+ mapsize = 0;
+
+ if (mapsize != 0) {
+ offset = 0;
+
+ for (;;) {
+ nbytes = write(fo, cp, mapsize);
+ /*
+ * if we write less than the mmaped size it's due to a
+ * media error on the input file or out of space on
+ * the output file. So, try again, and look for errno.
+ */
+ if ((nbytes >= 0) && (nbytes != (int)mapsize)) {
+ remains = mapsize - nbytes;
+ while (remains > 0) {
+ nbytes = write(fo,
+ cp + mapsize - remains, remains);
+ if (nbytes < 0) {
+ if (errno == ENOSPC)
+ perror(targbuf);
+ else
+ perror(srcbuf);
+ (void) close(fi);
+ (void) close(fo);
+ (void) munmap(cp, munmapsize);
+ if (ISREG(*s2p))
+ (void) unlink(targbuf);
+ return (1);
+ }
+ remains -= nbytes;
+ if (remains == 0)
+ nbytes = mapsize;
+ }
+ }
+ /*
+ * although the write manual page doesn't specify this
+ * as a possible errno, it is set when the nfs read
+ * via the mmap'ed file is accessed, so report the
+ * problem as a source access problem, not a target file
+ * problem
+ */
+ if (nbytes < 0) {
+ if (errno == EACCES)
+ perror(srcbuf);
+ else
+ perror(targbuf);
+ (void) close(fi);
+ (void) close(fo);
+ (void) munmap(cp, munmapsize);
+ if (ISREG(*s2p))
+ (void) unlink(targbuf);
+ if (srcbuf != NULL)
+ free(srcbuf);
+ if (targbuf != NULL)
+ free(targbuf);
+ return (1);
+ }
+ filesize -= nbytes;
+ if (filesize == 0)
+ break;
+ offset += nbytes;
+ if (filesize < mapsize)
+ mapsize = filesize;
+ if (mmap(cp, mapsize, PROT_READ, MAP_SHARED |
+ MAP_FIXED, fi, offset) == MAP_FAILED) {
+ perror(srcbuf);
+ (void) close(fi);
+ (void) close(fo);
+ (void) munmap(cp, munmapsize);
+ if (ISREG(*s2p))
+ (void) unlink(targbuf);
+ if (srcbuf != NULL)
+ free(srcbuf);
+ if (targbuf != NULL)
+ free(targbuf);
+ return (1);
+ }
+ }
+ (void) munmap(cp, munmapsize);
+ } else {
+ char buf[SMALLFILESIZE];
+ for (;;) {
+ n = read(fi, buf, sizeof (buf));
+ if (n == 0) {
+ return (0);
+ } else if (n < 0) {
+ (void) close(fi);
+ (void) close(fo);
+ if (ISREG(*s2p))
+ (void) unlink(targbuf);
+ if (srcbuf != NULL)
+ free(srcbuf);
+ if (targbuf != NULL)
+ free(targbuf);
+ return (1);
+ } else if (write(fo, buf, n) != n) {
+ (void) close(fi);
+ (void) close(fo);
+ if (ISREG(*s2p))
+ (void) unlink(targbuf);
+ if (srcbuf != NULL)
+ free(srcbuf);
+ if (targbuf != NULL)
+ free(targbuf);
+ return (1);
+ }
+ }
+ }
+ if (srcbuf != NULL)
+ free(srcbuf);
+ if (targbuf != NULL)
+ free(targbuf);
+ return (0);
+}
diff --git a/usr/src/lib/libcmdutils/libcmdutils.h b/usr/src/lib/libcmdutils/libcmdutils.h
index 28a9e996d4..d1c3a0b193 100644
--- a/usr/src/lib/libcmdutils/libcmdutils.h
+++ b/usr/src/lib/libcmdutils/libcmdutils.h
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2003 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -38,14 +37,35 @@
* this file.
*/
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <limits.h>
+#include <libintl.h>
+#include <string.h>
+#include <dirent.h>
+#include <attr.h>
#include <sys/avl.h>
#include <sys/types.h>
-#include <stdlib.h>
+#include <sys/stat.h>
+#include <sys/mman.h>
+#include <libnvpair.h>
#ifdef __cplusplus
extern "C" {
#endif
+/* extended system attribute support */
+#define _NOT_SATTR 0
+#define _RO_SATTR 1
+#define _RW_SATTR 2
+
+#define MAXMAPSIZE (1024*1024*8) /* map at most 8MB */
+#define SMALLFILESIZE (32*1024) /* don't use mmap on little file */
+#define ISREG(A) (((A).st_mode & S_IFMT) == S_IFREG)
+
/* avltree */
#define OFFSETOF(s, m) ((size_t)(&(((s *)0)->m)))
@@ -56,11 +76,38 @@ typedef struct tree_node {
avl_node_t avl_link;
} tree_node_t;
+
+ /* extended system attribute support */
+
+/* Determine if a file is the name of an extended system attribute file */
+extern int sysattr_type(char *);
+
+/* Determine if the underlying file system supports system attributes */
+extern int sysattr_support(char *, int);
+
+/* Copies the content of the source file to the target file */
+extern int writefile(int, int, char *, char *, char *, char *,
+struct stat *, struct stat *);
+
+/* Gets file descriptors of the source and target attribute files */
+extern int get_attrdirs(int, int, char *, int *, int *);
+
+/* Move extended attribute and extended system attribute */
+extern int mv_xattrs(char *, char *, char *, int, int);
+
+/* Returns non default extended system attribute list */
+extern nvlist_t *sysattr_list(char *, int, char *);
+
+
+
+ /* avltree */
+
/*
* Used to compare two nodes. We are attempting to match the 1st
* argument (node) against the 2nd argument (a node which
* is already in the search tree).
*/
+
extern int tnode_compare(const void *, const void *);
/*