From b997c90f9e3a64186341c57c8f3f25c2246d0ebb Mon Sep 17 00:00:00 2001 From: Sergey Poznyakoff Date: Sun, 18 Nov 2012 19:20:46 +0200 Subject: [PATCH] Prepare for implementing extended attribute support. This patch adds *xattr() stubs in case extended attribute support is not present and implements the *attrat() family of functions. Based on the patch by Pavel Raiskup for gnulib. * acinclude.m4 (TAR_HEADERS_ATTR_XATTR_H): New defun. * configure.ac: Call TAR_HEADERS_ATTR_XATTR_H * lib/Makefile.am: Add xattr-at.[ch], distribute attr-xattr.in.h [!TAR_COND_XATTR_H]: Build attr/xattr.h * lib/attr-xattr.in.h: New file. * lib/xattr-at.c: New file. * lib/xattr-at.h: New file. --- acinclude.m4 | 26 ++++++++++ configure.ac | 2 + lib/Makefile.am | 17 ++++++- lib/attr-xattr.in.h | 58 ++++++++++++++++++++++ lib/xattr-at.c | 110 ++++++++++++++++++++++++++++++++++++++++++ lib/xattr-at.h | 66 +++++++++++++++++++++++++ tests/capabs_raw01.at | 51 ++++++++++++++++++++ tests/xattr01.at | 47 ++++++++++++++++++ tests/xattr02.at | 55 +++++++++++++++++++++ tests/xattr03.at | 56 +++++++++++++++++++++ tests/xattr04.at | 48 ++++++++++++++++++ 11 files changed, 534 insertions(+), 2 deletions(-) create mode 100644 lib/attr-xattr.in.h create mode 100644 lib/xattr-at.c create mode 100644 lib/xattr-at.h create mode 100644 tests/capabs_raw01.at create mode 100644 tests/xattr01.at create mode 100644 tests/xattr02.at create mode 100644 tests/xattr03.at create mode 100644 tests/xattr04.at diff --git a/acinclude.m4 b/acinclude.m4 index 10a27e5..30381d3 100644 --- a/acinclude.m4 +++ b/acinclude.m4 @@ -24,3 +24,29 @@ AC_DEFUN([TAR_COMPR_PROGRAM],[ [tar_compr_var=m4_if($2,,$1,$2)]) AC_DEFINE_UNQUOTED(tar_compr_define, "$tar_compr_var", [Define to the program name of ]$1[ compressor program])]) + +# Provide , if necessary + +AC_DEFUN([TAR_HEADERS_ATTR_XATTR_H], +[ + AC_ARG_WITH([xattrs], + AS_HELP_STRING([--without-xattrs], [don't use linux extended attributes]), + [], [with_xattrs=maybe] + ) + + AC_CHECK_HEADERS([attr/xattr.h]) + AM_CONDITIONAL([TAR_COND_XATTR_H],[test "$ac_cv_header_attr_xattr_h" = yes]) + if test "$ac_cv_header_attr_xattr_h" = yes; then + AC_CHECK_FUNCS(getxattr fgetxattr lgetxattr \ + setxattr fsetxattr lsetxattr \ + listxattr flistxattr llistxattr, + # only when functions are present + AC_DEFINE([HAVE_ATTR_XATTR_H], [1], + [define to 1 if we have header]) + if test "$with_xattrs" != no; then + AC_DEFINE([HAVE_XATTRS],,[Define when we have working linux xattrs.]) + fi + ) + fi +]) + \ No newline at end of file diff --git a/configure.ac b/configure.ac index f2763bd..77976be 100644 --- a/configure.ac +++ b/configure.ac @@ -90,6 +90,8 @@ gl_INIT # paxutils modules tar_PAXUTILS +TAR_HEADERS_ATTR_XATTR_H + AC_CHECK_FUNCS_ONCE([fchmod fchown fsync lstat mkfifo readlink symlink]) AC_CHECK_DECLS([getgrgid],,, [#include ]) AC_CHECK_DECLS([getpwuid],,, [#include ]) diff --git a/lib/Makefile.am b/lib/Makefile.am index efd6826..d73fac8 100644 --- a/lib/Makefile.am +++ b/lib/Makefile.am @@ -28,11 +28,24 @@ BUILT_SOURCES = rmt-command.h CLEANFILES = rmt-command.h rmt-command.h-t INCLUDES = -I$(top_srcdir)/gnu -I../ -I../gnu -noinst_HEADERS = system.h system-ioctl.h rmt.h paxlib.h stdopen.h +noinst_HEADERS = system.h system-ioctl.h rmt.h paxlib.h stdopen.h xattr-at.h libtar_a_SOURCES = \ paxerror.c paxexit-status.c paxlib.h paxnames.c \ prepargs.c prepargs.h \ rtapelib.c \ rmt.h \ stdopen.c stdopen.h \ - system.h system-ioctl.h + system.h system-ioctl.h \ + xattr-at.c + +if !TAR_COND_XATTR_H +BUILT_SOURCES += attr/xattr.h +attr/xattr.h: attr-xattr.in.h $(top_builddir)/config.status + $(AM_V_at)$(MKDIR_P) attr + $(AM_V_GEN)rm -f $@-t $@ && \ + cp $(srcdir)/attr-xattr.in.h attr/xattr.h + +MOSTLYCLEANFILES = attr/xattr.h attr/xattr.h +endif + +EXTRA_DIST = attr-xattr.in.h diff --git a/lib/attr-xattr.in.h b/lib/attr-xattr.in.h new file mode 100644 index 0000000..b5796fe --- /dev/null +++ b/lib/attr-xattr.in.h @@ -0,0 +1,58 @@ +/* Replacement for platforms that lack it. + Copyright (C) 2012 Free Software Foundation, Inc. + + 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 3 of the License, 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. If not, see . */ + +#ifndef TAR_ATTR_XATTR_H +#define TAR_ATTR_XATTR_H +#include + +/* setting */ +static inline int setxattr (const char *path, const char *name, const void + *value, size_t size, int flags) +{ errno = ENOTSUP; return -1; } + +static inline int lsetxattr (const char *path, const char *name, const void + *value, size_t size, int flags) +{ errno = ENOTSUP; return -1; } + +static inline int fsetxattr (int filedes, const char *name, const void *value, + size_t size, int flags) +{ errno = ENOTSUP; return -1; } + + +/* getting */ +static inline ssize_t getxattr (const char *path, const char *name, void *value, + size_t size) +{ errno = ENOTSUP; return -1; } +static inline ssize_t lgetxattr (const char *path, const char *name, void + *value, size_t size) +{ errno = ENOTSUP; return -1; } +static inline ssize_t fgetxattr (int filedes, const char *name, void *value, + size_t size) +{ errno = ENOTSUP; return -1; } + + +/* listing */ +static inline ssize_t listxattr (const char *path, char *list, size_t size) +{ errno = ENOTSUP; return -1; } + +static inline ssize_t llistxattr (const char *path, char *list, size_t size) +{ errno = ENOTSUP; return -1; } + +static inline ssize_t flistxattr (int filedes, char *list, size_t size) +{ errno = ENOTSUP; return -1; } + +#endif + diff --git a/lib/xattr-at.c b/lib/xattr-at.c new file mode 100644 index 0000000..746578c --- /dev/null +++ b/lib/xattr-at.c @@ -0,0 +1,110 @@ +/* openat-style fd-relative functions for operating with extended file + attributes. + + Copyright (C) 2012 Free Software Foundation, Inc. + + 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 3 of the License, 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. If not, see . */ + +#include + +#include "xattr-at.h" +#include "openat.h" + +#include +#include +#include +#include + +#include "dirname.h" /* solely for definition of IS_ABSOLUTE_FILE_NAME */ +#include "save-cwd.h" + +#include "openat-priv.h" + +/* setxattrat */ +#define AT_FUNC_NAME setxattrat +#define AT_FUNC_F1 setxattr +#define AT_FUNC_POST_FILE_PARAM_DECLS , const char *name, const void *value \ + , size_t size, int flags +#define AT_FUNC_POST_FILE_ARGS , name, value, size, flags +#include "at-func.c" +#undef AT_FUNC_NAME +#undef AT_FUNC_F1 +#undef AT_FUNC_POST_FILE_PARAM_DECLS +#undef AT_FUNC_POST_FILE_ARGS + +/* lsetxattrat */ +#define AT_FUNC_NAME lsetxattrat +#define AT_FUNC_F1 lsetxattr +#define AT_FUNC_POST_FILE_PARAM_DECLS , const char *name, const void *value \ + , size_t size, int flags +#define AT_FUNC_POST_FILE_ARGS , name, value, size, flags +#include "at-func.c" +#undef AT_FUNC_NAME +#undef AT_FUNC_F1 +#undef AT_FUNC_POST_FILE_PARAM_DECLS +#undef AT_FUNC_POST_FILE_ARGS + +/* getxattrat */ +#define AT_FUNC_NAME getxattrat +#define AT_FUNC_RESULT ssize_t +#define AT_FUNC_F1 getxattr +#define AT_FUNC_POST_FILE_PARAM_DECLS , const char *name, void *value \ + , size_t size +#define AT_FUNC_POST_FILE_ARGS , name, value, size +#include "at-func.c" +#undef AT_FUNC_NAME +#undef AT_FUNC_F1 +#undef AT_FUNC_RESULT +#undef AT_FUNC_POST_FILE_PARAM_DECLS +#undef AT_FUNC_POST_FILE_ARGS + +/* lgetxattrat */ +#define AT_FUNC_NAME lgetxattrat +#define AT_FUNC_RESULT ssize_t +#define AT_FUNC_F1 lgetxattr +#define AT_FUNC_POST_FILE_PARAM_DECLS , const char *name, void *value \ + , size_t size +#define AT_FUNC_POST_FILE_ARGS , name, value, size +#include "at-func.c" +#undef AT_FUNC_NAME +#undef AT_FUNC_F1 +#undef AT_FUNC_RESULT +#undef AT_FUNC_POST_FILE_PARAM_DECLS +#undef AT_FUNC_POST_FILE_ARGS + +/* listxattrat */ +#define AT_FUNC_NAME listxattrat +#define AT_FUNC_RESULT ssize_t +#define AT_FUNC_F1 listxattr +#define AT_FUNC_POST_FILE_PARAM_DECLS , char *list , size_t size +#define AT_FUNC_POST_FILE_ARGS , list , size +#include "at-func.c" +#undef AT_FUNC_NAME +#undef AT_FUNC_F1 +#undef AT_FUNC_RESULT +#undef AT_FUNC_POST_FILE_PARAM_DECLS +#undef AT_FUNC_POST_FILE_ARGS + +/* llistxattrat */ +#define AT_FUNC_NAME llistxattrat +#define AT_FUNC_RESULT ssize_t +#define AT_FUNC_F1 llistxattr +#define AT_FUNC_POST_FILE_PARAM_DECLS , char *list , size_t size +#define AT_FUNC_POST_FILE_ARGS , list , size +#include "at-func.c" +#undef AT_FUNC_NAME +#undef AT_FUNC_F1 +#undef AT_FUNC_RESULT +#undef AT_FUNC_POST_FILE_PARAM_DECLS +#undef AT_FUNC_POST_FILE_ARGS diff --git a/lib/xattr-at.h b/lib/xattr-at.h new file mode 100644 index 0000000..360245c --- /dev/null +++ b/lib/xattr-at.h @@ -0,0 +1,66 @@ +/* Prototypes for openat-style fd-relative functions for operating with + extended file attributes. + + Copyright (C) 2012 Free Software Foundation, Inc. + + 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 3 of the License, 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. If not, see . */ + +#ifndef XATTRS_AT_H +#define XATTRS_AT_H + +#include +#include + +/* These are the dir-fd-relative variants of the functions without the + "at" suffix. For example, setxattrat (AT_FDCWD, path, name, value, size, + flags &c) is usually equivalent to setxattr (file, name, value, size, + flags). For more info use the setxattr(2), getxattr(2) or listxattr(2) + manpages. */ + +/* dir-fd-relative setxattr. Operation sets the VALUE of the extended + attribute identified by NAME and associated with the given PATH in the + filesystem relatively to directory identified by DIR_FD. See the + setxattr(2) manpage for the description of all parameters. */ +int setxattrat (int dir_fd, const char *path, const char *name, + const void *value, size_t size, int flags); + +/* dir-fd-relative lsetxattr. This function is just like setxattrat, + except when DIR_FD and FILE specify a symlink: lsetxattrat operates on the + symlink, while the setxattrat operates on the referent of the symlink. */ +int lsetxattrat (int dir_fd, const char *path, const char *name, + const void *value, size_t size, int flags); + +/* dir-fd-relative getxattr. Operation gets the VALUE of the extended + attribute idenfified by NAME and associated with the given PATH in the + filesystem relatively to directory identified by DIR_FD. For more info + about all parameters see the getxattr(2) manpage. */ +ssize_t getxattrat (int dir_fd, const char *path, const char *name, + void *value, size_t size); + +/* dir-fd-relative lgetxattr. This function is just like getxattrat, + except when DIR_FD and FILE specify a symlink: lgetxattrat operates on the + symlink, while the getxattrat operates on the referent of the symlink. */ +ssize_t lgetxattrat (int dir_fd, const char *path, const char *name, + void *value, size_t size); + +/* dir-fd-relative listxattr. Obtain the list of extended attrubtes names. For + more info see the listxattr(2) manpage. */ +ssize_t listxattrat (int dir_fd, const char *path, char *list, size_t size); + +/* dir-fd-relative llistxattr. This function is just like listxattrat, + except when DIR_FD and FILE specify a symlink: llistxattr operates on the + symlink, while the listxattrat operates on the referent of the symlink. */ +ssize_t llistxattrat (int dir_fd, const char *path, char *list, size_t size); + +#endif /* XATTRS_AT_H */ diff --git a/tests/capabs_raw01.at b/tests/capabs_raw01.at new file mode 100644 index 0000000..8eea0cf --- /dev/null +++ b/tests/capabs_raw01.at @@ -0,0 +1,51 @@ +# Process this file with autom4te to create testsuite. -*- Autotest -*- +# +# Test suite for GNU tar. +# Copyright (C) 2012 Free Software Foundation, Inc. +# +# 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 3, 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. If not, see . +# +# Test description: Test if file capabilities are archived/restored correctly +# using just the default xattr support (capabilities are stored/restored in +# binary format -> system dependant). + +AT_SETUP([capabilities: binary store/restore]) +AT_KEYWORDS([xattrs capabilities capabs_raw01]) + +AT_TAR_CHECK([ +AT_PRIVILEGED_PREREQ +AT_XATTRS_PREREQ +AT_CAPABILITIES_UTILS_PREREQ + +mkdir dir +genfile --file dir/file + +setcap "= cap_chown=ei" dir/file + +# archive whole directory including binary xattrs +tar --xattrs -cf archive.tar dir + +# clear the directory +rm -rf dir + +# restore _all_ xattrs (not just the user.* domain) +tar --xattrs --xattrs-include='*' -xf archive.tar + +getcap dir/file +], +[0], +[dir/file = cap_chown+ei +]) + +AT_CLEANUP diff --git a/tests/xattr01.at b/tests/xattr01.at new file mode 100644 index 0000000..fd960d5 --- /dev/null +++ b/tests/xattr01.at @@ -0,0 +1,47 @@ +# Process this file with autom4te to create testsuite. -*- Autotest -*- +# +# Test suite for GNU tar. +# Copyright (C) 2011 Free Software Foundation, Inc. +# +# 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 3, 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. If not, see . +# +# Test description: +# +# This is basic test for support of extended attributes. + +AT_SETUP([xattrs: basic functionality]) +AT_KEYWORDS([xattrs xattr01]) + +AT_TAR_CHECK([ +AT_XATTRS_PREREQ +mkdir dir +genfile --file dir/file + +setfattr -n user.test -v OurDirValue dir +setfattr -n user.test -v OurFileValue dir/file + +tar --xattrs -cf archive.tar dir + +rm -rf dir +tar --xattrs -xf archive.tar + +getfattr -h -d dir | grep -v -e '^#' -e ^$ +getfattr -h -d dir/file | grep -v -e '^#' -e ^$ +], +[0], +[user.test="OurDirValue" +user.test="OurFileValue" +]) + +AT_CLEANUP diff --git a/tests/xattr02.at b/tests/xattr02.at new file mode 100644 index 0000000..3aae3f9 --- /dev/null +++ b/tests/xattr02.at @@ -0,0 +1,55 @@ +# Process this file with autom4te to create testsuite. -*- Autotest -*- +# +# Test suite for GNU tar. +# Copyright (C) 2011 Free Software Foundation, Inc. +# +# 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 3, 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. If not, see . +# +# Test description: +# +# Cooperation of the '-C' option and storing/restoring extended attributes. + +AT_SETUP([xattrs: change directory with -C option]) +AT_KEYWORDS([xattrs xattr02]) + +AT_TAR_CHECK([ +AT_XATTRS_PREREQ + +mkdir dir +mkdir dir/subdir +mkdir dir/subdir/subsubdir +genfile --file dir/file1 +genfile --file dir/subdir/file2 + +setfattr -n user.test -v OurFile1Value dir/file1 +setfattr -n user.test -v OurFile2Value dir/subdir/file2 +setfattr -n user.test -v OurDirValue dir/subdir/subsubdir + +tar --xattrs -cf archive.tar -C dir file1 -C subdir file2 subsubdir + +rm -rf dir + +tar --xattrs -xf archive.tar + +getfattr -h -d file1 | grep -v -e '^#' -e ^$ +getfattr -h -d file2 | grep -v -e '^#' -e ^$ +getfattr -h -d subsubdir | grep -v -e '^#' -e ^$ +], +[0], +[user.test="OurFile1Value" +user.test="OurFile2Value" +user.test="OurDirValue" +]) + +AT_CLEANUP diff --git a/tests/xattr03.at b/tests/xattr03.at new file mode 100644 index 0000000..d834f9f --- /dev/null +++ b/tests/xattr03.at @@ -0,0 +1,56 @@ +# Process this file with autom4te to create testsuite. -*- Autotest -*- +# +# Test suite for GNU tar. +# Copyright (C) 2012 Free Software Foundation, Inc. +# +# 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 3, 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. If not, see . +# +# Test description: +# +# Setup of the trusted.* domain under privileged user. + +AT_SETUP([xattrs: trusted.* attributes]) +AT_KEYWORDS([xattrs xattr03]) + +AT_TAR_CHECK([ +AT_PRIVILEGED_PREREQ +AT_XATTRS_PREREQ + +mkdir dir +mkdir dir/subdir +mkdir dir/subdir/subsubdir +genfile --file dir/file1 +genfile --file dir/subdir/file2 + +setfattr -n trusted.test -v OurFile1Value dir/file1 +setfattr -n trusted.test -v OurFile2Value dir/subdir/file2 +setfattr -n trusted.test -v OurDirValue dir/subdir/subsubdir + +tar --xattrs -cf archive.tar -C dir file1 -C subdir file2 subsubdir + +rm -rf dir + +tar --xattrs --xattrs-include=trusted* -xf archive.tar + +getfattr -mtrusted. -d file1 | grep -v -e '^#' -e ^$ +getfattr -mtrusted. -d file2 | grep -v -e '^#' -e ^$ +getfattr -mtrusted. -d subsubdir | grep -v -e '^#' -e ^$ +], +[0], +[trusted.test="OurFile1Value" +trusted.test="OurFile2Value" +trusted.test="OurDirValue" +]) + +AT_CLEANUP diff --git a/tests/xattr04.at b/tests/xattr04.at new file mode 100644 index 0000000..31832af --- /dev/null +++ b/tests/xattr04.at @@ -0,0 +1,48 @@ +# Process this file with autom4te to create testsuite. -*- Autotest -*- +# +# Test suite for GNU tar. +# Copyright (C) 2012 Free Software Foundation, Inc. +# +# 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 3, 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. If not, see . +# +# Test description: Test for the regression caused by tar update from 1.23 to +# 1.26, Red Hat xattr patch was not ready for open->openat conversion. +# +# Related commit 4bde4f3. See the bug: https://bugzilla.redhat.com/717684 + +AT_SETUP([xattrs: s/open/openat/ regression]) +AT_KEYWORDS([xattrs xattr04]) + +AT_TAR_CHECK([ +AT_XATTRS_PREREQ + +mkdir dir +mkdir output +genfile --file dir/file + +setfattr -n user.test -v value dir/file + +# archive whole directory including binary xattrs +tar --xattrs -cf archive.tar -C dir . + +tar --xattrs -xf archive.tar -C output +ret=$? +getfattr -h -d output/file | grep -v -e '^#' -e ^$ +exit $ret +], +[0], +[user.test="value" +]) + +AT_CLEANUP -- 2.44.0