diff options
author | Nathan Scott <nathans@sgi.com> | 2003-02-25 09:06:10 +0000 |
---|---|---|
committer | Nathan Scott <nathans@sgi.com> | 2003-02-25 09:06:10 +0000 |
commit | 7b33ebd60e68795347c2c844d81d90e38fd9091e (patch) | |
tree | b8ad0b3165562c3d939d64720c109fd8d2a41116 /libattr | |
parent | 6562399105b5ff0ec4f5ebea154dc7a96b597653 (diff) | |
download | attr-7b33ebd60e68795347c2c844d81d90e38fd9091e.tar.gz |
New attr userspace package - transition to the trusted namespace for XFS,
Add in the new attribute copying routines from Andreas, and also update
the license info in the syscall man pages so that other folks can use em
too.
Diffstat (limited to 'libattr')
-rw-r--r-- | libattr/Makefile | 7 | ||||
-rw-r--r-- | libattr/attr_copy_fd.c | 168 | ||||
-rw-r--r-- | libattr/attr_copy_file.c | 166 | ||||
-rw-r--r-- | libattr/libattr.c | 23 | ||||
-rw-r--r-- | libattr/libattr.h | 11 |
5 files changed, 365 insertions, 10 deletions
diff --git a/libattr/Makefile b/libattr/Makefile index 854db51..f9f9e14 100644 --- a/libattr/Makefile +++ b/libattr/Makefile @@ -36,10 +36,13 @@ include $(TOPDIR)/include/builddefs LTLIBRARY = libattr.la LT_CURRENT = 1 -LT_REVISION = 1 +LT_REVISION = 2 LT_AGE = 0 -CFILES = libattr.c syscalls.c +CFILES = libattr.c syscalls.c attr_copy_fd.c attr_copy_file.c +HFILES = libattr.h + +LCFLAGS = -include libattr.h default: $(LTLIBRARY) diff --git a/libattr/attr_copy_fd.c b/libattr/attr_copy_fd.c new file mode 100644 index 0000000..78e6383 --- /dev/null +++ b/libattr/attr_copy_fd.c @@ -0,0 +1,168 @@ +/* Copy extended attributes between files. */ + +/* Copyright (C) 2002 Andreas Gruenbacher <agruen@suse.de>, SuSE Linux AG. + + This program is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by the + Free Software Foundation; either version 2, or (at your option) any + later version. + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; see the file COPYING. If not, write to the Free + Software Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA. */ + +#if defined (HAVE_CONFIG_H) +#include "config.h" +#endif + +#include <sys/types.h> +#include <stdlib.h> +#include <string.h> +#include <errno.h> + +#if defined(HAVE_ALLOCA_H) +# include <alloca.h> +#endif + +#if defined(HAVE_ATTR_XATTR_H) +# include <attr/xattr.h> +#endif + +#define ERROR_CONTEXT_MACROS +#include "error_context.h" + +#if !defined(ENOTSUP) +# define ENOTSUP (-1) +#endif + +#if defined(HAVE_ALLOCA) +# define my_alloc(size) alloca (size) +# define my_free(ptr) do { } while(0) +#else +# define my_alloc(size) malloc (size) +# define my_free(ptr) free (ptr) +#endif + +static int +check_no_acl(const char *name, struct error_context *ctx) +{ + return strcmp(name, "system.posix_acl_access") && + strcmp(name, "system.posix_acl_default"); +} + +/* Copy extended attributes from src_path to dst_path. If the file + has an extended Access ACL (system.posix_acl_access) and that is + copied successfully, the file mode permission bits are copied as + a side effect. This may not always the case, so the file mode + and/or ownership must be copied separately. */ +int +attr_copy_fd(const char *src_path, int src_fd, + const char *dst_path, int dst_fd, + int (*check) (const char *, struct error_context *), + struct error_context *ctx) +{ +#if defined(HAVE_FLISTXATTR) && defined(HAVE_FGETXATTR) && \ + defined(HAVE_FSETXATTR) + int ret = 0; + ssize_t size; + char *names = NULL, *end_names, *name, *value = NULL; + + /* ignore acls by default */ + if (check == NULL) + check = check_no_acl; + + size = flistxattr (src_fd, NULL, 0); + if (size < 0) { + if (errno != ENOSYS && errno != ENOTSUP) { + const char *qpath = quote (ctx, src_path); + error (ctx, _("listing attributes of %s"), qpath); + quote_free (ctx, qpath); + ret = -1; + } + goto getout; + } + names = (char *) my_alloc (size+1); + if (names == NULL) { + error (ctx, ""); + ret = -1; + goto getout; + } + size = flistxattr (src_fd, names, size); + if (size < 0) { + const char *qpath = quote (ctx, src_path); + error (ctx, _("listing attributes of %s"), qpath); + quote_free (ctx, qpath); + my_free (names); + ret = -1; + goto getout; + } else { + names[size] = '\0'; + end_names = names + size; + } + + for (name = names; name != end_names; name = strchr(name, '\0') + 1) { + void *old_value; + + /* check if this attribute shall be preserved */ + if (!*name || !check(name, ctx)) + continue; + + size = fgetxattr (src_fd, name, NULL, 0); + if (size < 0) { + const char *qpath = quote (ctx, src_path); + const char *qname = quote (ctx, name); + error (ctx, _("getting attribute %s of %s"), + qpath, qname); + quote_free (ctx, qname); + quote_free (ctx, qpath); + ret = -1; + continue; /* may not have permission to access */ + } + value = (char *) realloc (old_value = value, size); + if (size != 0 && value == NULL) { + free(old_value); + error (ctx, ""); + ret = -1; + } + size = fgetxattr (src_fd, name, value, size); + if (size < 0) { + const char *qpath = quote (ctx, src_path); + const char *qname = quote (ctx, name); + error (ctx, _("getting attribute %s of %s"), + qname, qpath); + quote_free (ctx, qname); + quote_free (ctx, qpath); + ret = -1; + } + if (fsetxattr (dst_fd, name, value, size, 0) != 0) + { + const char *qpath = quote (ctx, dst_path); + if (errno == ENOSYS) { + error (ctx, _("setting attributes for %s"), + qpath); + ret = -1; + break; /* no hope of getting any further */ + } else { + const char *qname = quote (ctx, name); + error (ctx, _("setting attribute %s for %s"), + qname, qpath); + quote_free (ctx, qname); + ret = -1; + } + quote_free (ctx, qpath); + } + } +getout: + free (value); + my_free (names); + return ret; +#else + return 0; +#endif +} + diff --git a/libattr/attr_copy_file.c b/libattr/attr_copy_file.c new file mode 100644 index 0000000..98296ed --- /dev/null +++ b/libattr/attr_copy_file.c @@ -0,0 +1,166 @@ +/* Copy extended attributes between files. */ + +/* Copyright (C) 2002 Andreas Gruenbacher <agruen@suse.de>, SuSE Linux AG. + + This program is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by the + Free Software Foundation; either version 2, or (at your option) any + later version. + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; see the file COPYING. If not, write to the Free + Software Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA. */ + +#if defined (HAVE_CONFIG_H) +#include "config.h" +#endif + +#include <sys/types.h> +#include <stdlib.h> +#include <string.h> +#include <errno.h> + +#if defined(HAVE_ALLOCA_H) +# include <alloca.h> +#endif + +#if defined(HAVE_ATTR_XATTR_H) +# include <attr/xattr.h> +#endif + +#define ERROR_CONTEXT_MACROS +#include "error_context.h" + +#if !defined(ENOTSUP) +# define ENOTSUP (-1) +#endif + +#if defined(HAVE_ALLOCA) +# define my_alloc(size) alloca (size) +# define my_free(ptr) do { } while(0) +#else +# define my_alloc(size) malloc (size) +# define my_free(ptr) free (ptr) +#endif + +static int +check_no_acl(const char *name, struct error_context *ctx) +{ + return strcmp(name, "system.posix_acl_access") && + strcmp(name, "system.posix_acl_default"); +} + +/* Copy extended attributes from src_path to dst_path. If the file + has an extended Access ACL (system.posix_acl_access) and that is + copied successfully, the file mode permission bits are copied as + a side effect. This may not always the case, so the file mode + and/or ownership must be copied separately. */ +int +attr_copy_file(const char *src_path, const char *dst_path, + int (*check) (const char *, struct error_context *), + struct error_context *ctx) +{ +#if defined(HAVE_LISTXATTR) && defined(HAVE_GETXATTR) && defined(HAVE_SETXATTR) + int ret = 0; + ssize_t size; + char *names = NULL, *end_names, *name, *value = NULL; + + /* ignore acls by default */ + if (check == NULL) + check = check_no_acl; + + size = listxattr (src_path, NULL, 0); + if (size < 0) { + if (errno != ENOSYS && errno != ENOTSUP) { + const char *qpath = quote (ctx, src_path); + error (ctx, _("listing attributes of %s"), qpath); + quote_free (ctx, qpath); + ret = -1; + } + goto getout; + } + names = (char *) my_alloc (size+1); + if (names == NULL) { + error (ctx, ""); + ret = -1; + goto getout; + } + size = listxattr (src_path, names, size); + if (size < 0) { + const char *qpath = quote (ctx, src_path); + error (ctx, _("listing attributes of %s"), qpath); + quote_free (ctx, qpath); + my_free (names); + ret = -1; + goto getout; + } else { + names[size] = '\0'; + end_names = names + size; + } + + for (name = names; name != end_names; name = strchr(name, '\0') + 1) { + void *old_value; + + /* check if this attribute shall be preserved */ + if (!*name || !check(name, ctx)) + continue; + + size = getxattr (src_path, name, NULL, 0); + if (size < 0) { + const char *qpath = quote (ctx, src_path); + const char *qname = quote (ctx, name); + error (ctx, _("getting attribute %s of %s"), + qname, qpath); + quote_free (ctx, qname); + quote_free (ctx, qpath); + ret = -1; + continue; /* may not have permission to access */ + } + value = (char *) realloc (old_value = value, size); + if (size != 0 && value == NULL) { + free(old_value); + error (ctx, ""); + ret = -1; + } + size = getxattr (src_path, name, value, size); + if (size < 0) { + const char *qpath = quote (ctx, src_path); + const char *qname = quote (ctx, name); + error (ctx, _("getting attribute %s of %s"), + qname, qpath); + quote_free (ctx, qname); + quote_free (ctx, qpath); + ret = -1; + } + if (setxattr (dst_path, name, value, size, 0) != 0) + { + const char *qpath = quote (ctx, dst_path); + if (errno == ENOSYS) { + error (ctx, _("setting attributes for %s"), + qpath); + ret = -1; + break; /* no hope of getting any further */ + } else { + const char *qname = quote (ctx, name); + error (ctx, _("setting attribute %s for %s"), + qname, qpath); + quote_free (ctx, qname); + ret = -1; + } + quote_free (ctx, qpath); + } + } +getout: + free (value); + my_free (names); + return ret; +#else + return 0; +#endif +} + diff --git a/libattr/libattr.c b/libattr/libattr.c index 110f07c..1c37abc 100644 --- a/libattr/libattr.c +++ b/libattr/libattr.c @@ -44,25 +44,32 @@ #undef MAXNAMELEN #define MAXNAMELEN 256 -static const char *user_name = "user."; -static const char *root_name = "xfsroot."; - /* * Convert IRIX API components into Linux/XFS API components */ static int api_convert(char *name, const char *irixname, int irixflags) { - int len = strlen(irixname); + static const char *user_name = "user."; + static const char *trusted_name = "trusted."; + static const char *xfsroot_name = "xfsroot."; + static int compat = -1; + + if (compat == -1) + compat = (getenv("COMPAT_XFSROOT") != NULL); - if (len >= MAXNAMELEN) { + if (strlen(irixname) >= MAXNAMELEN) { errno = EINVAL; return -1; } - if (irixflags & ATTR_ROOT) - strcpy(name, root_name); - else + if (irixflags & ATTR_ROOT) { + if (compat) + strcpy(name, xfsroot_name); + else + strcpy(name, trusted_name); + } else { strcpy(name, user_name); + } strcat(name, irixname); return 0; } diff --git a/libattr/libattr.h b/libattr/libattr.h new file mode 100644 index 0000000..316c1db --- /dev/null +++ b/libattr/libattr.h @@ -0,0 +1,11 @@ +/* Features we provide ourself. */ + +#define HAVE_ATTR_XATTR_H 1 +#define HAVE_CONFIG_H 1 + +#define HAVE_FGETXATTR 1 +#define HAVE_FLISTXATTR 1 +#define HAVE_FSETXATTR 1 +#define HAVE_GETXATTR 1 +#define HAVE_LISTXATTR 1 +#define HAVE_SETXATTR 1 |