summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore39
-rw-r--r--Makefile115
-rwxr-xr-xMakepkgs103
-rw-r--r--README13
-rw-r--r--VERSION7
-rw-r--r--build/Makefile63
-rw-r--r--build/rpm/Makefile76
-rw-r--r--build/rpm/acl.spec.in79
-rw-r--r--build/rpm/macros.template31
-rw-r--r--build/rpm/rpm-2.rc.template25
-rw-r--r--build/tar/Makefile36
-rw-r--r--chacl/Makefile35
-rw-r--r--chacl/chacl.c354
-rw-r--r--configure.in49
-rw-r--r--debian/Makefile51
-rw-r--r--debian/changelog335
-rw-r--r--debian/compat1
-rw-r--r--debian/control39
-rw-r--r--debian/copyright19
-rwxr-xr-xdebian/rules74
-rw-r--r--debian/watch2
-rw-r--r--doc/CHANGES495
-rw-r--r--doc/COPYING347
-rw-r--r--doc/COPYING.LGPL513
-rw-r--r--doc/INSTALL48
-rw-r--r--doc/Makefile42
-rw-r--r--doc/PORTING86
-rw-r--r--doc/TODO4
-rw-r--r--doc/extensions.txt77
-rw-r--r--doc/libacl.txt73
-rw-r--r--doc/old-acl.5263
-rw-r--r--examples/Makefile27
-rw-r--r--examples/Makefile.examples9
-rw-r--r--examples/README12
-rw-r--r--examples/copy-acl.c70
-rw-r--r--examples/copyperm.c61
-rw-r--r--examples/get-acl.c96
-rw-r--r--examples/set-acl.c64
-rw-r--r--exports85
-rw-r--r--getfacl/Makefile36
-rw-r--r--getfacl/getfacl.c733
-rw-r--r--getfacl/user_group.c59
-rw-r--r--getfacl/user_group.h31
-rw-r--r--include/Makefile40
-rw-r--r--include/acl.h130
-rw-r--r--include/acl_ea.h52
-rw-r--r--include/builddefs.in97
-rw-r--r--include/buildmacros162
-rw-r--r--include/buildrules104
-rw-r--r--include/config.h.in56
-rwxr-xr-xinclude/install-sh363
-rw-r--r--include/libacl.h79
-rw-r--r--libacl/Makefile67
-rw-r--r--libacl/__acl_from_xattr.c93
-rw-r--r--libacl/__acl_from_xattr.h1
-rw-r--r--libacl/__acl_reorder_obj_p.c134
-rw-r--r--libacl/__acl_to_any_text.c345
-rw-r--r--libacl/__acl_to_xattr.c63
-rw-r--r--libacl/__acl_to_xattr.h1
-rw-r--r--libacl/__apply_mask_to_mode.c68
-rw-r--r--libacl/__libobj.c93
-rw-r--r--libacl/acl_add_perm.c35
-rw-r--r--libacl/acl_calc_mask.c67
-rw-r--r--libacl/acl_check.c128
-rw-r--r--libacl/acl_clear_perms.c35
-rw-r--r--libacl/acl_cmp.c53
-rw-r--r--libacl/acl_copy_entry.c40
-rw-r--r--libacl/acl_copy_ext.c52
-rw-r--r--libacl/acl_copy_int.c65
-rw-r--r--libacl/acl_create_entry.c73
-rw-r--r--libacl/acl_delete_def_file.c40
-rw-r--r--libacl/acl_delete_entry.c44
-rw-r--r--libacl/acl_delete_perm.c35
-rw-r--r--libacl/acl_dup.c54
-rw-r--r--libacl/acl_entries.c33
-rw-r--r--libacl/acl_equiv_mode.c72
-rw-r--r--libacl/acl_error.c45
-rw-r--r--libacl/acl_extended_fd.c48
-rw-r--r--libacl/acl_extended_file.c48
-rw-r--r--libacl/acl_free.c76
-rw-r--r--libacl/acl_from_mode.c73
-rw-r--r--libacl/acl_from_text.c308
-rw-r--r--libacl/acl_get_entry.c59
-rw-r--r--libacl/acl_get_fd.c68
-rw-r--r--libacl/acl_get_file.c89
-rw-r--r--libacl/acl_get_perm.c33
-rw-r--r--libacl/acl_get_permset.c42
-rw-r--r--libacl/acl_get_qualifier.c48
-rw-r--r--libacl/acl_get_tag_type.c39
-rw-r--r--libacl/acl_init.c69
-rw-r--r--libacl/acl_set_fd.c50
-rw-r--r--libacl/acl_set_file.c77
-rw-r--r--libacl/acl_set_permset.c36
-rw-r--r--libacl/acl_set_qualifier.c48
-rw-r--r--libacl/acl_set_tag_type.c47
-rw-r--r--libacl/acl_size.c35
-rw-r--r--libacl/acl_to_any_text.c34
-rw-r--r--libacl/acl_to_text.c33
-rw-r--r--libacl/acl_valid.c41
-rw-r--r--libacl/byteorder.h37
-rw-r--r--libacl/libacl.h140
-rw-r--r--libacl/libobj.h108
-rw-r--r--libacl/perm_copy.h37
-rw-r--r--libacl/perm_copy_fd.c204
-rw-r--r--libacl/perm_copy_file.c241
-rw-r--r--m4/Makefile34
-rw-r--r--m4/manual_format.m431
-rw-r--r--m4/multilib.m443
-rw-r--r--m4/package_attrdev.m493
-rw-r--r--m4/package_globals.m461
-rw-r--r--m4/package_utilies.m4140
-rw-r--r--m4/visibility_hidden.m436
-rw-r--r--man/Makefile41
-rw-r--r--man/man1/Makefile35
-rw-r--r--man/man1/chacl.1155
-rw-r--r--man/man1/getfacl.1162
-rw-r--r--man/man1/setfacl.1295
-rw-r--r--man/man3/Makefile35
-rw-r--r--man/man3/acl_add_perm.385
-rw-r--r--man/man3/acl_calc_mask.3101
-rw-r--r--man/man3/acl_check.3122
-rw-r--r--man/man3/acl_clear_perms.375
-rw-r--r--man/man3/acl_cmp.390
-rw-r--r--man/man3/acl_copy_entry.382
-rw-r--r--man/man3/acl_copy_ext.3108
-rw-r--r--man/man3/acl_copy_int.389
-rw-r--r--man/man3/acl_create_entry.3104
-rw-r--r--man/man3/acl_delete_def_file.386
-rw-r--r--man/man3/acl_delete_entry.386
-rw-r--r--man/man3/acl_delete_perm.385
-rw-r--r--man/man3/acl_dup.387
-rw-r--r--man/man3/acl_entries.373
-rw-r--r--man/man3/acl_equiv_mode.396
-rw-r--r--man/man3/acl_error.371
-rw-r--r--man/man3/acl_extended_fd.3105
-rw-r--r--man/man3/acl_extended_file.3115
-rw-r--r--man/man3/acl_free.382
-rw-r--r--man/man3/acl_from_mode.374
-rw-r--r--man/man3/acl_from_text.393
-rw-r--r--man/man3/acl_get_entry.3142
-rw-r--r--man/man3/acl_get_fd.396
-rw-r--r--man/man3/acl_get_file.3136
-rw-r--r--man/man3/acl_get_perm.397
-rw-r--r--man/man3/acl_get_permset.382
-rw-r--r--man/man3/acl_get_qualifier.3125
-rw-r--r--man/man3/acl_get_tag_type.381
-rw-r--r--man/man3/acl_init.387
-rw-r--r--man/man3/acl_set_fd.391
-rw-r--r--man/man3/acl_set_file.3168
-rw-r--r--man/man3/acl_set_permset.398
-rw-r--r--man/man3/acl_set_qualifier.3113
-rw-r--r--man/man3/acl_set_tag_type.383
-rw-r--r--man/man3/acl_size.385
-rw-r--r--man/man3/acl_to_any_text.3169
-rw-r--r--man/man3/acl_to_text.3111
-rw-r--r--man/man3/acl_valid.386
-rw-r--r--man/man5/Makefile35
-rw-r--r--man/man5/acl.5504
-rw-r--r--po/Makefile42
-rw-r--r--po/de.po334
-rw-r--r--po/es.po355
-rw-r--r--po/fr.po348
-rw-r--r--po/gl.po355
-rw-r--r--po/pl.po347
-rw-r--r--po/sv.po345
-rw-r--r--setfacl/Makefile36
-rw-r--r--setfacl/do_set.c524
-rw-r--r--setfacl/parse.c566
-rw-r--r--setfacl/parse.h84
-rw-r--r--setfacl/sequence.c162
-rw-r--r--setfacl/sequence.h115
-rw-r--r--setfacl/setfacl.c640
-rw-r--r--test/Makefile49
-rw-r--r--test/cp.test46
-rw-r--r--test/getfacl-noacl.test55
-rw-r--r--test/getfacl-recursive.test194
-rw-r--r--test/make-tree45
-rw-r--r--test/misc.test426
-rw-r--r--test/nfs/nfs-dir.test50
-rw-r--r--test/nfs/nfsacl.test42
-rw-r--r--test/root/permissions.test279
-rw-r--r--test/root/setfacl.test144
-rwxr-xr-xtest/run327
-rw-r--r--test/setfacl-X.test119
-rwxr-xr-xtest/sort-getfacl-output4
-rw-r--r--test/utf8-filenames.test14
186 files changed, 21270 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..6113c60
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,39 @@
+*.la
+*.lo
+*.mo
+*.o
+*[-.]manifest
+.libs/
+/.census
+/Logs/
+/acl-*
+/aclocal.m4
+/autom4te.cache/
+/build/rpm/*.rpm
+/build/rpm/acl.spec
+/build/rpm/rpm-*.rc
+/build/rpm/rpmfiles*
+/build/rpm/rpmmacros
+/chacl/chacl
+/config.guess
+/config.log
+/config.status
+/config.sub
+/configure
+/doc/CHANGES.gz
+/getfacl/getfacl
+/include/acl
+/include/builddefs
+/include/config.h
+/include/sys
+/libtool
+/ltmain.sh
+/po/acl.pot
+/setfacl/setfacl
+acl-*.tar.gz
+install-sh
+m4/libtool.m4
+m4/ltoptions.m4
+m4/ltsugar.m4
+m4/ltversion.m4
+m4/lt~obsolete.m4
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..6969443
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,115 @@
+#
+# Copyright (c) 2000-2006 Silicon Graphics, Inc. All Rights Reserved.
+#
+# 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 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, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+
+TOPDIR = .
+HAVE_BUILDDEFS = $(shell test -f $(TOPDIR)/include/builddefs && echo yes || echo no)
+
+ifeq ($(HAVE_BUILDDEFS), yes)
+include $(TOPDIR)/include/builddefs
+endif
+
+CONFIGURE = \
+ aclocal.m4 \
+ configure config.guess config.sub \
+ ltmain.sh m4/libtool.m4 m4/ltoptions.m4 m4/ltsugar.m4 \
+ m4/ltversion.m4 m4/lt~obsolete.m4
+LSRCFILES = \
+ configure.in Makepkgs install-sh exports README VERSION \
+ $(CONFIGURE)
+
+LDIRT = config.log .dep config.status config.cache confdefs.h conftest* \
+ Logs/* built .census install.* install-dev.* install-lib.* *.gz
+
+LIB_SUBDIRS = include libmisc libacl
+TOOL_SUBDIRS = getfacl setfacl chacl m4 man doc po test examples build debian
+
+SUBDIRS = $(LIB_SUBDIRS) $(TOOL_SUBDIRS)
+
+default: include/builddefs include/config.h
+ifeq ($(HAVE_BUILDDEFS), no)
+ $(MAKE) -C . $@
+else
+ $(MAKE) $(SUBDIRS)
+endif
+
+# tool/lib dependencies
+libacl: libmisc
+getfacl setfacl chacl: libacl
+
+ifeq ($(HAVE_BUILDDEFS), yes)
+include $(BUILDRULES)
+else
+clean: # if configure hasn't run, nothing to clean
+endif
+
+# Recent versions of libtool require the -i option for copying auxiliary
+# files (config.sub, config.guess, install-sh, ltmain.sh), while older
+# versions will copy those files anyway, and don't understand -i.
+LIBTOOLIZE_INSTALL = `libtoolize -n -i >/dev/null 2>/dev/null && echo -i`
+
+configure include/builddefs:
+ libtoolize -c $(LIBTOOLIZE_INSTALL) -f
+ cp include/install-sh .
+ aclocal -I m4
+ autoconf
+ ./configure \
+ --prefix=/ \
+ --exec-prefix=/ \
+ --sbindir=/bin \
+ --bindir=/usr/bin \
+ --libdir=/lib \
+ --libexecdir=/usr/lib \
+ --enable-lib64=yes \
+ --includedir=/usr/include \
+ --mandir=/usr/share/man \
+ --datadir=/usr/share \
+ $$LOCAL_CONFIGURE_OPTIONS
+ touch .census
+
+include/config.h: include/builddefs
+## Recover from the removal of $@
+ @if test -f $@; then :; else \
+ rm -f include/builddefs; \
+ $(MAKE) $(AM_MAKEFLAGS) include/builddefs; \
+ fi
+
+install: default $(addsuffix -install,$(SUBDIRS))
+ $(INSTALL) -m 755 -d $(PKG_DOC_DIR)
+ $(INSTALL) -m 644 README $(PKG_DOC_DIR)
+
+install-dev: default $(addsuffix -install-dev,$(SUBDIRS))
+
+install-lib: default $(addsuffix -install-lib,$(SUBDIRS))
+
+%-install:
+ $(MAKE) -C $* install
+
+%-install-lib:
+ $(MAKE) -C $* install-lib
+
+%-install-dev:
+ $(MAKE) -C $* install-dev
+
+realclean distclean: clean
+ rm -f $(LDIRT) $(CONFIGURE)
+ rm -f include/builddefs include/config.h install-sh libtool
+ rm -rf autom4te.cache Logs
+
+.PHONY: tests root-tests nfs-tests
+tests root-tests nfs-tests: default
+ $(MAKE) -C test/ $@
diff --git a/Makepkgs b/Makepkgs
new file mode 100755
index 0000000..bc463df
--- /dev/null
+++ b/Makepkgs
@@ -0,0 +1,103 @@
+#! /bin/sh
+#
+# Copyright (C) 2001, 2002, 2003 Silicon Graphics, Inc. All rights reserved.
+#
+# 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 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 <http://www.gnu.org/licenses/>.
+#
+# Make whichever packages have been requested.
+# Defaults to RPMs.
+#
+LOGDIR=Logs
+
+type=rpm
+verbose=false
+
+MAKE=${MAKE:-make}
+test ! -z "$MAKE" && make=$MAKE
+
+for opt in $*
+do
+ case "$opt" in
+ clean)
+ ;; # ignored, kept for backward compatibility
+ rpm)
+ type=rpm ;;
+ debian)
+ type=debian ;;
+ verbose)
+ verbose=true ;;
+ *)
+ echo "Usage: Makepkgs [verbose] [debian|rpm]"; exit 1 ;;
+ esac
+done
+
+# start with a clean manifest
+test -f files.rpm && rm -f files.rpm
+test -f filesdevel.rpm && rm -f filesdevel.rpm
+test -f fileslib.rpm && rm -f fileslib.rpm
+
+test ! -d $LOGDIR && mkdir $LOGDIR
+rm -rf $LOGDIR/* > /dev/null 2>&1
+
+# build Debian packages, cleans itself before starting
+SUDO=${SUDO:-sudo}
+test ! -z "$SUDO" && sudo=$SUDO
+if [ $type = debian ] ; then
+ LOGDEB=`pwd`
+ LOGDEB=../`basename $LOGDEB`.log
+ echo "== Debian build, log is $LOGDEB"; echo
+ if $verbose ; then
+ dpkg-buildpackage -r$SUDO | tee $LOGDEB
+ else
+ dpkg-buildpackage -r$SUDO > $LOGDEB || exit 1
+ fi
+ exit 0
+fi
+
+# build RPM packages - manual clean before starting
+echo "== clean, log is $LOGDIR/clean"
+if $verbose ; then
+ $MAKE clean 2>&1 | tee $LOGDIR/clean
+else
+ $MAKE clean > $LOGDIR/clean 2>&1 || exit 1
+fi
+
+echo
+echo "== configure, log is $LOGDIR/configure"
+rm -f .census # force configure to run here
+if $verbose ; then
+ $MAKE configure 2>&1 | tee $LOGDIR/configure
+else
+ $MAKE configure > $LOGDIR/configure 2>&1 || exit 1
+fi
+
+echo
+echo "== default, log is $LOGDIR/default"
+if $verbose ; then
+ $MAKE default 2>&1 | tee $LOGDIR/default
+else
+ $MAKE default > $LOGDIR/default 2>&1 || exit 1
+fi
+
+echo
+echo "== dist, log is $LOGDIR/dist"
+[ ! -f .census ] && touch .census
+if $verbose ; then
+ $MAKE -C build dist 2>&1 | tee $LOGDIR/dist
+else
+ $MAKE -C build dist > $LOGDIR/dist 2>&1 || exit 1
+ grep '^Wrote:' $LOGDIR/dist | sed -e 's/\.\.\/\.\.\///'
+fi
+
+exit 0
diff --git a/README b/README
new file mode 100644
index 0000000..abcfdc6
--- /dev/null
+++ b/README
@@ -0,0 +1,13 @@
+Access control list package README
+__________________________________
+
+Package home: http://savannah.nongnu.org/projects/acl
+
+See the file doc/INSTALL for build, installation and post-
+install configuration steps.
+
+Refer to the acl(5) manual page for general access control list
+information and references to other related manual pages.
+
+For more information on the build process, please refer to
+doc/PORTING.
diff --git a/VERSION b/VERSION
new file mode 100644
index 0000000..7661291
--- /dev/null
+++ b/VERSION
@@ -0,0 +1,7 @@
+#
+# This file is used by configure to get version information
+#
+PKG_MAJOR=2
+PKG_MINOR=2
+PKG_REVISION=47
+PKG_BUILD=1
diff --git a/build/Makefile b/build/Makefile
new file mode 100644
index 0000000..0e87a20
--- /dev/null
+++ b/build/Makefile
@@ -0,0 +1,63 @@
+#
+# Copyright (c) 2000-2002 Silicon Graphics, Inc. All Rights Reserved.
+#
+# 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 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, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+
+TOPDIR = ..
+include $(TOPDIR)/include/builddefs
+
+MANIFEST=src-manifest
+SRCTAR=$(PKG_NAME)-$(PKG_VERSION).src.tar.gz
+
+LDIRT = *-manifest *.gz $(TOPDIR)/$(PKG_NAME)-*
+
+# for clean and clobber
+SUBDIRS = tar rpm
+
+# nothing to build here (it's all packaging)
+default install install-dev install-lib:
+
+include $(BUILDRULES)
+
+# Symlink in the TOPDIR is used to pack files relative to
+# product-version directory.
+$(MANIFEST) : $(_FORCE)
+ @if [ ! -L $(TOPDIR)/$(PKG_NAME)-$(PKG_VERSION) ] ; then \
+ $(LN_S) . $(TOPDIR)/$(PKG_NAME)-$(PKG_VERSION) ; \
+ fi
+ @CDIR=`pwd`; cd $(TOPDIR); \
+ $(MAKE) --no-print-directory source | \
+ sed -e 's/^\./$(PKG_NAME)-$(PKG_VERSION)/' > $$CDIR/$@ ;\
+ if [ $$? -ne 0 ] ; then \
+ exit 1; \
+ else \
+ unset TAPE; \
+ $(TAR) -T $$CDIR/$@ -cf - | $(ZIP) --best > $$CDIR/$(SRCTAR); \
+ echo Wrote: $$CDIR/$(SRCTAR); \
+ fi
+
+dist : default $(MANIFEST)
+ @DIST_MANIFEST=`pwd`/bin-manifest; DIST_ROOT=/tmp/$$$$; \
+ export DIST_MANIFEST DIST_ROOT; \
+ rm -f $$DIST_MANIFEST; \
+ echo === install === && $(MAKE) -C $(TOPDIR) install || exit $$?; \
+ if [ -x $(TAR) ]; then \
+ ( echo "=== tar ===" && $(MAKEF) -C tar $@ || exit $$? ); \
+ fi; \
+ if [ -x $(RPMBUILD) ]; then \
+ ( echo "=== rpm ===" && $(MAKEF) -C rpm $@ || exit $$? ); \
+ fi; \
+ test -z "$$KEEP_DIST_ROOT" || rm -rf $$DIST_ROOT; echo Done
diff --git a/build/rpm/Makefile b/build/rpm/Makefile
new file mode 100644
index 0000000..041b84c
--- /dev/null
+++ b/build/rpm/Makefile
@@ -0,0 +1,76 @@
+#
+# Copyright (c) 2000-2003 Silicon Graphics, Inc. All Rights Reserved.
+#
+# 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 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, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+
+TOPDIR = ../..
+TREEROOT = $(shell cd ${TOPDIR}; pwd)
+include $(TOPDIR)/include/builddefs
+
+SPECF = $(PKG_NAME).spec
+LDIRT = *.rpm $(SPECF) rpmmacros rpmfiles* rpm-*.rc
+
+LSRCFILES = macros.template $(SPECF).in rpm-2.rc.template
+
+default install install-dev install-lib:
+
+include $(BUILDRULES)
+
+# Generate a binary rpm file
+dist : default $(SPECF) rpm-$(RPM_VERSION).rc
+ $(RPMBUILD) -ba --rcfile ./rpm-$(RPM_VERSION).rc $(SPECF)
+
+# Because rpm prior to v.2.90 does not support macros and old style config
+# is not supported by rpm v.3, we have to resort to such ugly hacks
+ifneq ($(RPM_VERSION),2)
+rpm-$(RPM_VERSION).rc : rpmmacros
+ @$(SED) -e '/^macrofiles:/s|~/.rpmmacros|rpmmacros|' </usr/lib/rpm/rpmrc >$@
+
+rpmmacros : macros.template
+ @$(SED) -e 's|%topdir%|$(TREEROOT)|g' < $< > $@
+else
+rpm-2.rc: rpm-2.rc.template
+ @$(SED) -e 's|%topdir%|$(TOPDIR)|g' < $< > $@
+endif
+
+# Generate the rpm specfile format file list from the install-sh manifest
+rpmfiles rpmfiles-dev rpmfiles-lib:
+ $(SORT) -u $$DIST_MANIFEST | $(AWK) > $@ '\
+$$1 == "d" { printf ("%%%%dir %%%%attr(%s,%s,%s) %s\n", $$2, $$3, $$4, $$5); } \
+$$1 == "f" { if (match ($$6, "$(PKG_MAN_DIR)") || \
+ match ($$6, "$(PKG_DOC_DIR)")) \
+ printf ("%%%%doc "); \
+ if (match ($$6, "$(PKG_MAN_DIR)")) \
+ printf ("%%%%attr(%s,%s,%s) %s*\n", $$2, $$3, $$4, $$6); \
+ else \
+ printf ("%%%%attr(%s,%s,%s) %s\n", $$2, $$3, $$4, $$6); } \
+$$1 == "l" { if (match ($$3, "$(PKG_MAN_DIR)") || \
+ match ($$3, "$(PKG_DOC_DIR)")) \
+ printf ("%%%%doc "); \
+ if (match ($$3, "$(PKG_MAN_DIR)")) \
+ printf ("%%%%attr(0777,root,root) %s*\n", $$3); \
+ else \
+ printf ("%%%%attr(0777,root,root) %s\n", $$3); }'
+
+.PHONY: $(SPECF)
+${SPECF} : ${SPECF}.in
+ $(SED) -e's|@pkg_name@|$(PKG_NAME)|g' \
+ -e's|@pkg_version@|$(PKG_VERSION)|g' \
+ -e's|@pkg_release@|$(PKG_RELEASE)|g' \
+ -e's|@pkg_distribution@|$(PKG_DISTRIBUTION)|g' \
+ -e's|@build_root@|$(DIST_ROOT)|g' \
+ -e'/^BuildRoot: *$$/d' \
+ -e's|@make@|$(MAKE)|g' < $< > $@
diff --git a/build/rpm/acl.spec.in b/build/rpm/acl.spec.in
new file mode 100644
index 0000000..7946462
--- /dev/null
+++ b/build/rpm/acl.spec.in
@@ -0,0 +1,79 @@
+Summary: Access control list utilities.
+Name: @pkg_name@
+Version: @pkg_version@
+Release: @pkg_release@
+Packager: Silicon Graphics, Inc. <http://www.sgi.com/>
+BuildRoot: @build_root@
+Source: @pkg_name@-@pkg_version@.src.tar.gz
+License: GPL
+Vendor: Silicon Graphics, Inc.
+Group: System Environment/Base
+URL: http://acl.bestbits.at/
+
+%description
+This package contains the getfacl and setfacl utilities needed for
+manipulating access control lists.
+
+%package -n libacl
+Summary: Dynamic library for access control list support.
+Group: Development/Libraries
+Prereq: /sbin/ldconfig
+
+%description -n libacl
+This package contains the libacl.so dynamic library which contains
+the POSIX 1003.1e draft standard 17 functions for manipulating access
+control lists.
+
+%package -n libacl-devel
+Summary: Access control list static libraries and headers.
+Group: Development/Libraries
+Requires: libacl
+Provides: acl-devel
+Obsoletes: acl-devel
+
+%description -n libacl-devel
+This package contains static libraries and header files needed to develop
+programs which make use of the access control list programming interface
+defined in POSIX 1003.1e draft standard 17.
+
+%prep
+if [ -f .census ] ; then
+ if [ ! -d ${RPM_PACKAGE_NAME}-${RPM_PACKAGE_VERSION} ] ; then
+ ln -s . ${RPM_PACKAGE_NAME}-${RPM_PACKAGE_VERSION}
+ fi
+else
+%setup
+INSTALL_USER=root
+INSTALL_GROUP=root
+export INSTALL_USER INSTALL_GROUP
+@make@ configure
+fi
+
+%build
+@make@
+
+%install
+DIST_ROOT="$RPM_BUILD_ROOT"
+DIST_INSTALL=`pwd`/install.manifest
+DIST_INSTALL_DEV=`pwd`/install-dev.manifest
+DIST_INSTALL_LIB=`pwd`/install-lib.manifest
+export DIST_ROOT DIST_INSTALL DIST_INSTALL_DEV DIST_INSTALL_LIB
+@make@ install DIST_MANIFEST="$DIST_INSTALL"
+@make@ -C build/rpm rpmfiles DIST_MANIFEST="$DIST_INSTALL"
+@make@ install-dev DIST_MANIFEST="$DIST_INSTALL_DEV"
+@make@ -C build/rpm rpmfiles-dev DIST_MANIFEST="$DIST_INSTALL_DEV"
+@make@ install-lib DIST_MANIFEST="$DIST_INSTALL_LIB"
+@make@ -C build/rpm rpmfiles-lib DIST_MANIFEST="$DIST_INSTALL_LIB"
+
+%clean
+rm -rf $RPM_BUILD_ROOT
+
+%post -n libacl -p /sbin/ldconfig
+
+%postun -n libacl -p /sbin/ldconfig
+
+%files -f build/rpm/rpmfiles
+
+%files -n libacl-devel -f build/rpm/rpmfiles-dev
+
+%files -n libacl -f build/rpm/rpmfiles-lib
diff --git a/build/rpm/macros.template b/build/rpm/macros.template
new file mode 100644
index 0000000..4557242
--- /dev/null
+++ b/build/rpm/macros.template
@@ -0,0 +1,31 @@
+#
+# rpmrc.template
+#
+# Template to fudge rpm directory structure inside IRIX-like build
+# environment
+
+# Force 386 build on all platforms
+# (why that?)
+#%_target i386-pc-linux
+#%_target_cpu i386
+#%_target_os linux
+
+# topdir == $(WORKAREA)
+%_topdir %topdir%
+
+# Following directories are specific to the topdir
+# This is where build is done. In our case it's the same as $WORKAREA
+%_builddir %topdir%
+
+# This is where foo.1.99.tar.gz is living in the real world.
+# Be careful not to run full rpm build as it will override the sources
+%_sourcedir %topdir%/build
+
+# This is where binary RPM and source RPM would end up
+%_rpmdir %topdir%/build/rpm
+%_srcrpmdir %topdir%/build/rpm
+%_specdir %topdir%/build/rpm
+
+# Leave RPM files in the same directory - we're not building for
+# multiple architectures
+%_rpmfilename %%{NAME}-%%{VERSION}-%%{RELEASE}.%%{ARCH}.rpm
diff --git a/build/rpm/rpm-2.rc.template b/build/rpm/rpm-2.rc.template
new file mode 100644
index 0000000..f3b3eba
--- /dev/null
+++ b/build/rpm/rpm-2.rc.template
@@ -0,0 +1,25 @@
+#
+# rpmrc.template
+#
+# Template to fudge rpm directory structure inside IRIX-like build
+# environment
+
+# topdir == $(WORKAREA)
+topdir: %topdir%
+
+# Following directories are specific to the topdir
+# This is where build is done. In out case it's the same as $WORKAREA
+# Be careful not to run full rpm build as it will override the sources
+builddir: %topdir%
+
+# This is where foo.1.99.tar.gz is living in the real world.
+sourcedir: %topdir%/build
+
+# This is where binary RPM and source RPM would end up
+rpmdir: %topdir%/build/rpm
+srcrpmdir: %topdir%/build/rpm
+specdir: %topdir%/build/rpm
+
+# Leave RPM files in the same directory - we're not building for
+# multiple architectures
+rpmfilename: %{NAME}-%{VERSION}-%{RELEASE}.%{ARCH}.rpm
diff --git a/build/tar/Makefile b/build/tar/Makefile
new file mode 100644
index 0000000..31c8f92
--- /dev/null
+++ b/build/tar/Makefile
@@ -0,0 +1,36 @@
+#
+# Copyright (c) 2000-2003 Silicon Graphics, Inc. All Rights Reserved.
+#
+# 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 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, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+
+TOPDIR = ../..
+include $(TOPDIR)/include/builddefs
+
+BINTAR=$(PKG_NAME)-$(PKG_VERSION).tar.gz
+LDIRT = *.gz
+
+default install install-dev install-lib:
+
+include $(BUILDRULES)
+
+dist : default
+ @HERE=`pwd`; cd $${DIST_ROOT:-/}; \
+ $(SORT) -u $$HERE/../bin-manifest | $(AWK) ' \
+ $$1 == "f" { printf (".%s\n", $$6); } \
+ $$1 == "d" { next; } \
+ $$1 == "l" { printf (".%s\n", $$3); }' \
+ | $(TAR) -T - -cf - | $(ZIP) --best > $$HERE/$(BINTAR)
+ @echo Wrote: `pwd`/$(BINTAR)
diff --git a/chacl/Makefile b/chacl/Makefile
new file mode 100644
index 0000000..33858d6
--- /dev/null
+++ b/chacl/Makefile
@@ -0,0 +1,35 @@
+#
+# Copyright (c) 2000-2002 Silicon Graphics, Inc. All Rights Reserved.
+#
+# 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 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, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+
+TOPDIR = ..
+include $(TOPDIR)/include/builddefs
+
+LTCOMMAND = chacl
+CFILES = chacl.c
+
+LLDLIBS = $(LIBACL) $(LIBATTR)
+LTDEPENDENCIES = $(LIBACL)
+
+default: $(LTCOMMAND)
+
+include $(BUILDRULES)
+
+install: default
+ $(INSTALL) -m 755 -d $(PKG_BIN_DIR)
+ $(LTINSTALL) -m 755 $(LTCOMMAND) $(PKG_BIN_DIR)
+install-dev install-lib:
diff --git a/chacl/chacl.c b/chacl/chacl.c
new file mode 100644
index 0000000..854a620
--- /dev/null
+++ b/chacl/chacl.c
@@ -0,0 +1,354 @@
+/*
+ * Copyright (c) 2001-2002 Silicon Graphics, Inc.
+ * All Rights Reserved.
+ *
+ * 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 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it would 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, write the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <getopt.h>
+#include <libgen.h>
+#include <stdio.h>
+#include <errno.h>
+#include <dirent.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/acl.h>
+#include <acl/libacl.h>
+#include <locale.h>
+#include "config.h"
+
+static int acl_delete_file (const char * path, acl_type_t type);
+static int list_acl(char *file);
+static int set_acl(acl_t acl, acl_t dacl, const char *fname);
+static int walk_dir(acl_t acl, acl_t dacl, const char *fname);
+
+static char *program;
+static int rflag;
+
+static void
+usage(void)
+{
+ fprintf(stderr, _("Usage:\n"));
+ fprintf(stderr, _("\t%s acl pathname...\n"), program);
+ fprintf(stderr, _("\t%s -b acl dacl pathname...\n"), program);
+ fprintf(stderr, _("\t%s -d dacl pathname...\n"), program);
+ fprintf(stderr, _("\t%s -R pathname...\n"), program);
+ fprintf(stderr, _("\t%s -D pathname...\n"), program);
+ fprintf(stderr, _("\t%s -B pathname...\n"), program);
+ fprintf(stderr, _("\t%s -l pathname...\t[not IRIX compatible]\n"),
+ program);
+ fprintf(stderr, _("\t%s -r pathname...\t[not IRIX compatible]\n"),
+ program);
+ exit(1);
+}
+
+int
+main(int argc, char *argv[])
+{
+ char *file;
+ int switch_flag = 0; /* ensure only one switch is used */
+ int args_required = 2;
+ int failed = 0; /* exit status */
+ int c; /* For use by getopt(3) */
+ int dflag = 0; /* a Default ACL is desired */
+ int bflag = 0; /* a both ACLs are desired */
+ int Rflag = 0; /* set to true to remove an acl */
+ int Dflag = 0; /* set to true to remove default acls */
+ int Bflag = 0; /* set to true to remove both acls */
+ int lflag = 0; /* set to true to list acls */
+ acl_t acl = NULL; /* File ACL */
+ acl_t dacl = NULL; /* Directory Default ACL */
+
+ program = basename(argv[0]);
+
+ setlocale(LC_CTYPE, "");
+ setlocale(LC_MESSAGES, "");
+ bindtextdomain(PACKAGE, LOCALEDIR);
+ textdomain(PACKAGE);
+
+ /* parse arguments */
+ while ((c = getopt(argc, argv, "bdlRDBr")) != -1) {
+ if (switch_flag)
+ usage();
+ switch_flag = 1;
+
+ switch (c) {
+ case 'b':
+ bflag = 1;
+ args_required = 3;
+ break;
+ case 'd':
+ dflag = 1;
+ args_required = 2;
+ break;
+ case 'R':
+ Rflag = 1;
+ args_required = 1;
+ break;
+ case 'D':
+ Dflag = 1;
+ args_required = 1;
+ break;
+ case 'B':
+ Bflag = 1;
+ args_required = 1;
+ break;
+ case 'l':
+ lflag = 1;
+ args_required = 1;
+ break;
+ case 'r':
+ rflag = 1;
+ args_required = 1;
+ break;
+ default:
+ usage();
+ break;
+ }
+ }
+
+ /* if not enough arguments quit */
+ if ((argc - optind) < args_required)
+ usage();
+
+ /* list the acls */
+ if (lflag) {
+ for (; optind < argc; optind++) {
+ file = argv[optind];
+ if (!list_acl(file))
+ failed++;
+ }
+ return(failed);
+ }
+
+ /* remove the acls */
+ if (Rflag || Dflag || Bflag) {
+ for (; optind < argc; optind++) {
+ file = argv[optind];
+ if (!Dflag &&
+ (acl_delete_file(file, ACL_TYPE_ACCESS) == -1)) {
+ fprintf(stderr, _(
+ "%s: error removing access acl on \"%s\": %s\n"),
+ program, file, strerror(errno));
+ failed++;
+ }
+ if (!Rflag &&
+ (acl_delete_file(file, ACL_TYPE_DEFAULT) == -1)) {
+ fprintf(stderr, _(
+ "%s: error removing default acl on \"%s\": %s\n"),
+ program, file, strerror(errno));
+ failed++;
+ }
+ }
+ return(failed);
+ }
+
+ /* file access acl */
+ if (! dflag) {
+ acl = acl_from_text(argv[optind]);
+ failed = acl_check(acl, &c);
+ if (failed < 0) {
+ fprintf(stderr, "%s: %s - %s\n",
+ program, argv[optind], strerror(errno));
+ return 1;
+ }
+ else if (failed > 0) {
+ fprintf(stderr, _(
+ "%s: access ACL '%s': %s at entry %d\n"),
+ program, argv[optind], acl_error(failed), c);
+ return 1;
+ }
+ optind++;
+ }
+
+
+ /* directory default acl */
+ if (bflag || dflag) {
+ dacl = acl_from_text(argv[optind]);
+ failed = acl_check(dacl, &c);
+ if (failed < 0) {
+ fprintf(stderr, "%s: %s - %s\n",
+ program, argv[optind], strerror(errno));
+ return 1;
+ }
+ else if (failed > 0) {
+ fprintf(stderr, _(
+ "%s: access ACL '%s': %s at entry %d\n"),
+ program, argv[optind], acl_error(failed), c);
+ return 1;
+ }
+ optind++;
+ }
+
+ /* place acls on files */
+ for (; optind < argc; optind++)
+ failed += set_acl(acl, dacl, argv[optind]);
+
+ if (acl)
+ acl_free(acl);
+ if (dacl)
+ acl_free(dacl);
+
+ return(failed);
+}
+
+/*
+ * deletes an access acl or directory default acl if one exists
+ */
+static int
+acl_delete_file(const char *path, acl_type_t type)
+{
+ int error = 0;
+
+ /* converts access ACL to a minimal ACL */
+ if (type == ACL_TYPE_ACCESS) {
+ acl_t acl;
+ acl_entry_t entry;
+ acl_tag_t tag;
+
+ acl = acl_get_file(path, ACL_TYPE_ACCESS);
+ if (!acl)
+ return -1;
+ error = acl_get_entry(acl, ACL_FIRST_ENTRY, &entry);
+ while (error == 1) {
+ acl_get_tag_type(entry, &tag);
+ switch(tag) {
+ case ACL_USER:
+ case ACL_GROUP:
+ case ACL_MASK:
+ acl_delete_entry(acl, entry);
+ break;
+ }
+ error = acl_get_entry(acl, ACL_NEXT_ENTRY, &entry);
+ }
+ if (!error)
+ error = acl_set_file(path, ACL_TYPE_ACCESS, acl);
+ } else
+ error = acl_delete_def_file(path);
+ return(error);
+}
+
+/*
+ * lists the acl for a file/dir in short text form
+ * return 0 on failure
+ * return 1 on success
+ */
+static int
+list_acl(char *file)
+{
+ acl_t acl = NULL;
+ acl_t dacl = NULL;
+ char *acl_text, *dacl_text = NULL;
+
+ if ((acl = acl_get_file(file, ACL_TYPE_ACCESS)) == NULL) {
+ fprintf(stderr, _("%s: cannot get access ACL on '%s': %s\n"),
+ program, file, strerror(errno));
+ return 0;
+ }
+ if ((dacl = acl_get_file(file, ACL_TYPE_DEFAULT)) == NULL &&
+ (errno != EACCES)) { /* EACCES given if not a directory */
+ fprintf(stderr, _("%s: cannot get default ACL on '%s': %s\n"),
+ program, file, strerror(errno));
+ return 0;
+ }
+ acl_text = acl_to_any_text(acl, NULL, ',', TEXT_ABBREVIATE);
+ if (acl_text == NULL) {
+ fprintf(stderr, _("%s: cannot get access ACL text on "
+ "'%s': %s\n"), program, file, strerror(errno));
+ return 0;
+ }
+ if (acl_entries(dacl) > 0) {
+ dacl_text = acl_to_any_text(dacl, NULL, ',', TEXT_ABBREVIATE);
+ if (dacl_text == NULL) {
+ fprintf(stderr, _("%s: cannot get default ACL text on "
+ "'%s': %s\n"), program, file, strerror(errno));
+ return 0;
+ }
+ }
+ if (dacl_text) {
+ printf("%s [%s/%s]\n", file, acl_text, dacl_text);
+ acl_free(dacl_text);
+ } else
+ printf("%s [%s]\n", file, acl_text);
+ acl_free(acl_text);
+ acl_free(acl);
+ acl_free(dacl);
+ return 1;
+}
+
+static int
+set_acl(acl_t acl, acl_t dacl, const char *fname)
+{
+ int failed = 0;
+
+ if (rflag)
+ failed += walk_dir(acl, dacl, fname);
+
+ /* set regular acl */
+ if (acl && acl_set_file(fname, ACL_TYPE_ACCESS, acl) == -1) {
+ fprintf(stderr, _("%s: cannot set access acl on \"%s\": %s\n"),
+ program, fname, strerror(errno));
+ failed++;
+ }
+ /* set default acl */
+ if (dacl && acl_set_file(fname, ACL_TYPE_DEFAULT, dacl) == -1) {
+ fprintf(stderr, _("%s: cannot set default acl on \"%s\": %s\n"),
+ program, fname, strerror(errno));
+ failed++;
+ }
+
+ return(failed);
+}
+
+static int
+walk_dir(acl_t acl, acl_t dacl, const char *fname)
+{
+ int failed = 0;
+ DIR *dir;
+ struct dirent64 *d;
+ char *name;
+
+ if ((dir = opendir(fname)) == NULL) {
+ if (errno != ENOTDIR) {
+ fprintf(stderr, _("%s: opendir failed: %s\n"),
+ program, strerror(errno));
+ return(1);
+ }
+ return(0); /* got a file, not an error */
+ }
+
+ while ((d = readdir64(dir)) != NULL) {
+ /* skip "." and ".." entries */
+ if (strcmp(d->d_name, ".") == 0 || strcmp(d->d_name, "..") == 0)
+ continue;
+
+ name = malloc(strlen(fname) + strlen(d->d_name) + 2);
+ if (name == NULL) {
+ fprintf(stderr, _("%s: malloc failed: %s\n"),
+ program, strerror(errno));
+ exit(1);
+ }
+ sprintf(name, "%s/%s", fname, d->d_name);
+
+ failed += set_acl(acl, dacl, name);
+ free(name);
+ }
+ closedir(dir);
+
+ return(failed);
+}
diff --git a/configure.in b/configure.in
new file mode 100644
index 0000000..7af2e8d
--- /dev/null
+++ b/configure.in
@@ -0,0 +1,49 @@
+# Copyright (C) 2009 Andreas Gruenbacher <agruen@suse.de>
+#
+# 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 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 <http://www.gnu.org/licenses/>.
+#
+AC_INIT(include/acl.h)
+AC_CONFIG_AUX_DIR([.])
+AC_CONFIG_MACRO_DIR([m4])
+AC_CONFIG_HEADER(include/config.h)
+AC_PREFIX_DEFAULT(/usr)
+
+AC_PROG_LIBTOOL
+
+AC_ARG_ENABLE(shared,
+[ --enable-shared=[yes/no] Enable use of shared libraries [default=yes]],,
+ enable_shared=yes)
+AC_SUBST(enable_shared)
+
+AC_ARG_ENABLE(gettext,
+[ --enable-gettext=[yes/no] Enable alternate language support [default=yes]],,
+ enable_gettext=yes)
+AC_SUBST(enable_gettext)
+
+AC_ARG_ENABLE(lib64,
+[ --enable-lib64=[yes/no] Enable lib64 support [default=no]],,
+ enable_lib64=no)
+AC_SUBST(enable_lib64)
+
+AC_PACKAGE_GLOBALS(acl)
+AC_PACKAGE_UTILITIES(acl)
+AC_PACKAGE_NEED_ATTR_XATTR_H
+AC_PACKAGE_NEED_ATTR_ERROR_H
+AC_MULTILIB($enable_lib64)
+AC_PACKAGE_NEED_GETXATTR_LIBATTR
+AC_MANUAL_FORMAT
+
+AC_FUNC_GCC_VISIBILITY
+
+AC_OUTPUT(include/builddefs)
diff --git a/debian/Makefile b/debian/Makefile
new file mode 100644
index 0000000..0a0fc2d
--- /dev/null
+++ b/debian/Makefile
@@ -0,0 +1,51 @@
+#
+# Copyright (c) 2000-2003 Silicon Graphics, Inc. All Rights Reserved.
+#
+# 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 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, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+
+TOPDIR = ..
+include $(TOPDIR)/include/builddefs
+
+LIBPKG = lib$(PKG_NAME)1
+LSRCFILES = changelog compat control copyright rules watch
+DEV_DOC_DIR = $(PKG_DOC_DIR)/../$(LIBPKG)-dev
+LIB_DOC_DIR = $(PKG_DOC_DIR)/../$(LIBPKG)
+
+default:
+
+include $(BUILDRULES)
+
+install: default
+ifeq ($(PKG_DISTRIBUTION), debian)
+ $(INSTALL) -m 755 -d $(PKG_DOC_DIR)
+ $(INSTALL) -m 644 changelog $(PKG_DOC_DIR)/changelog.Debian
+endif
+
+install-dev: default
+ifeq ($(PKG_DISTRIBUTION), debian)
+ $(INSTALL) -m 755 -d $(PKG_DOC_DIR)
+ $(INSTALL) -m 755 -d $(DEV_DOC_DIR)
+ $(INSTALL) -m 644 copyright $(DEV_DOC_DIR)
+ $(INSTALL) -m 644 changelog $(DEV_DOC_DIR)/changelog.Debian
+endif
+
+install-lib: default
+ifeq ($(PKG_DISTRIBUTION), debian)
+ $(INSTALL) -m 755 -d $(PKG_DOC_DIR)
+ $(INSTALL) -m 755 -d $(LIB_DOC_DIR)
+ $(INSTALL) -m 644 copyright $(LIB_DOC_DIR)
+ $(INSTALL) -m 644 changelog $(LIB_DOC_DIR)/changelog.Debian
+endif
diff --git a/debian/changelog b/debian/changelog
new file mode 100644
index 0000000..cb01da5
--- /dev/null
+++ b/debian/changelog
@@ -0,0 +1,335 @@
+acl (2.2.47-2) unstable; urgency=low
+
+ * Acknowledge NMU. Closes: Closes: #477515
+
+ -- Anibal Monsalve Salazar <anibal@debian.org> Thu, 24 Apr 2008 06:47:12 +1000
+
+acl (2.2.47-1.1) unstable; urgency=low
+
+ * Non-maintainer upload.
+ * Don't call configure with --enable-lib64=yes. (Closes: #477515)
+ This fixes the lib64 rpaths, so no need to call chrpath anymore.
+
+ -- Kurt Roeckx <kurt@roeckx.be> Wed, 23 Apr 2008 18:58:41 +0200
+
+acl (2.2.47-1) unstable; urgency=low
+
+ * New upstream release
+ * Update debian/watch
+ * Remove empty directories. Closes: #445902, #222534
+ * Fix the following lintian issues:
+ W: acl source: package-uses-deprecated-debhelper-compat-version 1
+ W: acl source: out-of-date-standards-version 3.7.2 (current is 3.7.3)
+ W: libacl1-dev: package-contains-empty-directory usr/share/doc/acl/
+ W: libacl1-dev: description-contains-homepage
+ W: libacl1: package-contains-empty-directory usr/share/doc/acl/
+ W: libacl1: description-contains-homepage
+ W: acl: description-contains-homepage
+ W: acl: binary-or-shlib-defines-rpath ./usr/bin/chacl /lib64
+ W: acl: binary-or-shlib-defines-rpath ./usr/bin/getfacl /lib64
+ W: acl: binary-or-shlib-defines-rpath ./usr/bin/setfacl /lib64
+
+ -- Anibal Monsalve Salazar <anibal@debian.org> Wed, 23 Apr 2008 21:48:29 +1000
+
+acl (2.2.45-1) unstable; urgency=low
+
+ * New upstream release
+ * debian/control:
+ - Added homepage
+ - Added myself as comaintainer
+ - Set Standards-Version to 3.7.2
+ - libacl1-dev depends on libacl1 (= ${binary:Version})
+ - acl and libacl1 depend on ${misc:Depends}
+ * debian/rules: Regenerate acl.pot
+ * debian/watch: Added
+
+ -- Anibal Monsalve Salazar <anibal@debian.org> Sat, 15 Sep 2007 14:28:33 +1000
+
+acl (2.2.42-1) unstable; urgency=low
+
+ * New upstream release
+ * Incorporate Petr Salinger's GNU/kFreeBSD patch (closes: #401511)
+
+ -- Nathan Scott <nathans@debian.org> Fri, 08 Dec 2006 14:21:40 +1100
+
+acl (2.2.41-1) unstable; urgency=low
+
+ * New upstream release
+ * Rework translation Makefile slightly (closes: #375796)
+
+ -- Nathan Scott <nathans@debian.org> Fri, 21 Jul 2006 09:37:35 +1000
+
+acl (2.2.39-1) unstable; urgency=low
+
+ * New upstream release
+ * Add Swedish translation from Daniel Nylander (closes: #368656)
+ * Fix get/setfacl segfault on non-existant files (closes: #370826)
+
+ -- Nathan Scott <nathans@debian.org> Wed, 07 Jun 2006 09:30:45 +1000
+
+acl (2.2.37-1) unstable; urgency=low
+
+ * New upstream release
+ * Fix tree walking with symbolic links (closes: #333160)
+
+ -- Nathan Scott <nathans@debian.org> Tue, 02 May 2006 09:41:15 +1000
+
+acl (2.2.36-1) unstable; urgency=low
+
+ * New upstream release
+ * Fixed build dependency on libc-dev (closes: #358788)
+
+ -- Nathan Scott <nathans@debian.org> Tue, 28 Mar 2006 09:14:25 +1100
+
+acl (2.2.35-1) unstable; urgency=low
+
+ * New upstream release
+ * Switch from debmake to debhelper
+
+ -- Nathan Scott <nathans@debian.org> Wed, 15 Feb 2006 20:43:49 +1100
+
+acl (2.2.34-1) unstable; urgency=low
+
+ * New upstream release
+ * Add libacl1-dev dependency on libattr1-dev (closes: #339786, #341711)
+
+ -- Nathan Scott <nathans@debian.org> Mon, 05 Dec 2005 11:15:41 +1100
+
+acl (2.2.33-1) unstable; urgency=low
+
+ * New upstream release
+
+ -- Nathan Scott <nathans@debian.org> Thu, 10 Nov 2005 07:59:12 +1100
+
+acl (2.2.32-1) unstable; urgency=low
+
+ * New upstream release
+ * Added French translation (closes: #330596)
+
+ -- Nathan Scott <nathans@debian.org> Thu, 29 Sep 2005 09:47:28 +1000
+
+acl (2.2.29-1) unstable; urgency=low
+
+ * New upstream release
+ * Replace use of _POSIX_PATH_MAX with PATH_MAX (closes: #292819)
+
+ -- Nathan Scott <nathans@debian.org> Mon, 31 Jan 2005 20:13:02 +1100
+
+acl (2.2.28-1) unstable; urgency=low
+
+ * New upstream release
+
+ -- Nathan Scott <nathans@debian.org> Tue, 30 Nov 2004 15:29:29 +1100
+
+acl (2.2.26-1) unstable; urgency=low
+
+ * New upstream release
+ * acl.5 man page user/group typo fixed (closes: #272186)
+
+ -- Nathan Scott <nathans@debian.org> Fri, 10 Sep 2004 10:51:19 +1000
+
+acl (2.2.23-1) unstable; urgency=low
+
+ * New upstream release
+
+ -- Nathan Scott <nathans@debian.org> Mon, 02 Feb 2004 12:35:56 +1100
+
+acl (2.2.21-1) unstable; urgency=low
+
+ * New upstream release
+ * Make libacl1-dev conflict on kerberos4kth versioned (closes: #219715)
+
+ -- Nathan Scott <nathans@debian.org> Mon, 10 Nov 2003 09:23:21 +1100
+
+acl (2.2.20-1) unstable; urgency=low
+
+ * New upstream release
+ * Fix incorrect man page entry (closes: #213244)
+ * Fix GNU/Hurd build issues, thanks to Robert Millan (closes: #215153)
+
+ -- Nathan Scott <nathans@debian.org> Mon, 13 Oct 2003 13:07:43 +1000
+
+acl (2.2.15-1) unstable; urgency=low
+
+ * New upstream release
+
+ -- Nathan Scott <nathans@debian.org> Fri, 08 Aug 2003 16:39:10 +1000
+
+acl (2.2.14-1) unstable; urgency=low
+
+ * New upstream release
+
+ -- Nathan Scott <nathans@debian.org> Mon, 04 Aug 2003 09:18:00 +1000
+
+acl (2.2.13-1) unstable; urgency=low
+
+ * New upstream release
+
+ -- Nathan Scott <nathans@debian.org> Tue, 29 Jul 2003 11:27:53 +1000
+
+acl (2.2.12-1) unstable; urgency=low
+
+ * Don't always call msgmerge, fix from Steve Langasek (closes: #199277)
+
+ -- Nathan Scott <nathans@debian.org> Thu, 3 Jul 2003 10:55:01 +1000
+
+acl (2.2.11-1) unstable; urgency=low
+
+ * New upstream release
+ * Fix lib package dependencies, thanks to Steve Langasek (closes: #193149)
+
+ -- Nathan Scott <nathans@debian.org> Wed, 04 Jun 2003 15:50:50 +1000
+
+acl (2.2.10-1) unstable; urgency=low
+
+ * New upstream release
+ * Added runtime conflict with libacl1-kerberos4kth, as the
+ presence of this package breaks Samba's use of libacl1.
+
+ -- Nathan Scott <nathans@debian.org> Mon, 26 May 2003 11:38:53 +1000
+
+acl (2.2.9-1) unstable; urgency=low
+
+ * New upstream release
+ * Updated policy version to which this package conforms
+ * Fine-tuned the libacl1-dev dependencies a bit (closes: #188068)
+
+ -- Nathan Scott <nathans@debian.org> Sat, 26 Apr 2003 04:36:01 +1000
+
+acl (2.2.4-1) unstable; urgency=low
+
+ * New upstream release
+
+ -- Nathan Scott <nathans@debian.org> Mon, 10 Feb 2003 16:15:18 +1100
+
+acl (2.2.1-1) unstable; urgency=low
+
+ * Clarify acl(5) with respect to fileutils support (closes: #172642)
+ * Fix a bash-ism in debian/rules (closes: #173025)
+
+ -- Nathan Scott <nathans@debian.org> Mon, 16 Dec 2002 09:40:50 +1100
+
+acl (2.2.0-1) unstable; urgency=low
+
+ * New upstream release
+ * Added runtime conflict with kerberos4kth-dev (closes: #172169)
+
+ -- Nathan Scott <nathans@debian.org> Mon, 9 Dec 2002 08:09:15 +1100
+
+acl (2.1.1-1) unstable; urgency=low
+
+ * Fix Debian package dependency rules for acl (closes: #166709)
+ * Fix the group for libacl1, was "utils" now "libs" (closes: #166835)
+
+ -- Nathan Scott <nathans@debian.org> Tue, 29 Oct 2002 09:29:52 +1100
+
+acl (2.1.0-1) unstable; urgency=low
+
+ * New upstream release, changing dev package name (closes: #141756)
+
+ -- Nathan Scott <nathans@debian.org> Sat, 19 Oct 2002 08:40:38 +1000
+
+acl (2.0.19-1) unstable; urgency=low
+
+ * New upstream release
+
+ -- Nathan Scott <nathans@debian.org> Thu, 5 Sep 2002 09:12:02 +1000
+
+acl (2.0.17-1) unstable; urgency=low
+
+ * New upstream bugfix release
+
+ -- Nathan Scott <nathans@debian.org> Tue, 13 Aug 2002 07:52:54 +1000
+
+acl (2.0.15-1) unstable; urgency=low
+
+ * New upstream release (build-related and docs changes only)
+ * Follow Steve Langasek's advice to fix libattr issue (closes: #150854)
+
+ -- Nathan Scott <nathans@debian.org> Thu, 4 Jul 2002 12:10:38 +1000
+
+acl (2.0.14-1) unstable; urgency=low
+
+ * New upstream release (build-related changes only)
+
+ -- Nathan Scott <nathans@debian.org> Thu, 4 Jul 2002 12:10:38 +1000
+
+acl (2.0.13-1) unstable; urgency=low
+
+ * New upstream release for (even) closer standard compliance
+ * Increment the libacl version from 1.0.1 to 1.0.2
+
+ -- Nathan Scott <nathans@debian.org> Tue, 25 Jun 2002 17:08:03 +1000
+
+acl (2.0.12-1) unstable; urgency=low
+
+ * Increment the libacl version from 1.0.0 to 1.0.1 (closes: #150854)
+
+ -- Nathan Scott <nathans@debian.org> Tue, 25 Jun 2002 08:27:20 +1000
+
+acl (2.0.11-1) unstable; urgency=low
+
+ * New upstream bugfix release
+
+ -- Nathan Scott <nathans@debian.org> Wed, 1 May 2002 09:30:54 +1000
+
+acl (2.0.10-1) unstable; urgency=low
+
+ * New upstream bugfix release
+ * Add accidentally removed dependency of libacl on libattr
+
+ -- Nathan Scott <nathans@debian.org> Mon, 22 Apr 2002 15:12:21 +1000
+
+acl (2.0.9-1) unstable; urgency=low
+
+ * New upstream bugfix release (affects 64 bit platforms only)
+
+ -- Nathan Scott <nathans@debian.org> Tue, 16 Apr 2002 08:31:48 +1000
+
+acl (2.0.8-1) unstable; urgency=low
+
+ * New upstream bugfix release
+
+ -- Nathan Scott <nathans@debian.org> Sat, 13 Apr 2002 09:45:06 +1000
+
+acl (2.0.7-1) unstable; urgency=low
+
+ * New upstream bugfix release
+
+ -- Nathan Scott <nathans@debian.org> Wed, 10 Apr 2002 09:50:24 +1100
+
+acl (2.0.6-1) unstable; urgency=low
+
+ * New upstream bugfix release
+
+ -- Nathan Scott <nathans@debian.org> Mon, 8 Apr 2002 08:56:34 +1100
+
+acl (2.0.5-1) unstable; urgency=low
+
+ * New upstream release
+
+ -- Nathan Scott <nathans@debian.org> Wed, 27 Mar 2002 08:47:58 +1100
+
+acl (2.0.4-2) unstable; urgency=low
+
+ * Fix attr-dev build dependency issue (closes: #138280)
+
+ -- Nathan Scott <nathans@debian.org> Fri, 15 Mar 2002 07:08:50 +1100
+
+acl (2.0.4-1) unstable; urgency=low
+
+ * New upstream bugfix release
+
+ -- Nathan Scott <nathans@debian.org> Tue, 12 Mar 2002 09:47:50 +1100
+
+acl (2.0.2-1) unstable; urgency=low
+
+ * Initial release (closes: #97686)
+ * Uses the official Linux extended attributes interfaces (currently
+ supported by ext2, ext3, and XFS)
+
+ -- Nathan Scott <nathans@debian.org> Tue, 26 Feb 2002 13:25:26 +1100
+
+Local variables:
+mode: debian-changelog
+End:
diff --git a/debian/compat b/debian/compat
new file mode 100644
index 0000000..7ed6ff8
--- /dev/null
+++ b/debian/compat
@@ -0,0 +1 @@
+5
diff --git a/debian/control b/debian/control
new file mode 100644
index 0000000..1681b0b
--- /dev/null
+++ b/debian/control
@@ -0,0 +1,39 @@
+Source: acl
+Section: utils
+Priority: optional
+Maintainer: Nathan Scott <nathans@debian.org>
+Uploaders: Anibal Monsalve Salazar <anibal@debian.org>, Niv Sardi <xaiki@debian.org>
+Build-Depends: autoconf, debhelper (>= 5), gettext, libtool, libattr1-dev (>= 2.4.4)
+Standards-Version: 3.7.3
+Homepage: http://oss.sgi.com/projects/xfs/
+
+Package: acl
+Depends: ${shlibs:Depends}, ${misc:Depends}
+Architecture: any
+Description: Access control list utilities
+ This package contains the getfacl and setfacl utilities needed for
+ manipulating access control lists.
+
+Package: libacl1-dev
+Section: libdevel
+Priority: extra
+Depends: libc6-dev | libc-dev, libacl1 (= ${binary:Version}), libattr1-dev (>= 2.4.4)
+Provides: acl-dev
+Replaces: acl-dev
+Conflicts: acl-dev, acl (<< 2.0.0), kerberos4kth-dev (<< 1.2.2-4)
+Architecture: any
+Description: Access control list static libraries and headers
+ This package contains the static libraries and header files needed
+ for developing programs which make use of the access control list
+ programming interface defined in POSIX 1003.1e draft standard 17.
+
+Package: libacl1
+Depends: ${shlibs:Depends}, ${misc:Depends}
+Section: libs
+Priority: required
+Conflicts: acl (<< 2.0.0), libacl1-kerberos4kth
+Architecture: any
+Description: Access control list shared library
+ This package contains the libacl.so dynamic library containing
+ the POSIX 1003.1e draft standard 17 functions for manipulating
+ access control lists.
diff --git a/debian/copyright b/debian/copyright
new file mode 100644
index 0000000..a7dd472
--- /dev/null
+++ b/debian/copyright
@@ -0,0 +1,19 @@
+This package was debianized by Nathan Scott nathans@debian.org on
+Tue, 26 Feb 2002 13:25:26 +1100
+
+It can be downloaded from ftp://acl.bestbits.at/
+
+Copyright:
+
+Copyright (C) 2001 Andreas Gruenbacher.
+Copyright (C) 2001-2002 Silicon Graphics, Inc. All Rights Reserved.
+
+You are free to distribute this software under Version 2.1
+of the GNU Lesser General Public License.
+On Debian systems, refer to /usr/share/common-licenses/LGPL-2.1
+for the complete text of the GNU Lesser General Public License.
+
+Certain components (as annotated in the source) are licensed
+under the terms of the GNU General Public License.
+On Debian systems, the complete text of the GNU General Public
+License can be found in /usr/share/common-licenses/GPL file.
diff --git a/debian/rules b/debian/rules
new file mode 100755
index 0000000..41293b3
--- /dev/null
+++ b/debian/rules
@@ -0,0 +1,74 @@
+#!/usr/bin/make -f
+
+export DH_VERBOSE=1
+
+package = acl
+develop = lib$(package)1-dev
+library = lib$(package)1
+
+dirme = debian/$(package)
+dirdev = debian/$(develop)
+dirlib = debian/$(library)
+pkgme = DIST_ROOT=`pwd`/$(dirme); export DIST_ROOT;
+pkgdev = DIST_ROOT=`pwd`/$(dirdev); export DIST_ROOT;
+pkglib = DIST_ROOT=`pwd`/$(dirlib); export DIST_ROOT;
+stdenv = @GZIP=-q; export GZIP;
+
+options = export DEBUG=-DNDEBUG DISTRIBUTION=debian \
+ INSTALL_USER=root INSTALL_GROUP=root ;
+checkdir = test -f debian/rules
+
+build: built
+built: config
+ @echo "== dpkg-buildpackage: build" 1>&2
+ $(MAKE) default
+ cd po; rm -rf acl.pot; make acl.pot
+ touch built
+
+config: .census
+.census:
+ @echo "== dpkg-buildpackage: configure" 1>&2
+ $(checkdir)
+ $(options) $(MAKE) configure
+ touch .census
+
+clean:
+ @echo "== dpkg-buildpackage: clean" 1>&2
+ $(checkdir)
+ -rm -f built .census
+ $(MAKE) distclean
+ -rm -rf $(dirme) $(dirdev) $(dirlib)
+ -rm -f debian/*substvars debian/files* debian/*.debhelper
+
+binary-indep:
+
+binary-arch: checkroot built
+ @echo "== dpkg-buildpackage: binary-arch" 1>&2
+ $(checkdir)
+ -rm -rf $(dirme) $(dirdev) $(dirlib)
+ $(pkgme) $(MAKE) -C . install
+ $(pkgdev) $(MAKE) -C . install-dev
+ $(pkglib) $(MAKE) -C . install-lib
+ $(pkgme) $(MAKE) -C build src-manifest
+ rmdir debian/libacl1-dev/usr/share/doc/acl
+ rmdir debian/libacl1/usr/share/doc/acl
+ dh_installdocs
+ dh_installchangelogs
+ dh_strip
+ dh_compress
+ dh_fixperms
+ dh_makeshlibs -N $(library)
+ dh_makeshlibs -p $(library) -V 'libacl1 (>= 2.2.11-1)'
+ dh_installdeb
+ dh_shlibdeps
+ dh_gencontrol
+
+ dh_md5sums
+ dh_builddeb
+
+binary: binary-indep binary-arch
+
+checkroot:
+ test 0 -eq `id -u`
+
+.PHONY: binary binary-arch binary-indep clean checkroot
diff --git a/debian/watch b/debian/watch
new file mode 100644
index 0000000..c14272b
--- /dev/null
+++ b/debian/watch
@@ -0,0 +1,2 @@
+version=3
+ftp://oss.sgi.com/projects/xfs/cmd_tars/ acl_([\d]+[\d\.]*)-[\d].tar.gz
diff --git a/doc/CHANGES b/doc/CHANGES
new file mode 100644
index 0000000..666b866
--- /dev/null
+++ b/doc/CHANGES
@@ -0,0 +1,495 @@
+* Fix in acl_equiv_mode(): Return the mode that the acl corresponds to even
+ when the acl has more than three entries (i.e., it is not equivalent to
+ this mode).
+* When restoring acls and the file ownership from the output of getfacl
+ with setfacl --restore, make sure to only chown(2) files when the
+ owner or owning group does not match the current owner or owning group:
+ otherwise, if the caller does not have the appropriate privilege,
+ chown(2) will implicitly clear the suid and sgid flags.
+
+2.2.49
+* Fix attr/acl code for handling of recursive walking without following symlinks
+ Patch contributed by Brandon Philips <brandon@ifup.org>.
+ http://oss.sgi.com/archives/xfs/2008-07/msg00162.html
+
+2.2.48
+* Fix NULL pointer access / segmentation fault in setfacl.
+ When invoked as ``setfacl -- ...'', setfacl segfaults. Reported
+ by Peng Haitao; fix based on patches by Peng Haitao and Jiri
+ Moskovcak. Final fix from Andreas Gruenbacher <agruen@suse.de>.
+ Red Hat Bugzilla Bug 430458.
+
+2.2.47 (4 December 2007)
+* From Andreas Gruenbacher:
+ * fix issues for tree walking with file descriptors
+ - fd duplicates and running out
+
+2.2.46 (21 November 2007)
+* From Andreas Gruenbacher:
+ * Update acl.5 man page to clarify the relationship between
+ the file permissions and the *OBJ ACL entries.
+ * In some cases, gcc does not link in functions from libmisc.a
+ unless libmisc is specified before the dynamic libraries on
+ the command line.
+ * Rip out nftw tree walking, it is broken and hopeless to fix.
+ The replacement walk_tree() function does exactly what we
+ want, and is much simpler to use.
+
+2.2.45 (11 September 2007)
+* Fix symlink handling with getfacl and setfacl, thanks to Utako Usaka.
+
+2.2.44 (27 March 2007)
+* Add Spanish and Galician translation
+ (thanks to Antonio Trueba)
+
+2.2.43 (23 January 2007)
+* Fix a build issue with cross-compiling, thanks to Diego Petten�
+
+2.2.42 (08 December 2006)
+* Fix a build issue on GNU/kFreeBSD, thanks to Petr Salinger.
+
+2.2.41 (14 July 2006)
+* Fix issues with makedepend on libtool libraries.
+* Fix issues with install using named ids instead of numeric ones.
+
+2.2.40 (03 July 2006)
+* Update translation Makefile to work better with the Ubuntu
+ translation system. Thanks to feedback from Martin Pitt.
+* Fix annoying "ignores datarootdir" warning from configure.
+* Fix issues with makedepend build infrastructure.
+
+2.2.39 (06 June 2006)
+* Fix a segfault in getfacl/setfacl when handling non-existent
+ files, related to previos nftw-related workarounds. Thanks
+ to Daniel Kahn Gillmor for the fix.
+
+2.2.38 (23 May 2006)
+* Add Swedish translation from the debian localisation folks
+ (thanks to Daniel Nylander)
+
+2.2.37 (02 May 2006)
+* Fix handling of symbolic links in setfacl/getfacl, and resulting
+ nftw-related oddities.
+
+2.2.36 (28 March 2006)
+* Debian packaging updates (libc-dev dependency fixed)
+* Enable -O2 optimised builds by default
+
+2.2.35 (15 February 2006)
+* Debian packaging updates (debmake out, debhelper in)
+* Fix GNU/Hurd builds (no PATH_MAX macro)
+
+2.2.34 (05 December 2005)
+* Debian packaging updates
+
+2.2.33 (10 November 2005)
+* Sync up build system (m4 macros, etc) with other projects
+* Update SGI copyright/licence notices
+
+2.2.32 (29 September 2005)
+* Add French translation from the debian-l10n-french folks
+ (thanks to Sylvain Archenault)
+
+2.2.31 (11 March 2005)
+* Fix setfacl builds when compiling without gettext support
+ (thanks to vapier@gentoo.org).
+
+2.2.30 (21 February 2005)
+* Allocate the line buffer dynamically when reading from a file.
+* This mainly fixes restoring of large ACLs.
+
+2.2.29 (31 January 2005)
+* Replace use of _POSIX_PATH_MAX with the larger PATH_MAX
+ (thanks to Andree Leidenfrost).
+
+2.2.28 (30 November 2004)
+* Licensing fixes and clarifications.
+* Update outdated email addresses.
+
+2.2.27 (29 September 2004)
+* Update m4 macros, incorporating some portability changes.
+
+2.2.26 (8 September 2004)
+* Fix email address in manual pages.
+
+2.2.25 (25 August 2004)
+* Fix processing of the X pseudo permission in setfacl: Must not
+ modify the sequence of commands directly or else only the first
+ file is processed correctly, and X is not evaluated for any other
+ file. Add test case for X pseudo permission.
+* Remove support for relative permission changes; this non-standard
+ feature was disabled since a while already.
+
+2.2.24 (17 May 2004)
+* Update example source code.
+
+2.2.23 (02 February 2004)
+* Included Polish message translations by Jakub Bogusz.
+
+2.2.22 (06 January 2004)
+* Fix a permission bug in directory tree walking code.
+
+2.2.21 (10 November 2003)
+* Update Debian packaging conflict with Kerberos development package.
+
+2.2.20 (13 October 2003)
+* Fix build on the GNU/Hurd platform for some Debian folks.
+
+2.2.19 (07 October 2003)
+* Man page tweaks
+
+2.2.18 (30 September 2003)
+* Fix a documentation error in setfacl manual page, was refering to a
+ non-existent getfacl option in the example section.
+
+2.2.17 (29 August 2003)
+* Fix a bug in nftw worker routines' error handling code.
+
+2.2.16 (27 August 2003)
+* Fix issues in the libmisc quote routine (from Ben Escoto).
+
+2.2.15 (08 August 2003)
+* Somehow the SEGV fix from 2.2.14 got lost, reinstate it.
+
+2.2.14 (04 August 2003)
+* Fix chacl argument count checking in one or two places.
+* Fix libmisc quote/unquote routines so they handle NULL as input,
+ was causing some SEGV's inside libacl routines.
+
+2.2.13 (29 July 2003)
+* Add internal library for misc. functions: quote, unquote, high_water_alloc.
+* Quote special characters in path names and user names.
+* Fix examples/get-acl.c: Retrieving the default ACL of a plain file used
+ to result in an empty ACL, but fails now.
+* Update the test scripts.
+
+2.2.12 (03 July 2003)
+* Tweak the build so we don't always run msgmerge, fix from
+ Steve Langasek originally.
+
+2.2.11 (04 June 2003)
+* More Debian-specific packaging changes.
+
+2.2.10 (26 May 2003)
+* Some Debian-specific packaging changes.
+
+2.2.9 (26 April 2003)
+* Rework configure.in to make use of shared macros.
+
+2.2.8 (14 April 2003)
+* Fix configure tests that used AC_PATH_PROG incorrectly.
+* Minor cosmetic cleanups to configure.in.
+* Some dependency fixes to the Debian packaging.
+
+2.2.7 (27 March 2003)
+* Cleanups to the build process, in particular the automatic rpm
+ package generation Makefile and spec file template.
+* Makepkgs script can now propagate failures back up from make.
+* Change default --prefix to /usr.
+
+2.2.6 (26 February 2003)
+* Add symbol level versioning to libacl. This improves link time
+ consistency checks. The library versions are also honored by RPM, so
+ an RPM package built against say, libacl.so.1(ACL_1.1) won't link
+ against libacl.so.1(ACL_1.0), which was not checked before.
+* Added routines to libattr for copying extended attributes -
+ perm_copy_file and perm_copy_fd.
+* Increment the libacl version number, so that the presence of
+ those functions can be checked.
+
+2.2.5 (20 February 2003)
+* Merge symbol visibility patch from Andreas for hiding symbols
+ in libacl which we don't want exported, provided the compiler
+ supports that (added a new configure check too).
+
+2.2.4 (10 February 2003)
+* Merge several patches from Andreas - note that the library minor
+ version number has been incremented (libacl.so.1.0.3 -> 1.0.4)
+* A minor acl.5 update.
+* Fix memory leak in libacl (reported by
+ Leo Qiu <leoxqiu@yahoo.com> -- thanks!).
+* Preallocation of ACL entries in acl_init() to avoid calling
+ malloc() repeatedly.
+* Moved ACL entry reordering outside of loops to avoid O(n^2)
+ behavior (where n = #entries).
+* Fixed bug in acl_get_file() when the guessed number of entries
+ in a default ACL turned out to be too low (access ACL was used
+ instead).
+* Correct a signedness issue in getfacl's handling of uid/gid.
+
+2.2.3 (06 February 2003)
+* Fix order of library declarations in tools to allow linking when
+ only a static libattr library is available (mario@klebsch.de).
+
+2.2.2 (15 January 2003)
+* Add 'X' permission specification for setfacl(1) following
+ the same usage as chmod(1).
+
+2.2.1 (16 December 2002)
+* Clarify man page with respect to fileutils support.
+* Minor Debian build update to remove a shell script "bash-ism".
+
+2.2.0 (29 November 2002)
+* Complete the localisation/internationalisation support, including
+ the initial German translation by Andreas.
+
+2.1.1 (31 October 2002)
+* Minor updates to the Debian packaging.
+
+2.1.0 (19 October 2002)
+* Remove the -s and -S short options from setfacl, since it confuses
+ many users (--set and -set-file still exist).
+* Update the setfacl(1) manual page.
+* Improve the wording of some error messages, and update the pot/po
+ files. Also update the setfacl.test script.
+* Change the devel .rpm and .deb package names so that they now use
+ a "lib" prefix.
+* Several packaging changes related to this to ensure upgrades work
+ and depenency information isn't lost.
+
+2.0.19 (04 September 2002)
+* Correct the description of the access check algorithm in acl(5).
+* Add --numeric option to getfacl (so all uid's/gid's are displayed
+ numerically rather than by symbolic name). Also enlarge the static
+ buffer used for numeric identifiers from 12 to 22 characters, which
+ is enough for 64 bit id's.
+* Add a test case for setting just a base ACL.
+* Make the test/run script return a proper status code.
+* Check for ENOATTR and for ENODATA error numbers in places where
+ ENOATTR is expected, so if ENOATTR is assigned a separate number
+ we'll only need to rebuild.
+
+2.0.18 (21 August 2002)
+* Setfacl failed to parse ACLs with whitespace around user/group
+ names or ids (e.g., 'u: bin :rw', 'u: 0 :rwx').
+
+2.0.17 (12 August 2002)
+* Setfacl tried to retrieve the default ACL of regular files, which
+ resulted in errno = EACCES since 2.0.13, and broke setfacl's
+ --restore operation.
+
+2.0.16 (08 August 2002)
+* Fix an IA64 alignment issue affecting several libacl functions.
+* Updated libacl version number from libacl.so.1.0.2 to libacl.so.1.0.3
+
+2.0.15 (08 July 2002)
+* Fix configure warning (autoconf 2.13) - namely:
+ "AC_TRY_RUN called without default to allow cross compiling"
+* Fix a couple of typos in the documentation
+* Fix a Debian-specific build issue
+
+2.0.14 (04 July 2002)
+* Build infrastructure updates so that configure options can be used
+ to specify paths rather than semi-hard-coded path names controlled
+ by ROOT/ROOT_PREFIX env variables; eg. now allows /lib64 and /lib32.
+
+2.0.13 (25 June 2002)
+* Make acl_get_file() fail for regular files and type ACL_TYPE_DEFAULT,
+ as required by 1003.1e draft 17. Update manual page accordingly.
+* Make acl_set_file() fail for regular files and type ACL_TYPE_DEFAULT,
+ as required by 1003.1e draft 17. Update manual page accordingly.
+* Updated libacl version number from libacl.so.1.0.1 to libacl.so.1.0.2.
+* Updated chacl(1) command to behave correctly with this libacl change.
+
+2.0.12 (25 June 2002)
+* Increment the libacl version so that its possible for other packages
+ like Samba to easily tell which library version has the libacl build
+ bug fixed (without having to play configure games, etc).
+* In other words, libacl.so.1.0.0 is now libacl.so.1.0.1; nothing else
+ has changed in this release.
+
+2.0.11 (30 April 2002)
+* Fix a bug when reallocating space in __acl_to_any_text.c
+ (the bug causes ACL entries to get skipped!)
+* Minor clean-up in the test/setfacl.test script
+
+2.0.10 (22 April 2002)
+* Add accidentally removed dependency of libacl on libattr.
+
+2.0.9 (16 April 2002)
+* Fix a struct alignment issue in libacl on 64 bit platforms.
+
+2.0.8 (13 April 2002)
+* Fix a minor issue in build macro handling introduced in 2.0.7.
+
+2.0.7 (10 April 2002)
+* Fix a bug in the --tabular format of getfacl where user/group names
+ without a symbolic name did not get printed
+* Remove setfacl/user_group.[ch] as these are no longer used
+* Added configure check for libattr -- uses libtool archive if found
+
+2.0.6 (08 April 2002)
+* Fix a bug that causes setfacl not to report error messages if
+ acl_set_file() fails (the bug was introduced in version 2.0.3).
+
+2.0.5 (26 March 2002)
+* Fix up acl_to_text compliance with POSIX draft.
+* Add the new acl(5) manual page.
+* Add a manual section 3 directory and Makefile.
+* Add the libacl manual pages.
+* Rename the existing acl_to_any_text function to __acl_to_any_text, and
+ add a new acl_to_any_text function that only contains parameters that
+ are actually useful. Make acl_to_text and acl_to_any_text invoke
+ __acl_to_any_text internally. Update all uses of acl_to_any_text in
+ getfacl/getfacl.c, setfacl/do_set.c, and chacl/chacl.c.
+* Move the acl_size function form the LIBACL_CFILES to the POSIX_CFILES
+ section (it is a POSIX function)
+* Rearrange libacl routines so that several non-POSIX routines which
+ were being exported are no longer exported (eg. acl_entry_to_any_str,
+ acl_get_file_mode, acl_get_fd_mode, acl_set_file_mode, acl_set_fd_mode).
+
+2.0.4 (12 March 2002)
+* Man page updates from Andreas
+* Test script updates from Andreas
+
+2.0.3 (05 March 2002)
+* Clean up the --default option handling in setfacl. The old
+ workarounds caused a bug for unusual input.
+* Changes to the --test output format setfacl generates: ACLs that
+ are not changed are now displayed as `*'.
+* Fix a bug in setfacl/sequence.c:seq_delete_cmd().
+* Minor changes to test scripts
+
+2.0.2 (01 March 2002)
+* Apply several patches from Andreas, namely:
+* man page fixes
+* libacl code reformatting
+* acl_from_text errno handling
+
+2.0.1 (27 February 2002)
+* Apply Andreas Gruenbacher's diffs.
+* Fix up chacl for deletion of access ACL to be in line with Andreas.
+* Incorporate the Debian packaging again.
+
+2.0.0 (21 February 2002)
+* Reworked to use the new official system call API.
+* Sync up with the XFS project, the SGI folk now use this source.
+* Jumped to version 2 to allow XFS users to upgrade
+ (Rationale: the XFS ACL user tools were at version 1.1.X, and
+ packaging tools like rpm, dpkg, etc. must be presented with a
+ greater version number to allow an upgrade to proceed).
+* Added the chacl command to ease migration for existing XFS users,
+ and for compatibility with IRIX.
+* Added a flag to allow acl_print to produce a single-line ACL, in
+ addition to the multi-line format.
+* Extended attribute documentation has moved into the extended
+ attribute package from SGI ("attr"), this ACL package now deals
+ exclusively with ACLs.
+* acl_from_text sometimes did not set errno when failing.
+* Moved files and simplified #includes in libacl
+
+0.7.22
+* Create a shared version of libacl, instead of linking statically.
+* Added missing error reporting to getfacl do_print() function.
+
+0.7.16
+* Minor cleanups/fixes in the make files
+* The test cases in test/src have been updated to match the
+ corrected ACL entry syntax (see the 0.7.15 changes).
+
+0.7.15
+* acl_from_text() now accepts mask and other entries with either two
+ or three fields (`other:rwx' or `other::rwx'). Posix 1003.1e specifies
+ that these entries should have three entries, while under Solaris,
+ they have only two fields.
+* setfacl now parses mask and other entries with two or three entries.
+* getfacl now produces mask and other entries with three fields
+ (`mask::rwx' instead of the previous `mask:rwx').
+* acl_get_fd(), acl_get_file(), acl_set_fd(), acl_set_file() now only
+ fail with errno=ENOSYS if the underlying filesystem doesn't support
+ ACLs. acl_get_fd() and acl_get_file() construct ACLs from the file
+ mode permission bits if the kernel supports ACLs, but no ACL extended
+ attributes are defined for the file (errno=ENOATTR).
+* acl_to_text() wrongly separated ACL entires with ',' instead of '\n'.
+* acl_from_text() only accepted three-letter permission strings
+ (rwx, ---, rw-, etc.). Now also short strings (rw, -, etc.) are
+ supported.
+
+0.7.10
+* acl_get_fd(), acl_get_file() now don't return basic ACL's anymore.
+* acl_set_fd(), acl_set_file() fail on filesystems that don't support
+ ACLs, even if the ACL to be set is a basice ACL.
+* If msgfmt is not present on a system, the message catalog(s) are
+ no longer being built.
+
+0.7.8 (19 February 2001)
+* Buffer overflow bug in ACL library (acl_to_any_text).
+ (Reported by Charles Bertsch <CBertsch@microtest.com>)
+
+0.7.2 (22 November 2000)
+* Replace rman with groff for building HTML versions of the
+ manual pages.
+* Add descriptions of the permissions required for manipulating
+ ACLs to the manual pages.
+* Add long options to getfacl and setfacl, update the manual pages.
+* Remove some small bugs from the src/showacl Perl script.
+* showacl is now integrated in getfacl.
+* Bug in acl_to_any_text() for ACLs with 0 entries fixed.
+* Bug in acl_to_text(): Used '\n' as the ACL entry separator.
+* German messages updated.
+
+0.7.1 (23 October 2000)
+* Basic GNU gettext support and a German translation of messages
+ added.
+
+0.7.0 (22 October 2000)
+* Updates to the documentation
+* Now an ACL_MASK entry is cloned from the ACL_GROUP_OBJ entry
+ when needed also when the ACL_MASK entry is not re-calculated
+ (-n option), so setfacl doesn't complain about an invalid ACL.
+
+0.6.8 (11 October 2000)
+* src/walk_tree.c was stat()ing the targets of symbolic links in
+ WALK_PHYSICAL mode.
+* Removed spurious definitions from src/gettext.h that caused
+ problems with several versions of GNU gettext headers
+* setfacl calls acl_delete_def_file() if removing the default ACL
+ of a directory that doesn't have a default ACL. i(If the user lacks
+ appropriate permissions, that no-operation fails.) Fixed.
+* Tiny bug in src/showacl script (mask entry not applied to owning
+ group entry)
+
+0.6.5 (10 September 2000)
+* Command line options revised for POSIX compatibility (now defaults to
+ -H half-logical walk, added -L logical walk, -P physical walk).
+* Funny post-order option no longer documented.
+
+0.6.0 (24 March 2000)
+* Permissions were not set to the union of the ACL_GROUP_OBJ and
+ ACL_MASK_OBJ entries for `setfacl -b'.
+* getfacl didn't display the default ACL for links do directories.
+
+0.5.6 (31 Jan 2000)
+* Cleaned up the ACL entry ring handling in the library
+* Fixed a few minor issues with setfacl
+* Fixed a bug in acl_equiv_mode
+* Added acl_{get,set}_{file,fd}_mode functions
+
+0.5.5 (19 October 1999)
+* Updates to the documentation
+* Some other things (?)
+
+0.5.4 (up to 14 October 1999)
+* Fixed an incompatibility with more recent GNU getopt
+* Fixed a problem with errno handling in lib/text.c
+* Some cosmetic changes to streamline the distribution process
+* setfacl now implies `user:' if neither of `user', `group:',
+ `other:' and `mask:' is given. Was a major annoyance (to me).
+* errno not set when acl_read was presented with an empty file.
+* some missing '\n' chars in setfacl
+
+0.5.3
+* Fixed a bug in setfacl.c that caused the default mask to
+ be recalculated wrong.
+* Fixed a bug in acl_kernel.c:acl_check_one() that caused
+ invalid ACLs to be accepted
+
+0.5.2 (25 September 1999)
+* Added doc/Implementation.txt (some internals and ideas)
+* Fixed a bug in lib/manip.c that caused setfacl to reject
+ some valid ACLs
+* Fixed a bug that caused setfacl to produce duplicate ACL
+ entries
+* Fixed a bug/feature that caused `sefacl -s' to include the
+ current base ACL entries in results. This is not done with
+ `setfacl -bm'.
diff --git a/doc/COPYING b/doc/COPYING
new file mode 100644
index 0000000..af9ceab
--- /dev/null
+++ b/doc/COPYING
@@ -0,0 +1,347 @@
+Most components of the "acl" package are licensed under
+Version 2.1 of the GNU Lesser General Public License (see COPYING.LGPL).
+
+Some components (as annotated in the source) are licensed
+under Version 2 of the GNU General Public License (see below),
+
+----------------------------------------------------------------------
+
+ GNU GENERAL PUBLIC LICENSE
+ Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users. This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it. (Some other Free Software Foundation software is covered by
+the GNU Lesser General Public License instead.) You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+ To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have. You must make sure that they, too, receive or can get the
+source code. And you must show them these terms so they know their
+rights.
+
+ We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+ Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software. If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+ Finally, any free program is threatened constantly by software
+patents. We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary. To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ GNU GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License. The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language. (Hereinafter, translation is included without limitation in
+the term "modification".) Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+ 1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+ 2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) You must cause the modified files to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ b) You must cause any work that you distribute or publish, that in
+ whole or in part contains or is derived from the Program or any
+ part thereof, to be licensed as a whole at no charge to all third
+ parties under the terms of this License.
+
+ c) If the modified program normally reads commands interactively
+ when run, you must cause it, when started running for such
+ interactive use in the most ordinary way, to print or display an
+ announcement including an appropriate copyright notice and a
+ notice that there is no warranty (or else, saying that you provide
+ a warranty) and that users may redistribute the program under
+ these conditions, and telling the user how to view a copy of this
+ License. (Exception: if the Program itself is interactive but
+ does not normally print such an announcement, your work based on
+ the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+ a) Accompany it with the complete corresponding machine-readable
+ source code, which must be distributed under the terms of Sections
+ 1 and 2 above on a medium customarily used for software interchange; or,
+
+ b) Accompany it with a written offer, valid for at least three
+ years, to give any third party, for a charge no more than your
+ cost of physically performing source distribution, a complete
+ machine-readable copy of the corresponding source code, to be
+ distributed under the terms of Sections 1 and 2 above on a medium
+ customarily used for software interchange; or,
+
+ c) Accompany it with the information you received as to the offer
+ to distribute corresponding source code. (This alternative is
+ allowed only for noncommercial distribution and only if you
+ received the program in object code or executable form with such
+ an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it. For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable. However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License. Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+ 5. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Program or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+ 6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+ 7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all. For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded. In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+ 9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation. If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+ 10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission. For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this. Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+ NO WARRANTY
+
+ 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+ 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the program's name and a brief idea of what it does.>
+ Copyright (C) <year> <name of author>
+
+ 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 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, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+ Gnomovision version 69, Copyright (C) year name of author
+ Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+ `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+ <signature of Ty Coon>, 1 April 1989
+ Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs. If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library. If this is what you want to do, use the GNU Lesser General
+Public License instead of this License.
diff --git a/doc/COPYING.LGPL b/doc/COPYING.LGPL
new file mode 100644
index 0000000..74586da
--- /dev/null
+++ b/doc/COPYING.LGPL
@@ -0,0 +1,513 @@
+Most components of the "acl" package are licensed under
+Version 2.1 of the GNU Lesser General Public License (see below).
+below.
+
+Some components (as annotated in the source) are licensed
+under Version 2 of the GNU General Public License (see COPYING).
+
+----------------------------------------------------------------------
+
+ GNU LESSER GENERAL PUBLIC LICENSE
+ Version 2.1, February 1999
+
+ Copyright (C) 1991, 1999 Free Software Foundation, Inc.
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+[This is the first released version of the Lesser GPL. It also counts
+ as the successor of the GNU Library Public License, version 2, hence
+ the version number 2.1.]
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+Licenses are intended to guarantee your freedom to share and change
+free software--to make sure the software is free for all its users.
+
+ This license, the Lesser General Public License, applies to some
+specially designated software packages--typically libraries--of the
+Free Software Foundation and other authors who decide to use it. You
+can use it too, but we suggest you first think carefully about whether
+this license or the ordinary General Public License is the better
+strategy to use in any particular case, based on the explanations below.
+
+ When we speak of free software, we are referring to freedom of use,
+not price. Our General Public Licenses are designed to make sure that
+you have the freedom to distribute copies of free software (and charge
+for this service if you wish); that you receive source code or can get
+it if you want it; that you can change the software and use pieces of
+it in new free programs; and that you are informed that you can do
+these things.
+
+ To protect your rights, we need to make restrictions that forbid
+distributors to deny you these rights or to ask you to surrender these
+rights. These restrictions translate to certain responsibilities for
+you if you distribute copies of the library or if you modify it.
+
+ For example, if you distribute copies of the library, whether gratis
+or for a fee, you must give the recipients all the rights that we gave
+you. You must make sure that they, too, receive or can get the source
+code. If you link other code with the library, you must provide
+complete object files to the recipients, so that they can relink them
+with the library after making changes to the library and recompiling
+it. And you must show them these terms so they know their rights.
+
+ We protect your rights with a two-step method: (1) we copyright the
+library, and (2) we offer you this license, which gives you legal
+permission to copy, distribute and/or modify the library.
+
+ To protect each distributor, we want to make it very clear that
+there is no warranty for the free library. Also, if the library is
+modified by someone else and passed on, the recipients should know
+that what they have is not the original version, so that the original
+author's reputation will not be affected by problems that might be
+introduced by others.
+
+ Finally, software patents pose a constant threat to the existence of
+any free program. We wish to make sure that a company cannot
+effectively restrict the users of a free program by obtaining a
+restrictive license from a patent holder. Therefore, we insist that
+any patent license obtained for a version of the library must be
+consistent with the full freedom of use specified in this license.
+
+ Most GNU software, including some libraries, is covered by the
+ordinary GNU General Public License. This license, the GNU Lesser
+General Public License, applies to certain designated libraries, and
+is quite different from the ordinary General Public License. We use
+this license for certain libraries in order to permit linking those
+libraries into non-free programs.
+
+ When a program is linked with a library, whether statically or using
+a shared library, the combination of the two is legally speaking a
+combined work, a derivative of the original library. The ordinary
+General Public License therefore permits such linking only if the
+entire combination fits its criteria of freedom. The Lesser General
+Public License permits more lax criteria for linking other code with
+the library.
+
+ We call this license the "Lesser" General Public License because it
+does Less to protect the user's freedom than the ordinary General
+Public License. It also provides other free software developers Less
+of an advantage over competing non-free programs. These disadvantages
+are the reason we use the ordinary General Public License for many
+libraries. However, the Lesser license provides advantages in certain
+special circumstances.
+
+ For example, on rare occasions, there may be a special need to
+encourage the widest possible use of a certain library, so that it becomes
+a de-facto standard. To achieve this, non-free programs must be
+allowed to use the library. A more frequent case is that a free
+library does the same job as widely used non-free libraries. In this
+case, there is little to gain by limiting the free library to free
+software only, so we use the Lesser General Public License.
+
+ In other cases, permission to use a particular library in non-free
+programs enables a greater number of people to use a large body of
+free software. For example, permission to use the GNU C Library in
+non-free programs enables many more people to use the whole GNU
+operating system, as well as its variant, the GNU/Linux operating
+system.
+
+ Although the Lesser General Public License is Less protective of the
+users' freedom, it does ensure that the user of a program that is
+linked with the Library has the freedom and the wherewithal to run
+that program using a modified version of the Library.
+
+ The precise terms and conditions for copying, distribution and
+modification follow. Pay close attention to the difference between a
+"work based on the library" and a "work that uses the library". The
+former contains code derived from the library, whereas the latter must
+be combined with the library in order to run.
+
+ GNU LESSER GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License Agreement applies to any software library or other
+program which contains a notice placed by the copyright holder or
+other authorized party saying it may be distributed under the terms of
+this Lesser General Public License (also called "this License").
+Each licensee is addressed as "you".
+
+ A "library" means a collection of software functions and/or data
+prepared so as to be conveniently linked with application programs
+(which use some of those functions and data) to form executables.
+
+ The "Library", below, refers to any such software library or work
+which has been distributed under these terms. A "work based on the
+Library" means either the Library or any derivative work under
+copyright law: that is to say, a work containing the Library or a
+portion of it, either verbatim or with modifications and/or translated
+straightforwardly into another language. (Hereinafter, translation is
+included without limitation in the term "modification".)
+
+ "Source code" for a work means the preferred form of the work for
+making modifications to it. For a library, complete source code means
+all the source code for all modules it contains, plus any associated
+interface definition files, plus the scripts used to control compilation
+and installation of the library.
+
+ Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running a program using the Library is not restricted, and output from
+such a program is covered only if its contents constitute a work based
+on the Library (independent of the use of the Library in a tool for
+writing it). Whether that is true depends on what the Library does
+and what the program that uses the Library does.
+
+ 1. You may copy and distribute verbatim copies of the Library's
+complete source code as you receive it, in any medium, provided that
+you conspicuously and appropriately publish on each copy an
+appropriate copyright notice and disclaimer of warranty; keep intact
+all the notices that refer to this License and to the absence of any
+warranty; and distribute a copy of this License along with the
+Library.
+
+ You may charge a fee for the physical act of transferring a copy,
+and you may at your option offer warranty protection in exchange for a
+fee.
+
+ 2. You may modify your copy or copies of the Library or any portion
+of it, thus forming a work based on the Library, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) The modified work must itself be a software library.
+
+ b) You must cause the files modified to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ c) You must cause the whole of the work to be licensed at no
+ charge to all third parties under the terms of this License.
+
+ d) If a facility in the modified Library refers to a function or a
+ table of data to be supplied by an application program that uses
+ the facility, other than as an argument passed when the facility
+ is invoked, then you must make a good faith effort to ensure that,
+ in the event an application does not supply such function or
+ table, the facility still operates, and performs whatever part of
+ its purpose remains meaningful.
+
+ (For example, a function in a library to compute square roots has
+ a purpose that is entirely well-defined independent of the
+ application. Therefore, Subsection 2d requires that any
+ application-supplied function or table used by this function must
+ be optional: if the application does not supply it, the square
+ root function must still compute square roots.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Library,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Library, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote
+it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Library.
+
+In addition, mere aggregation of another work not based on the Library
+with the Library (or with a work based on the Library) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may opt to apply the terms of the ordinary GNU General Public
+License instead of this License to a given copy of the Library. To do
+this, you must alter all the notices that refer to this License, so
+that they refer to the ordinary GNU General Public License, version 2,
+instead of to this License. (If a newer version than version 2 of the
+ordinary GNU General Public License has appeared, then you can specify
+that version instead if you wish.) Do not make any other change in
+these notices.
+
+ Once this change is made in a given copy, it is irreversible for
+that copy, so the ordinary GNU General Public License applies to all
+subsequent copies and derivative works made from that copy.
+
+ This option is useful when you wish to copy part of the code of
+the Library into a program that is not a library.
+
+ 4. You may copy and distribute the Library (or a portion or
+derivative of it, under Section 2) in object code or executable form
+under the terms of Sections 1 and 2 above provided that you accompany
+it with the complete corresponding machine-readable source code, which
+must be distributed under the terms of Sections 1 and 2 above on a
+medium customarily used for software interchange.
+
+ If distribution of object code is made by offering access to copy
+from a designated place, then offering equivalent access to copy the
+source code from the same place satisfies the requirement to
+distribute the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 5. A program that contains no derivative of any portion of the
+Library, but is designed to work with the Library by being compiled or
+linked with it, is called a "work that uses the Library". Such a
+work, in isolation, is not a derivative work of the Library, and
+therefore falls outside the scope of this License.
+
+ However, linking a "work that uses the Library" with the Library
+creates an executable that is a derivative of the Library (because it
+contains portions of the Library), rather than a "work that uses the
+library". The executable is therefore covered by this License.
+Section 6 states terms for distribution of such executables.
+
+ When a "work that uses the Library" uses material from a header file
+that is part of the Library, the object code for the work may be a
+derivative work of the Library even though the source code is not.
+Whether this is true is especially significant if the work can be
+linked without the Library, or if the work is itself a library. The
+threshold for this to be true is not precisely defined by law.
+
+ If such an object file uses only numerical parameters, data
+structure layouts and accessors, and small macros and small inline
+functions (ten lines or less in length), then the use of the object
+file is unrestricted, regardless of whether it is legally a derivative
+work. (Executables containing this object code plus portions of the
+Library will still fall under Section 6.)
+
+ Otherwise, if the work is a derivative of the Library, you may
+distribute the object code for the work under the terms of Section 6.
+Any executables containing that work also fall under Section 6,
+whether or not they are linked directly with the Library itself.
+
+ 6. As an exception to the Sections above, you may also combine or
+link a "work that uses the Library" with the Library to produce a
+work containing portions of the Library, and distribute that work
+under terms of your choice, provided that the terms permit
+modification of the work for the customer's own use and reverse
+engineering for debugging such modifications.
+
+ You must give prominent notice with each copy of the work that the
+Library is used in it and that the Library and its use are covered by
+this License. You must supply a copy of this License. If the work
+during execution displays copyright notices, you must include the
+copyright notice for the Library among them, as well as a reference
+directing the user to the copy of this License. Also, you must do one
+of these things:
+
+ a) Accompany the work with the complete corresponding
+ machine-readable source code for the Library including whatever
+ changes were used in the work (which must be distributed under
+ Sections 1 and 2 above); and, if the work is an executable linked
+ with the Library, with the complete machine-readable "work that
+ uses the Library", as object code and/or source code, so that the
+ user can modify the Library and then relink to produce a modified
+ executable containing the modified Library. (It is understood
+ that the user who changes the contents of definitions files in the
+ Library will not necessarily be able to recompile the application
+ to use the modified definitions.)
+
+ b) Use a suitable shared library mechanism for linking with the
+ Library. A suitable mechanism is one that (1) uses at run time a
+ copy of the library already present on the user's computer system,
+ rather than copying library functions into the executable, and (2)
+ will operate properly with a modified version of the library, if
+ the user installs one, as long as the modified version is
+ interface-compatible with the version that the work was made with.
+
+ c) Accompany the work with a written offer, valid for at
+ least three years, to give the same user the materials
+ specified in Subsection 6a, above, for a charge no more
+ than the cost of performing this distribution.
+
+ d) If distribution of the work is made by offering access to copy
+ from a designated place, offer equivalent access to copy the above
+ specified materials from the same place.
+
+ e) Verify that the user has already received a copy of these
+ materials or that you have already sent this user a copy.
+
+ For an executable, the required form of the "work that uses the
+Library" must include any data and utility programs needed for
+reproducing the executable from it. However, as a special exception,
+the materials to be distributed need not include anything that is
+normally distributed (in either source or binary form) with the major
+components (compiler, kernel, and so on) of the operating system on
+which the executable runs, unless that component itself accompanies
+the executable.
+
+ It may happen that this requirement contradicts the license
+restrictions of other proprietary libraries that do not normally
+accompany the operating system. Such a contradiction means you cannot
+use both them and the Library together in an executable that you
+distribute.
+
+ 7. You may place library facilities that are a work based on the
+Library side-by-side in a single library together with other library
+facilities not covered by this License, and distribute such a combined
+library, provided that the separate distribution of the work based on
+the Library and of the other library facilities is otherwise
+permitted, and provided that you do these two things:
+
+ a) Accompany the combined library with a copy of the same work
+ based on the Library, uncombined with any other library
+ facilities. This must be distributed under the terms of the
+ Sections above.
+
+ b) Give prominent notice with the combined library of the fact
+ that part of it is a work based on the Library, and explaining
+ where to find the accompanying uncombined form of the same work.
+
+ 8. You may not copy, modify, sublicense, link with, or distribute
+the Library except as expressly provided under this License. Any
+attempt otherwise to copy, modify, sublicense, link with, or
+distribute the Library is void, and will automatically terminate your
+rights under this License. However, parties who have received copies,
+or rights, from you under this License will not have their licenses
+terminated so long as such parties remain in full compliance.
+
+ 9. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Library or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Library (or any work based on the
+Library), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Library or works based on it.
+
+ 10. Each time you redistribute the Library (or any work based on the
+Library), the recipient automatically receives a license from the
+original licensor to copy, distribute, link with or modify the Library
+subject to these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties with
+this License.
+
+ 11. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Library at all. For example, if a patent
+license would not permit royalty-free redistribution of the Library by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Library.
+
+If any portion of this section is held invalid or unenforceable under any
+particular circumstance, the balance of the section is intended to apply,
+and the section as a whole is intended to apply in other circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 12. If the distribution and/or use of the Library is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Library under this License may add
+an explicit geographical distribution limitation excluding those countries,
+so that distribution is permitted only in or among countries not thus
+excluded. In such case, this License incorporates the limitation as if
+written in the body of this License.
+
+ 13. The Free Software Foundation may publish revised and/or new
+versions of the Lesser General Public License from time to time.
+Such new versions will be similar in spirit to the present version,
+but may differ in detail to address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Library
+specifies a version number of this License which applies to it and
+"any later version", you have the option of following the terms and
+conditions either of that version or of any later version published by
+the Free Software Foundation. If the Library does not specify a
+license version number, you may choose any version ever published by
+the Free Software Foundation.
+
+ 14. If you wish to incorporate parts of the Library into other free
+programs whose distribution conditions are incompatible with these,
+write to the author to ask for permission. For software which is
+copyrighted by the Free Software Foundation, write to the Free
+Software Foundation; we sometimes make exceptions for this. Our
+decision will be guided by the two goals of preserving the free status
+of all derivatives of our free software and of promoting the sharing
+and reuse of software generally.
+
+ NO WARRANTY
+
+ 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
+WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
+EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
+OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
+KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
+LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
+THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+ 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
+WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
+AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
+FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
+CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
+LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
+RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
+FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
+SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Libraries
+
+ If you develop a new library, and you want it to be of the greatest
+possible use to the public, we recommend making it free software that
+everyone can redistribute and change. You can do so by permitting
+redistribution under these terms (or, alternatively, under the terms of the
+ordinary General Public License).
+
+ To apply these terms, attach the following notices to the library. It is
+safest to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least the
+"copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the library's name and a brief idea of what it does.>
+ Copyright (C) <year> <name of author>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+Also add information on how to contact you by electronic and paper mail.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the library, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the
+ library `Frob' (a library for tweaking knobs) written by James Random Hacker.
+
+ <signature of Ty Coon>, 1 April 1990
+ Ty Coon, President of Vice
+
+That's all there is to it!
+
+
diff --git a/doc/INSTALL b/doc/INSTALL
new file mode 100644
index 0000000..de99605
--- /dev/null
+++ b/doc/INSTALL
@@ -0,0 +1,48 @@
+This document describes how to configure and build the extended
+attribute library and utility from source, and how to install them.
+
+0. If you have the binary rpm, simply install it and skip to step 2 (below).
+ The rpm command to do this is:
+ # rpm -Uvh acl
+
+ The Debian command to do this is:
+ # dpkg -i acl
+ or, if you have apt configured (don't need the binary package):
+ # apt-get install acl
+
+1. Configure, build and install the package
+
+ The "acl" package uses autoconf/configure and expects a GNU build
+ environment (your platform must at least have both autoconf and gmake).
+
+ If you just want to spin an RPM and/or tar file, use the Makepkgs
+ script in the top level directory. This will configure and build
+ the package and leave binary and src RPMs in the build/rpm
+ directory. It will also leave a tar file in the build/tar
+ directory.
+
+ # ./Makepkgs verbose
+
+ If you want to build the package and install it manually, use the
+ following steps:
+
+ # make configure (or run autoconf; ./configure)
+ # make
+ # su root
+ # make install install-lib
+
+ Note that there are so many "install" variants out there that we
+ wrote our own script (see "install-sh" in the top level directory).
+
+ If you wish to turn off debugging asserts in the command build and
+ turn on the optimizer then set the shell environment variables:
+
+ OPTIMIZER=-O
+ DEBUG=-DNDEBUG
+
+ before running make configure or Makepkgs.
+
+2. How to Contribute
+
+ See the README file in this directory for details about how to
+ contribute to the Linux access control lists project.
diff --git a/doc/Makefile b/doc/Makefile
new file mode 100644
index 0000000..a08e403
--- /dev/null
+++ b/doc/Makefile
@@ -0,0 +1,42 @@
+#
+# Copyright (c) 2000-2002 Silicon Graphics, Inc. All Rights Reserved.
+#
+# 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 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, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+
+TOPDIR = ..
+include $(TOPDIR)/include/builddefs
+
+LSRCFILES = extensions.txt libacl.txt TODO PORTING CHANGES COPYING COPYING.LGPL INSTALL \
+ old-acl.5
+LDIRT = *.gz
+
+default: CHANGES.gz
+
+include $(BUILDRULES)
+
+CHANGES.gz:
+ $(ZIP) --best -c < CHANGES > $@
+
+install: default
+ $(INSTALL) -m 755 -d $(PKG_DOC_DIR)
+ $(INSTALL) -m 644 PORTING CHANGES.gz $(PKG_DOC_DIR)
+ifeq ($(PKG_DISTRIBUTION), debian)
+ $(INSTALL) -S CHANGES.gz $(PKG_DOC_DIR)/changelog.gz
+else
+ $(INSTALL) -m 644 COPYING COPYING.LGPL $(PKG_DOC_DIR)
+endif
+
+install-dev install-lib:
diff --git a/doc/PORTING b/doc/PORTING
new file mode 100644
index 0000000..f395b7a
--- /dev/null
+++ b/doc/PORTING
@@ -0,0 +1,86 @@
+
+1. unpack the source tarball and cd to the resulting dir
+
+2. # autoconf
+ this reads configure.in and generates the ./configure script
+
+3. # ./configure
+ this probes your system and then, for each "file" named
+ in the AC_OUTPUT() macro near the end of configure.in,
+ read "file".in and generate "file". Variables named @somevariable@
+ will be substituted with literal values.
+
+4. step (3) produces several files. These files are generated by
+ configure from their respective .in file in the same directory.
+ You should have a read of these generated files and diff them
+ against their respective .in files to see what was substituted
+ by configure.
+
+ src/include/builddefs
+ common definitions for the build environment. This is included
+ by all Makefiles, in conjunction with src/include/buildrules.
+ Note that most autoconf/configure build environments generate
+ Makefile (from Makefile.in) in every src dir. Instead, we
+ generate builddefs, and then include it in every Makefile.
+
+ src/include/platform_defs.h
+ header containing conditional macros defining the C run-time
+ environment discovered by the configure script.
+
+5. read some or all of the GNU tool chain documentation
+ GNU make :
+ http://www.delorie.com/gnu/docs/make/make_toc.html
+ autoconf :
+ http://www.delorie.com/gnu/docs/autoconf/autoconf_toc.html
+ libtool :
+ http://www.delorie.com/gnu/docs/libtool/libtool_toc.html
+ gcc/g++ :
+ http://www.delorie.com/gnu/docs/gcc/gcc_toc.html
+
+6. Makefiles and build environment
+ First have a look at some Makefiles
+
+ example using SUBDIRS : acl/Makefile
+ example static library: acl/libacl/Makefile
+ example command : acl/getfacl/Makefile
+
+ All Makefiles must define TOPDIR as the root of the project. This
+ allows other stuff to be found relative to $(TOPDIR).
+
+ All Makefiles should have the following structure, which is
+ much like commondefs and commonrules in the IRIX build environment, e.g.
+
+ # ----------------------------------------------------------------------
+ # TOPDIR must point to the root of the project
+ # The builddefs file defines lots of things. Read it.
+ TOPDIR = ..
+ include $(TOPDIR)/include/builddefs
+
+ # first rule should always be "default"
+ default : sometarget
+ commands to build targets, if necessary
+
+ # $(BUILDRULES) is defined in builddefs and includes rules for
+ # descending subdirs, building targets and installation rules
+ include $(BUILDRULES)
+
+ install : default
+ $(INSTALL) sometargets somewhere
+ # ----------------------------------------------------------------------
+
+7. packaging
+
+ # ./Makepkgs
+ this script generates all of the packages supported - each has a
+ subdirectory below acl/build where knowledge specific to each
+ package type is maintained.
+
+ The script produces logs of each stage of the build (this info is
+ also echoed to the screen when the "verbose" option is provided):
+
+ acl/Logs/configure - `autoconf; ./configure' output
+ acl/Logs/default - `make default' output
+ acl/Logs/dist - `make build dist' output
+
+ On successful completion, the script echoes the names of packages
+ successfully generated.
diff --git a/doc/TODO b/doc/TODO
new file mode 100644
index 0000000..9c23d69
--- /dev/null
+++ b/doc/TODO
@@ -0,0 +1,4 @@
+- include po (gettext stuff) in packages and build process
+- fix build process
+- check documentation
+- add manual pages for POSIX functions
diff --git a/doc/extensions.txt b/doc/extensions.txt
new file mode 100644
index 0000000..5455bbc
--- /dev/null
+++ b/doc/extensions.txt
@@ -0,0 +1,77 @@
+The Posix ACL user library
+==========================
+
+The Posix ACL manipulation functions defined in Posix 1003.1e DS17 are
+declared in <sys/acl.h>; you need to link against libacl.a for these
+functions to be included in your binaries.
+
+There is an additional header file <acl/libacl.h> that gives you
+access to some extensions that are also contained in the same library.
+The functions declared there are:
+
+acl_to_any_text()
+
+ Similar to acl_to_text(), but also allows you to specify:
+ - a prefix string that is printed before each ACL entry.
+ - a seperator character that is printed between two ACL entries.
+ - a set of options (TEXT_* constants).
+
+ This function returns the length in characters of the text returned
+ in the len_p parameter, unless len_p is NULL. The returned string
+ must be freed using the acl_free() function.
+
+ Returns NULL and sets errno accordingly on error.
+
+acl_entry_to_any_str()
+
+ Converts a single ACL entry to text, filling a buffer. It takes as
+ additional parameter the ACL mask entry (which is used to computer
+ the effective permissions if specified). The prefix and options are
+ the same as for acl_to_any_text().
+
+ Returns -1 and sets errno accordingly on error.
+
+acl_cmp()
+
+ Returns 0 if both ACLs are equal, and 1 otherwise.
+
+ Returns -1 and sets errno accordingly on error.
+
+acl_check()
+
+ Checks an ACL for validity, similar to acl_valid. Returns the entry
+ at which an error occurred in last (unless last is NULL), and
+ returns a positive error code (ACL_*_ERROR) if the ACL is invalid; 0
+ on success.
+
+ Returns -1 and sets errno accordingly on error.
+
+acl_equiv_mode()
+
+ Checks if an ACL is a basic ACL. If so, returns 0 and sets mode_p to
+ the file mode permission bits that correspond to the ACL. Returns 1
+ otherwise.
+
+ Returns -1 and sets errno accordingly on error.
+
+acl_entries()
+
+ Returns the number of entries in an ACL.
+
+ Returns -1 and sets errno accordingly on error.
+
+acl_error()
+
+ Returns a textual message describing the error code returned by
+ acl_check().
+
+acl_get_perm()
+
+ Check if a permission is set in a permission set (acl_permset_t).
+
+ Returns 1 if the permission is set, or 0 if it is not set.
+ Returns -1 and sets errno if an error occurs.
+
+
+Andreas
+
diff --git a/doc/libacl.txt b/doc/libacl.txt
new file mode 100644
index 0000000..bd5ef56
--- /dev/null
+++ b/doc/libacl.txt
@@ -0,0 +1,73 @@
+Internals of the libacl library
+===============================
+
+Posix 1003.1e DS17 leaves the library developer relatively few choices
+on how to implement the library. A pseudo object oriented approach
+seems necessary (otherwise, not all of the requirements can be met).
+Unfortunately, C is no object oriented language, so the classes etc.
+need to be hand coded. Here is how it works.
+
+From the user's point of view, the following things are objects:
+
+ F - acl_t objects
+ - acl_entry_t objects
+ - acl_permset_t objects
+ F - strings returned by acl_to_text
+ F - entities returned by acl_get_qualifier
+
+The objects flagged with F need to be freed with acl_free() when they
+are no longer needed.
+
+The user gets pointers to the contents of these objects. Each object
+also has a prefix, which is not accessible from the user. The complete
+objects are declared in <lib/libacl.h>. The p_magic field of the
+prefix is set to <object_name>_MAGIC.
+
+The macros ext2int() and int2ext() convert between the internal and
+external view on objects. The macros new_obj_p() and new_var_obj_p()
+create a new object and object with variable size, respectively. See
+the code for the rest.
+
+The code necessary to access fields in objects, especially in objects
+accessed through indirections, would get almost unreadable. The second
+ACL entry of an ACL would be:
+
+ acl_obj *acl_p;
+ acl_entry_obj *acl_entry_p = acl_p->i.a_ring->i.e_next;
+
+For better readability, all the "i.a_", "i.e_" etc. parts can be
+hidden using macros:
+
+ acl_obj *acl_p;
+ acl_entry_obj *acl_entry_p = acl_p->aring->enext;
+
+
+ACLs and ACL entries
+====================
+The ACL entries associated with an ACL are stored on a sorted double
+linked list. The first and last entries in that list are available via
+ACL object. This is implemented with a little trick:
+
+ The acl_obj and acl_entry_obj have {a,e}_prev and {a,e}_prev
+ pointers at the same memory location (directly after the object
+ prefix). The a_prev and a_next entries of an acl_obj are
+ initialized to point to the acl_obj itself (this requires a type
+ cast). We only need to check if the acl_obj object has been
+ reached to detect the end of the list. Since the acl_obj object
+ isn't actually an acl_entry_obj object, care must be taken not to
+ manipulate any of the other acl_entry_obj fields other than e_prev
+ and e_next.
+
+Whenever an entry is changed, __acl_reorder_obj_p() reorders the
+entries accordingly. This takes O(n^2) time, but that's not a big
+problem as long as ACLs don't contain very many entries. Some of the
+library functions need a sorted ACL anyway, so the best we could
+possibly do is O(n*log(n)), with a sorted flag in each ACL, and a
+complicated sorting function (the linked list would have to be
+converted to an array first to allow more efficient sorting).
+
+
+Hope that helps. Good luck!
+
+Andreas
+
diff --git a/doc/old-acl.5 b/doc/old-acl.5
new file mode 100644
index 0000000..18bf783
--- /dev/null
+++ b/doc/old-acl.5
@@ -0,0 +1,263 @@
+.\"
+.\" Access Control Lists
+.\"
+.\" Documentation for the Linux implementation
+.\" (C) Andreas Gruenbacher, 1999
+.\"
+.TH ACL 5 "Access Control Lists" "Sep 1999" "Access Control Lists"
+.SH NAME
+acl - Access Control Lists
+.SH DESCRIPTION
+This document describes Posix-style access control lists as implemented under
+Linux. Access control lists (ACLs) are used to define access to files
+and directories.
+
+In portable programs, the Posix 1003.1e Draft Standard 17 library
+functions should be used for mainpulating ACL. On most platforms, the
+ACL entry manipulation functions are not available, so relying only on
+the ACL manipulation and format conversion functions (ACL to and from
+text format) is more portable. The library functions are declared in
+the
+.I sys/acl.h
+header file.
+
+.SH ACCESS CONTROL LIST ENTRIES
+An access control list contains a number of entries of various types. Each entry stands for permissions granted to a user, or to a group of users.
+.PP
+An ACL may contain entries with the following entry tag types.
+.PP
+.RS
+.fam C
+.nf
+ACL_USER_OBJ (owner)
+ACL_USER (named user)
+ACL_GROUP_OBJ (owning group)
+ACL_GROUP (named group)
+ACL_MASK (effective rights mask)
+ACL_OTHER (other users)
+.fi
+.fam T
+.RE
+.PP
+The
+ACL_USER_OBJ, ACL_GROUP_OBJ, and ACL_OTHER entries
+correspond to the traditional file mode permission bits. There is
+exactly one each of these entries in a valid ACL.
+.PP
+ACL_USER and ACL_GROUP
+entries define explicit rights for users and groups, respectively. For
+entries of these two types,
+.I a_id[0]
+is set to the ID of the user or group in question. Whenever there are
+any entries of the last two types in the ACL, an ACL_MASK
+entry is also required.
+
+An ACL_MASK entry limits the effective rights granted
+to named users or groups. The efective rights granted are those
+that are both granted by the user's or group's entry, and by the ACL_MASK entry. The ACL_MASK entry does not apply to the ACL_USER_OBJ and ACL_OTHER entries.
+.PP
+The lowest three bits of
+.I a_perm
+define the rights granted to the user the entry applies to, just like
+the bits in the traditional file mode. This results in a value between 0 and 7
+(from 0 standing for no access to 7 standing for read, write, and execute access). For accessing these bits, the constants ACL_READ, ACL_WRITE and ACL_EXECUTE should be used.
+
+.SH VALID ACCESS CONTROL LISTS
+Each valid ACL has as a minimum the three required base entries
+ACL_USER_OBJ, ACL_GROUP_OBJ, and ACL_OTHER. These entries correspond
+to the traditional Posix permission bits. There must be exactly one each
+of these three entries. The permission mask `rw-r-----' corresponds to the
+following entries:
+.sp
+.RS
+.fam C
+.nf
+ u::rw- (ACL_USER_OBJ entry)
+ g::r-- (ACL_GROUP_OBJ entry)
+ o::--- (ACL_OTHER entry)
+.fi
+.fam T
+.RE
+.PP
+An ACL must also contain exactly one ACL_MASK entry, if it contains
+additional ACL_USER or ACL_GROUP entries. For each user or group, there
+must be at most one ACL_USER or ACL_GROUP entry per access control list. An ACL may also contain an ACL_MASK entry if no ACL_USER or ACL_GROUP entries exist.
+.sp
+.RS
+.fam C
+.nf
+ u:joe:rw- (ACL_USER entry)
+ g:webteam:rw- (ACL_GROUP entry)
+ m::rw- (ACL_MASK entry)
+.fi
+.fam T
+.RE
+.PP
+.SS THE ACL_MASK ENTRY
+The purpose of the ACL_MASK entry is to limit
+the effective rights granted to groups and named users in
+the ACL. The effective rights granted to a user or a group with an ACL_USER
+or an ACL_GROUP entry are those which are listed in both the ACL_USER
+or ACL_GROUP entry
+.I and
+the ACL_MASK entry. The ACL_USER_OBJ and ACL_OTHER entries
+are not affected by the ACL_MASK entry.
+
+.SH PERMISSIONS
+The permissions required for manipulating ACLs of an inode are similar
+to the permissions required for manipulating the file mode. Processes
+with search access to a file are granted the right to read ACLs. Only the
+file owner and processes capable of CAP_FOWNER are granted the right to
+modify ACLs. (On current Linux systems, root is the only user with the
+CAP_FOWNER capability.)
+
+.SH DETERMINING ACCESS
+When a process requests access to a file, the following algorithm determines whether access is granted or not. The input to the algorithm is a set of requested permissions (read, write, execute).
+
+.SS (1) "Find a matching ACL entry"
+.IP * 4
+If the user is the file owner, access is granted \fIonly\fR if the
+ACL_USER_OBJ entry contains the requested permissions.
+.IP * 4
+If the ACL contains a named user (ACL_USER) entry that matches the user, then:
+.RS
+.IP - 4
+If access is granted by that entry, continue with step \fB(2)\fR below.
+.IP - 4
+Otherwise, access is denied.
+.RE
+.IP * 4
+If the user is in the owning group of the file (ACL_GROUP_OBJ entry), or if the user is member of a named group (ACL_GROUP entries), then:
+.RS
+.IP - 4
+If either the ACL_GROUP_OBJ entry or one of the ACL_GROUP entries contains the requested permissions, continue with step \fB(2)\fR below. (Permissions of multiple ACL entries are
+.I not
+accumulated.)
+.IP - 4
+Otherwise, access is denied.
+.RE
+.IP * 4
+If none of the above rules match, then
+.RS
+.IP - 4
+If the ACL_OTHER entry contains the requested permissions, access is
+granted.
+.IP - 4
+Otherwise, access is denied.
+.RE
+.SS (2) Check the access mask
+.IP * 4
+If the access mask (ACL_MASK) contains the requested permissions, access is granted.
+.IP * 4
+Otherwise, access is denied.
+.SH DEFAULT ACCESS CONTROL LISTS
+Directories may have a default ACL, in addition to the regular ACL. While the
+purpose of the regular ACL is to control access to a file or directory,
+the purpose of the default ACL is to control access to files which are
+created inside the directory.
+.PP
+When a file is created,
+a create permissions are specified that determines the maximum access rights to
+the file. This usually is 0666 of files, and 0777 for directories.
+.PP
+Traditionally, the effective access rights to new files are determined by combining the
+.B umask
+and the create permissions. The default ACL replaces the role of the
+.BR umask .
+The following steps are taken when a file is created inside a directory which has a default ACL:
+.IP * 4
+The new file inherits the directory's default ACL as its access ACL.
+.IP * 4
+The permissions of the new file's access ACL are modified in the following way:
+.RS
+.IP - 4
+The ACL_USER entry is set to the union of the value determied by the default ACL and the user bits of the create permissions.
+.IP - 4
+The ACL_OTHER entry is set to the union of the value determined by the default ACL and the other bits of the create permissions.
+.IP - 4
+If the new file's ACL contains an ACL_MASK entry, the permission bits of the ACL_MASK entry are set to the group bits of the create permissions. If the new file's ACL does not contain an ACL_MASK entry, the permission bits of the ACL_GROUP_OBJ entry are set to the group bits of the create permissions.
+.RE
+.IP * 4
+The user and other part of the new file's mode bits are set to the ACL_USER_OBJ and ACL_OTHER permission bits, respectively.
+.IP * 4
+If the new file's ACL contains an ACL_MASK entry, the group bits of the new file's mode field are set to the ACL_MASK entry permission bits. If the new file's ACL does not contain an ACL_MASK entry, the group bits of the new file's mode field are set to the ACL_GROUP_OBJ entry permission bits.
+.IP * 4
+If the new file is a directory, it inherits the parent directory's default ACL as its own default ACL.
+.PP
+For directories without a default ACL, the
+.B umask
+is used to determine effective permissions (see
+.BR umask (2)).
+.PP
+.SH FILE MODE PERMISSION BITS TO ACL ENTRY MAPPING
+.fam C
+.nf
+ user group other
+ ----+-------+-------+-------+
+ | r w x | r w x | r w x |
+ ----+-------+-------+-------+
+ ^ ^ ^
+ | | +-- maps to ACL_OTHER
+ | +-- maps to ACL_GROUP_OBJ or ACL_MASK
+ +-- maps to ACL_USER_OBJ
+.fi
+.fam T
+.PP
+.SH NFSv2, NFSv3 AND ACCESS CONTROL LISTS
+The NFS protocol in version 2 performs some access control decisions at
+the client, based on the file mode permission bits. It serves the user
+cached file contents if it thinks access would be granted. This logic
+is no longer correct if access control lists are in effect. Both false
+positives and denials might result.
+
+As a workaround, the file mode permission bits are modified before
+sending them to NFSv2 clients. This ensures NFS clients don't grant
+extra permissions. (Only the kernel NFS daemon does that right now; the
+userspace NFS daemon has not been patched yet.) The file mode permission
+sent are a subset of the real file mode permission bits. They are changed
+as follows:
+
+.IP * 4
+The group file mode permission bits are set to the intersection of the ACL_GROUP_OBJ and the ACL_MASK ACL entry.
+.IP * 4
+The others file mode permission bits are set to the intersection of all
+ACL entries excluding the ACL_USER_OBJ entry.
+.PP
+A consequence of these changes is that extended permissions granted by ACLs are not available over NFSv2 mounts.
+
+Up to at least 2.2.18 and 2.4.2 kernels, the NFSv3 implementation does
+not implement the ACCESS remote procedure call. Therefore, NFSv3 currently
+suffers the same problems as NFSv2. The same workaround is employed right
+now.
+
+.SH CHANGES TO THE FILE UTILITIES
+The
+.BR ls (1)
+utility displays a plus sign (`+') after the permission string of entries with an extended ACL (i.e., entries where the permission string shows only part of the effective permissions).
+.PP
+The
+.BR cp "(1) and " mv (1)
+utilities preserve ACLs if possible. If files are copied or moved between fileystems that do not support ACLs, only the file mode permission bits are preserved, and a warning is written to standard error.
+.PP
+The
+.BR chmod (1)
+utility is traditionally used to change the file mode permission bits.
+Changing the permission bits using
+.B chmod
+has the following effect on an ACL that is associated with a file:
+.IP * 4
+The new user permission bits replace the permissions of the owner ACL entry.
+.IP * 4
+The new group permission bits replace the permission bits of the mask ACL entry if a mask ACL entry exists. The new group permission bits replace the permission bits of the owning group ACL entry if no mask ACL entry exists.
+.IP * 4
+The new others permission bits replace the permissions of the others ACL entry.
+.PP
+.fam T
+.SH AUTHOR
+Andreas Gruenbacher,
+.RI < a.gruenbacher@computer.org >.
+
+Please send your bug reports, suggested features and comments to the
+above address.
+.SH SEE ALSO
+getfacl(1), setfacl(1), chmod(1), umask(1), ls(1)
diff --git a/examples/Makefile b/examples/Makefile
new file mode 100644
index 0000000..2a862d3
--- /dev/null
+++ b/examples/Makefile
@@ -0,0 +1,27 @@
+#
+# Copyright (c) 2001-2002 Silicon Graphics, Inc. All Rights Reserved.
+#
+# 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 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, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+
+TOPDIR = ..
+include $(TOPDIR)/include/builddefs
+
+LSRCFILES = README Makefile.examples get-acl.c set-acl.c copy-acl.c
+LDIRT = get-acl set-acl copy-acl
+
+include $(BUILDRULES)
+
+default install install-dev install-lib:
diff --git a/examples/Makefile.examples b/examples/Makefile.examples
new file mode 100644
index 0000000..b33c2a5
--- /dev/null
+++ b/examples/Makefile.examples
@@ -0,0 +1,9 @@
+CFLAGS = -g -Wall
+LDFLAGS = -lacl
+
+PROGS = get-acl copy-acl set-acl copyperm
+
+all: $(PROGS)
+
+clean:
+ rm -f $(PROGS)
diff --git a/examples/README b/examples/README
new file mode 100644
index 0000000..09a3678
--- /dev/null
+++ b/examples/README
@@ -0,0 +1,12 @@
+Simple examples using libacl
+============================
+
+This directory contains very simple examples of how to use the acl
+library. After installing the acl library on your system, you can
+build the examples by typing the following command in this directory:
+
+ make -f Makefile.examples
+
+
+ --Andreas Gruenbacher.
+
diff --git a/examples/copy-acl.c b/examples/copy-acl.c
new file mode 100644
index 0000000..9999615
--- /dev/null
+++ b/examples/copy-acl.c
@@ -0,0 +1,70 @@
+/*
+ Copyright (C) 2009 Andreas Gruenbacher <agruen@suse.de>
+
+ 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 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 <http://www.gnu.org/licenses/>.
+*/
+
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include <libgen.h>
+#include <sys/acl.h>
+
+const char *progname;
+
+int main(int argc, char *argv[])
+{
+ acl_t acl, default_acl;
+ int n, ret = 0;
+
+ progname = basename(argv[0]);
+
+ if (argc < 3) {
+ printf("%s -- copy access control lists between files \n"
+ "Usage: %s file1 file2 ...\n",
+ progname, progname);
+ return 1;
+ }
+
+ acl = acl_get_file(argv[1], ACL_TYPE_ACCESS);
+ if (acl == NULL) {
+ fprintf(stderr, "%s: getting acl of %s: %s\n",
+ progname, argv[1], strerror(errno));
+ return 1;
+ }
+ default_acl = acl_get_file(argv[1], ACL_TYPE_DEFAULT);
+ if (default_acl == NULL) {
+ fprintf(stderr, "%s: getting default acl of %s: %s\n",
+ progname, argv[1], strerror(errno));
+ return 1;
+ }
+
+ for (n = 2; n < argc; n++) {
+ if (acl_set_file(argv[n], ACL_TYPE_ACCESS, acl) != 0) {
+ fprintf(stderr, "%s: setting acl for %s: %s\n",
+ progname, argv[n], strerror(errno));
+ ret = 1;
+ } else if (acl_set_file(argv[n], ACL_TYPE_DEFAULT,
+ default_acl) != 0) {
+ fprintf(stderr, "%s: setting default acl for %s: %s\n",
+ progname, argv[n], strerror(errno));
+ ret = 1;
+ }
+ }
+
+ acl_free(acl);
+ acl_free(default_acl);
+
+ return ret;
+}
diff --git a/examples/copyperm.c b/examples/copyperm.c
new file mode 100644
index 0000000..97a60ec
--- /dev/null
+++ b/examples/copyperm.c
@@ -0,0 +1,61 @@
+/*
+ Copyright (C) 2009 Andreas Gruenbacher <agruen@suse.de>
+
+ 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 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 <http://www.gnu.org/licenses/>.
+*/
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdarg.h>
+#include <string.h>
+#include <errno.h>
+#include <locale.h>
+
+#include <attr/error_context.h>
+#include <attr/libattr.h>
+#include <acl/libacl.h>
+
+void
+error(struct error_context *ctx, const char *fmt, ...)
+{
+ va_list ap;
+
+ va_start(ap, fmt);
+ if (vfprintf(stderr, fmt, ap))
+ fprintf(stderr, ": ");
+ fprintf(stderr, "%s\n", strerror(errno));
+ va_end(ap);
+}
+
+struct error_context ctx = {
+ error
+};
+
+int
+main(int argc, char *argv[])
+{
+ int ret;
+
+ setlocale(LC_MESSAGES, "");
+ setlocale(LC_CTYPE, "");
+
+ if (argc != 3) {
+ fprintf(stderr, "Usage: %s from to\n", argv[0]);
+ exit(1);
+ }
+
+ ret = perm_copy_file(argv[1], argv[2], &ctx);
+ exit (ret == 0 ? EXIT_SUCCESS : EXIT_FAILURE);
+}
+
diff --git a/examples/get-acl.c b/examples/get-acl.c
new file mode 100644
index 0000000..716e247
--- /dev/null
+++ b/examples/get-acl.c
@@ -0,0 +1,96 @@
+/*
+ Copyright (C) 2009 Andreas Gruenbacher <agruen@suse.de>
+
+ 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 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 <http://www.gnu.org/licenses/>.
+*/
+
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include <libgen.h>
+#include <sys/stat.h>
+#include <sys/acl.h>
+
+const char *progname;
+
+int main(int argc, char *argv[])
+{
+ int n, ret = 0;
+
+ progname = basename(argv[0]);
+
+ if (argc == 1) {
+ printf("%s -- get access control lists of files\n"
+ "Usage: %s file ...\n",
+ progname, progname);
+ return 1;
+ }
+
+ for (n = 1; n < argc; n++) {
+ struct stat st;
+ acl_t acl, default_acl;
+ char *acl_text, *default_acl_text, *token;
+
+ if (stat(argv[n], &st) != 0) {
+ fprintf(stderr, "%s: %s: %s\n",
+ progname, argv[n], strerror(errno));
+ ret = 1;
+ continue;
+ }
+
+ acl = acl_get_file(argv[n], ACL_TYPE_ACCESS);
+ if (acl == NULL) {
+ fprintf(stderr, "%s: getting acl of %s: %s\n",
+ progname, argv[n], strerror(errno));
+ ret = 1;
+ continue;
+ }
+ acl_text = acl_to_text(acl, NULL);
+ acl_free(acl);
+
+ if (S_ISDIR(st.st_mode)) {
+ default_acl = acl_get_file(argv[n], ACL_TYPE_DEFAULT);
+ if (default_acl == NULL) {
+ acl_free(acl_text);
+ fprintf(stderr, "%s: getting default acl "
+ "of %s: %s\n", progname, argv[n],
+ strerror(errno));
+ ret = 1;
+ continue;
+ }
+ default_acl_text = acl_to_text(default_acl, NULL);
+ acl_free(default_acl);
+ }
+
+ printf("# file: %s\n"
+ "# owner: %d\n"
+ "# group: %d\n"
+ "%s",
+ argv[n], st.st_uid, st.st_gid, acl_text);
+
+ if (S_ISDIR(st.st_mode)) {
+ token = strtok(default_acl_text, "\n");
+ while (token) {
+ printf("default:%s\n", token);
+ token = strtok(NULL, "\n");
+ }
+ acl_free(default_acl_text);
+ }
+ printf("\n");
+
+ acl_free(acl_text);
+ }
+ return ret;
+}
+
diff --git a/examples/set-acl.c b/examples/set-acl.c
new file mode 100644
index 0000000..b3dd8d3
--- /dev/null
+++ b/examples/set-acl.c
@@ -0,0 +1,64 @@
+/*
+ Copyright (C) 2009 Andreas Gruenbacher <agruen@suse.de>
+
+ 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 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 <http://www.gnu.org/licenses/>.
+*/
+
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include <libgen.h>
+#include <sys/acl.h>
+
+const char *progname;
+
+int main(int argc, char *argv[])
+{
+ acl_t acl;
+ int n, ret = 0;
+
+ progname = basename(argv[0]);
+
+ if (argc < 3) {
+ printf("%s -- set access control list of files\n"
+ "Usage: %s acl file ...\n",
+ progname, progname);
+ return 1;
+ }
+
+ acl = acl_from_text(argv[1]);
+ if (!acl) {
+ fprintf(stderr, "%s: `%s': %s\n",
+ progname, argv[1], strerror(errno));
+ return 1;
+ }
+ if (acl_valid(acl) != 0) {
+ fprintf(stderr, "%s: `%s': invalid/incomplete acl\n",
+ progname, argv[1]);
+ acl_free(acl);
+ return 1;
+ }
+
+ for (n = 2; n < argc; n++) {
+ if (acl_set_file(argv[n], ACL_TYPE_ACCESS, acl) != 0) {
+ fprintf(stderr, "%s: setting acl of %s: %s\n",
+ progname, argv[n], strerror(errno));
+ ret = 1;
+ }
+ }
+
+ acl_free(acl);
+
+ return ret;
+}
diff --git a/exports b/exports
new file mode 100644
index 0000000..ef02842
--- /dev/null
+++ b/exports
@@ -0,0 +1,85 @@
+# Copyright (C) 2003 Andreas Gruenbacher <agruen@suse.de>
+#
+# This program is free software: you can redistribute it and/or modify it
+# under the terms of the GNU Lesser General Public License as published by
+# the Free Software Foundation, either version 2.1 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 Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+
+ACL_1.0 {
+ global:
+ # POSIX 1003.1e draft stardard 17 functions
+ acl_init;
+ acl_dup;
+ acl_free;
+ acl_valid;
+ acl_copy_entry;
+ acl_create_entry;
+ acl_delete_entry;
+ acl_get_entry;
+ acl_add_perm;
+ acl_calc_mask;
+ acl_clear_perms;
+ acl_delete_perm;
+ acl_get_permset;
+ acl_set_permset;
+ acl_get_qualifier;
+ acl_get_tag_type;
+ acl_set_qualifier;
+ acl_set_tag_type;
+ acl_copy_ext;
+ acl_copy_int;
+ acl_from_text;
+ acl_size;
+ acl_to_text;
+ acl_delete_def_file;
+ acl_get_fd;
+ acl_get_file;
+ acl_set_fd;
+ acl_set_file;
+
+ # Linux specific extensions
+ acl_check;
+ acl_cmp;
+ acl_entries;
+ acl_equiv_mode;
+ acl_error;
+ acl_extended_fd;
+ acl_extended_file;
+ acl_from_mode;
+ acl_get_perm;
+ acl_to_any_text;
+
+ local:
+ # Library internal stuff
+ __new_var_obj_p;
+ __new_obj_p_here;
+ __free_obj_p;
+ __check_obj_p;
+ __ext2int_and_check;
+ __acl_reorder_entry_obj_p;
+ __acl_reorder_obj_p;
+ __acl_init_obj;
+ __acl_create_entry_obj;
+ __acl_free_acl_obj;
+ __acl_to_any_text;
+ __apply_mask_to_mode;
+
+ quote;
+ unquote;
+};
+
+ACL_1.1 {
+ global:
+ # Linux specific extensions
+ perm_copy_fd;
+ perm_copy_file;
+} ACL_1.0;
diff --git a/getfacl/Makefile b/getfacl/Makefile
new file mode 100644
index 0000000..7fbafda
--- /dev/null
+++ b/getfacl/Makefile
@@ -0,0 +1,36 @@
+#
+# Copyright (c) 2000, 2002 Silicon Graphics, Inc. All Rights Reserved.
+#
+# 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 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, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+
+TOPDIR = ..
+include $(TOPDIR)/include/builddefs
+
+LTCOMMAND = getfacl
+CFILES = getfacl.c user_group.c
+HFILES = user_group.h
+
+LLDLIBS = $(LIBMISC) $(LIBACL) $(LIBATTR)
+LTDEPENDENCIES = $(LIBMISC) $(LIBACL)
+
+default: $(LTCOMMAND)
+
+include $(BUILDRULES)
+
+install: default
+ $(INSTALL) -m 755 -d $(PKG_BIN_DIR)
+ $(LTINSTALL) -m 755 $(LTCOMMAND) $(PKG_BIN_DIR)
+install-dev install-lib:
diff --git a/getfacl/getfacl.c b/getfacl/getfacl.c
new file mode 100644
index 0000000..ab050ba
--- /dev/null
+++ b/getfacl/getfacl.c
@@ -0,0 +1,733 @@
+/*
+ File: getfacl.c
+ (Linux Access Control List Management)
+
+ Copyright (C) 1999-2002
+ Andreas Gruenbacher, <a.gruenbacher@bestbits.at>
+
+ 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 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 library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+ USA.
+*/
+
+#include <stdio.h>
+#include <errno.h>
+#include <sys/acl.h>
+#include <acl/libacl.h>
+
+#include <limits.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <dirent.h>
+#include <libgen.h>
+#include <getopt.h>
+#include <locale.h>
+#include "config.h"
+#include "user_group.h"
+#include "walk_tree.h"
+#include "misc.h"
+
+#define POSIXLY_CORRECT_STR "POSIXLY_CORRECT"
+
+#if !POSIXLY_CORRECT
+# define CMD_LINE_OPTIONS "aceEsRLPtpndvh"
+#endif
+#define POSIXLY_CMD_LINE_OPTIONS "d"
+
+struct option long_options[] = {
+#if !POSIXLY_CORRECT
+ { "access", 0, 0, 'a' },
+ { "omit-header", 0, 0, 'c' },
+ { "all-effective", 0, 0, 'e' },
+ { "no-effective", 0, 0, 'E' },
+ { "skip-base", 0, 0, 's' },
+ { "recursive", 0, 0, 'R' },
+ { "logical", 0, 0, 'L' },
+ { "physical", 0, 0, 'P' },
+ { "tabular", 0, 0, 't' },
+ { "absolute-names", 0, 0, 'p' },
+ { "numeric", 0, 0, 'n' },
+#endif
+ { "default", 0, 0, 'd' },
+ { "version", 0, 0, 'v' },
+ { "help", 0, 0, 'h' },
+ { NULL, 0, 0, 0 }
+};
+
+const char *progname;
+const char *cmd_line_options;
+
+int walk_flags = WALK_TREE_DEREFERENCE;
+int opt_print_acl;
+int opt_print_default_acl;
+int opt_strip_leading_slash = 1;
+int opt_comments = 1; /* include comments */
+int opt_skip_base; /* skip files that only have the base entries */
+int opt_tabular; /* tabular output format (alias `showacl') */
+#if POSIXLY_CORRECT
+const int posixly_correct = 1; /* Posix compatible behavior! */
+#else
+int posixly_correct; /* Posix compatible behavior? */
+#endif
+int had_errors;
+int absolute_warning; /* Absolute path warning was issued */
+int print_options = TEXT_SOME_EFFECTIVE;
+int opt_numeric; /* don't convert id's to symbolic names */
+
+
+static const char *xquote(const char *str)
+{
+ const char *q = quote(str);
+ if (q == NULL) {
+ fprintf(stderr, "%s: %s\n", progname, strerror(errno));
+ exit(1);
+ }
+ return q;
+}
+
+struct name_list {
+ struct name_list *next;
+ char name[0];
+};
+
+void free_list(struct name_list *names)
+{
+ struct name_list *next;
+
+ while (names) {
+ next = names->next;
+ free(names);
+ names = next;
+ }
+}
+
+struct name_list *get_list(const struct stat *st, acl_t acl)
+{
+ struct name_list *first = NULL, *last = NULL;
+ acl_entry_t ent;
+ int ret = 0;
+
+ if (acl != NULL)
+ ret = acl_get_entry(acl, ACL_FIRST_ENTRY, &ent);
+ if (ret != 1)
+ return NULL;
+ while (ret > 0) {
+ acl_tag_t e_type;
+ const id_t *id_p;
+ const char *name = "";
+ int len;
+
+ acl_get_tag_type(ent, &e_type);
+ switch(e_type) {
+ case ACL_USER_OBJ:
+ name = user_name(st->st_uid, opt_numeric);
+ break;
+
+ case ACL_USER:
+ id_p = acl_get_qualifier(ent);
+ if (id_p != NULL)
+ name = user_name(*id_p, opt_numeric);
+ break;
+
+ case ACL_GROUP_OBJ:
+ name = group_name(st->st_gid, opt_numeric);
+ break;
+
+ case ACL_GROUP:
+ id_p = acl_get_qualifier(ent);
+ if (id_p != NULL)
+ name = group_name(*id_p, opt_numeric);
+ break;
+ }
+ name = xquote(name);
+ len = strlen(name);
+ if (last == NULL) {
+ first = last = (struct name_list *)
+ malloc(sizeof(struct name_list) + len + 1);
+ } else {
+ last->next = (struct name_list *)
+ malloc(sizeof(struct name_list) + len + 1);
+ last = last->next;
+ }
+ if (last == NULL) {
+ free_list(first);
+ return NULL;
+ }
+ last->next = NULL;
+ strcpy(last->name, name);
+
+ ret = acl_get_entry(acl, ACL_NEXT_ENTRY, &ent);
+ }
+ return first;
+}
+
+int max_name_length(struct name_list *names)
+{
+ int max_len = 0;
+ while (names != NULL) {
+ struct name_list *next = names->next;
+ int len = strlen(names->name);
+
+ if (len > max_len)
+ max_len = len;
+ names = next;
+ }
+ return max_len;
+}
+
+int names_width;
+
+struct acl_perm_def {
+ acl_tag_t tag;
+ char c;
+};
+
+struct acl_perm_def acl_perm_defs[] = {
+ { ACL_READ, 'r' },
+ { ACL_WRITE, 'w' },
+ { ACL_EXECUTE, 'x' },
+ { 0, 0 }
+};
+
+#define ACL_PERMS (sizeof(acl_perm_defs) / sizeof(struct acl_perm_def) - 1)
+
+void acl_perm_str(acl_entry_t entry, char *str)
+{
+ acl_permset_t permset;
+ int n;
+
+ acl_get_permset(entry, &permset);
+ for (n = 0; n < (int) ACL_PERMS; n++) {
+ str[n] = (acl_get_perm(permset, acl_perm_defs[n].tag) ?
+ acl_perm_defs[n].c : '-');
+ }
+ str[n] = '\0';
+}
+
+void acl_mask_perm_str(acl_t acl, char *str)
+{
+ acl_entry_t entry;
+
+ str[0] = '\0';
+ if (acl_get_entry(acl, ACL_FIRST_ENTRY, &entry) != 1)
+ return;
+ for(;;) {
+ acl_tag_t tag;
+
+ acl_get_tag_type(entry, &tag);
+ if (tag == ACL_MASK) {
+ acl_perm_str(entry, str);
+ return;
+ }
+ if (acl_get_entry(acl, ACL_NEXT_ENTRY, &entry) != 1)
+ return;
+ }
+}
+
+void apply_mask(char *perm, const char *mask)
+{
+ while (*perm) {
+ if (*mask == '-' && *perm >= 'a' && *perm <= 'z')
+ *perm = *perm - 'a' + 'A';
+ perm++;
+ if (*mask)
+ mask++;
+ }
+}
+
+int show_line(FILE *stream, struct name_list **acl_names, acl_t acl,
+ acl_entry_t *acl_ent, const char *acl_mask,
+ struct name_list **dacl_names, acl_t dacl,
+ acl_entry_t *dacl_ent, const char *dacl_mask)
+{
+ acl_tag_t tag_type;
+ const char *tag, *name;
+ char acl_perm[ACL_PERMS+1], dacl_perm[ACL_PERMS+1];
+
+ if (acl) {
+ acl_get_tag_type(*acl_ent, &tag_type);
+ name = (*acl_names)->name;
+ } else {
+ acl_get_tag_type(*dacl_ent, &tag_type);
+ name = (*dacl_names)->name;
+ }
+
+ switch(tag_type) {
+ case ACL_USER_OBJ:
+ tag = "USER";
+ break;
+ case ACL_USER:
+ tag = "user";
+ break;
+ case ACL_GROUP_OBJ:
+ tag = "GROUP";
+ break;
+ case ACL_GROUP:
+ tag = "group";
+ break;
+ case ACL_MASK:
+ tag = "mask";
+ break;
+ case ACL_OTHER:
+ tag = "other";
+ break;
+ default:
+ return -1;
+ }
+
+ memset(acl_perm, ' ', ACL_PERMS);
+ acl_perm[ACL_PERMS] = '\0';
+ if (acl_ent) {
+ acl_perm_str(*acl_ent, acl_perm);
+ if (tag_type != ACL_USER_OBJ && tag_type != ACL_OTHER &&
+ tag_type != ACL_MASK)
+ apply_mask(acl_perm, acl_mask);
+ }
+ memset(dacl_perm, ' ', ACL_PERMS);
+ dacl_perm[ACL_PERMS] = '\0';
+ if (dacl_ent) {
+ acl_perm_str(*dacl_ent, dacl_perm);
+ if (tag_type != ACL_USER_OBJ && tag_type != ACL_OTHER &&
+ tag_type != ACL_MASK)
+ apply_mask(dacl_perm, dacl_mask);
+ }
+
+ fprintf(stream, "%-5s %*s %*s %*s\n",
+ tag, -names_width, name,
+ -(int)ACL_PERMS, acl_perm,
+ -(int)ACL_PERMS, dacl_perm);
+
+ if (acl_names) {
+ acl_get_entry(acl, ACL_NEXT_ENTRY, acl_ent);
+ (*acl_names) = (*acl_names)->next;
+ }
+ if (dacl_names) {
+ acl_get_entry(dacl, ACL_NEXT_ENTRY, dacl_ent);
+ (*dacl_names) = (*dacl_names)->next;
+ }
+ return 0;
+}
+
+int do_show(FILE *stream, const char *path_p, const struct stat *st,
+ acl_t acl, acl_t dacl)
+{
+ struct name_list *acl_names = get_list(st, acl),
+ *first_acl_name = acl_names;
+ struct name_list *dacl_names = get_list(st, dacl),
+ *first_dacl_name = dacl_names;
+
+ int acl_names_width = max_name_length(acl_names);
+ int dacl_names_width = max_name_length(dacl_names);
+ acl_entry_t acl_ent;
+ acl_entry_t dacl_ent;
+ char acl_mask[ACL_PERMS+1], dacl_mask[ACL_PERMS+1];
+ int ret;
+
+ names_width = 8;
+ if (acl_names_width > names_width)
+ names_width = acl_names_width;
+ if (dacl_names_width > names_width)
+ names_width = dacl_names_width;
+
+ acl_mask[0] = '\0';
+ if (acl) {
+ acl_mask_perm_str(acl, acl_mask);
+ ret = acl_get_entry(acl, ACL_FIRST_ENTRY, &acl_ent);
+ if (ret == 0)
+ acl = NULL;
+ if (ret < 0)
+ return ret;
+ }
+ dacl_mask[0] = '\0';
+ if (dacl) {
+ acl_mask_perm_str(dacl, dacl_mask);
+ ret = acl_get_entry(dacl, ACL_FIRST_ENTRY, &dacl_ent);
+ if (ret == 0)
+ dacl = NULL;
+ if (ret < 0)
+ return ret;
+ }
+ fprintf(stream, "# file: %s\n", xquote(path_p));
+ while (acl_names != NULL || dacl_names != NULL) {
+ acl_tag_t acl_tag, dacl_tag;
+
+ if (acl)
+ acl_get_tag_type(acl_ent, &acl_tag);
+ if (dacl)
+ acl_get_tag_type(dacl_ent, &dacl_tag);
+
+ if (acl && (!dacl || acl_tag < dacl_tag)) {
+ show_line(stream, &acl_names, acl, &acl_ent, acl_mask,
+ NULL, NULL, NULL, NULL);
+ continue;
+ } else if (dacl && (!acl || dacl_tag < acl_tag)) {
+ show_line(stream, NULL, NULL, NULL, NULL,
+ &dacl_names, dacl, &dacl_ent, dacl_mask);
+ continue;
+ } else {
+ if (acl_tag == ACL_USER || acl_tag == ACL_GROUP) {
+ id_t *acl_id_p = NULL, *dacl_id_p = NULL;
+ if (acl_ent)
+ acl_id_p = acl_get_qualifier(acl_ent);
+ if (dacl_ent)
+ dacl_id_p = acl_get_qualifier(dacl_ent);
+
+ if (acl && (!dacl || *acl_id_p < *dacl_id_p)) {
+ show_line(stream, &acl_names, acl,
+ &acl_ent, acl_mask,
+ NULL, NULL, NULL, NULL);
+ continue;
+ } else if (dacl &&
+ (!acl || *dacl_id_p < *acl_id_p)) {
+ show_line(stream, NULL, NULL, NULL,
+ NULL, &dacl_names, dacl,
+ &dacl_ent, dacl_mask);
+ continue;
+ }
+ }
+ show_line(stream, &acl_names, acl, &acl_ent, acl_mask,
+ &dacl_names, dacl, &dacl_ent, dacl_mask);
+ }
+ }
+
+ free_list(first_acl_name);
+ free_list(first_dacl_name);
+
+ return 0;
+}
+
+/*
+ * Create an ACL from the file permission bits
+ * of the file PATH_P.
+ */
+static acl_t
+acl_get_file_mode(const char *path_p)
+{
+ struct stat st;
+
+ if (stat(path_p, &st) != 0)
+ return NULL;
+ return acl_from_mode(st.st_mode);
+}
+
+int do_print(const char *path_p, const struct stat *st, int walk_flags, void *unused)
+{
+ const char *default_prefix = NULL;
+ acl_t acl = NULL, default_acl = NULL;
+ int error = 0;
+
+ if (walk_flags & WALK_TREE_FAILED) {
+ fprintf(stderr, "%s: %s: %s\n", progname, xquote(path_p),
+ strerror(errno));
+ return 1;
+ }
+
+ /*
+ * Symlinks can never have ACLs, so when doing a physical walk, we
+ * skip symlinks altogether, and when doing a half-logical walk, we
+ * skip all non-toplevel symlinks.
+ */
+ if ((walk_flags & WALK_TREE_SYMLINK) &&
+ ((walk_flags & WALK_TREE_PHYSICAL) ||
+ !(walk_flags & (WALK_TREE_TOPLEVEL | WALK_TREE_LOGICAL))))
+ return 0;
+
+ if (opt_print_acl) {
+ acl = acl_get_file(path_p, ACL_TYPE_ACCESS);
+ if (acl == NULL && (errno == ENOSYS || errno == ENOTSUP))
+ acl = acl_get_file_mode(path_p);
+ if (acl == NULL)
+ goto fail;
+ }
+
+ if (opt_print_default_acl && S_ISDIR(st->st_mode)) {
+ default_acl = acl_get_file(path_p, ACL_TYPE_DEFAULT);
+ if (default_acl == NULL) {
+ if (errno != ENOSYS && errno != ENOTSUP)
+ goto fail;
+ } else if (acl_entries(default_acl) == 0) {
+ acl_free(default_acl);
+ default_acl = NULL;
+ }
+ }
+
+ if (opt_skip_base &&
+ (!acl || acl_equiv_mode(acl, NULL) == 0) && !default_acl)
+ return 0;
+
+ if (opt_print_acl && opt_print_default_acl)
+ default_prefix = "default:";
+
+ if (opt_strip_leading_slash) {
+ if (*path_p == '/') {
+ if (!absolute_warning) {
+ fprintf(stderr, _("%s: Removing leading "
+ "'/' from absolute path names\n"),
+ progname);
+ absolute_warning = 1;
+ }
+ while (*path_p == '/')
+ path_p++;
+ } else if (*path_p == '.' && *(path_p+1) == '/')
+ while (*++path_p == '/')
+ /* nothing */ ;
+ if (*path_p == '\0')
+ path_p = ".";
+ }
+
+ if (opt_tabular) {
+ if (do_show(stdout, path_p, st, acl, default_acl) != 0)
+ goto fail;
+ } else {
+ if (opt_comments) {
+ printf("# file: %s\n", xquote(path_p));
+ printf("# owner: %s\n",
+ xquote(user_name(st->st_uid, opt_numeric)));
+ printf("# group: %s\n",
+ xquote(group_name(st->st_gid, opt_numeric)));
+ }
+ if (acl != NULL) {
+ char *acl_text = acl_to_any_text(acl, NULL, '\n',
+ print_options);
+ if (!acl_text)
+ goto fail;
+ if (puts(acl_text) < 0) {
+ acl_free(acl_text);
+ goto fail;
+ }
+ acl_free(acl_text);
+ }
+ if (default_acl != NULL) {
+ char *acl_text = acl_to_any_text(default_acl,
+ default_prefix, '\n',
+ print_options);
+ if (!acl_text)
+ goto fail;
+ if (puts(acl_text) < 0) {
+ acl_free(acl_text);
+ goto fail;
+ }
+ acl_free(acl_text);
+ }
+ }
+ if (acl || default_acl || opt_comments)
+ printf("\n");
+
+cleanup:
+ if (acl)
+ acl_free(acl);
+ if (default_acl)
+ acl_free(default_acl);
+ return error;
+
+fail:
+ fprintf(stderr, "%s: %s: %s\n", progname, xquote(path_p),
+ strerror(errno));
+ error = -1;
+ goto cleanup;
+}
+
+
+void help(void)
+{
+ printf(_("%s %s -- get file access control lists\n"),
+ progname, VERSION);
+ printf(_("Usage: %s [-%s] file ...\n"),
+ progname, cmd_line_options);
+#if !POSIXLY_CORRECT
+ if (posixly_correct) {
+#endif
+ printf(_(
+" -d, --default display the default access control list\n"));
+#if !POSIXLY_CORRECT
+ } else {
+ printf(_(
+" -a, --access display the file access control list only\n"
+" -d, --default display the default access control list only\n"
+" -c, --omit-header do not display the comment header\n"
+" -e, --all-effective print all effective rights\n"
+" -E, --no-effective print no effective rights\n"
+" -s, --skip-base skip files that only have the base entries\n"
+" -R, --recursive recurse into subdirectories\n"
+" -L, --logical logical walk, follow symbolic links\n"
+" -P, --physical physical walk, do not follow symbolic links\n"
+" -t, --tabular use tabular output format\n"
+" -n, --numeric print numeric user/group identifiers\n"
+" -p, --absolute-names don't strip leading '/' in pathnames\n"));
+ }
+#endif
+ printf(_(
+" -v, --version print version and exit\n"
+" -h, --help this help text\n"));
+}
+
+int main(int argc, char *argv[])
+{
+ int opt;
+ char *line;
+
+ progname = basename(argv[0]);
+
+#if POSIXLY_CORRECT
+ cmd_line_options = POSIXLY_CMD_LINE_OPTIONS;
+#else
+ if (getenv(POSIXLY_CORRECT_STR))
+ posixly_correct = 1;
+ if (!posixly_correct)
+ cmd_line_options = CMD_LINE_OPTIONS;
+ else
+ cmd_line_options = POSIXLY_CMD_LINE_OPTIONS;
+#endif
+
+ setlocale(LC_CTYPE, "");
+ setlocale(LC_MESSAGES, "");
+ bindtextdomain(PACKAGE, LOCALEDIR);
+ textdomain(PACKAGE);
+
+ /* Align `#effective:' comments to column 40 for tty's */
+ if (!posixly_correct && isatty(fileno(stdout)))
+ print_options |= TEXT_SMART_INDENT;
+
+ while ((opt = getopt_long(argc, argv, cmd_line_options,
+ long_options, NULL)) != -1) {
+ switch (opt) {
+ case 'a': /* acl only */
+ if (posixly_correct)
+ goto synopsis;
+ opt_print_acl = 1;
+ break;
+
+ case 'd': /* default acl only */
+ opt_print_default_acl = 1;
+ break;
+
+ case 'c': /* no comments */
+ if (posixly_correct)
+ goto synopsis;
+ opt_comments = 0;
+ break;
+
+ case 'e': /* all #effective comments */
+ if (posixly_correct)
+ goto synopsis;
+ print_options |= TEXT_ALL_EFFECTIVE;
+ break;
+
+ case 'E': /* no #effective comments */
+ if (posixly_correct)
+ goto synopsis;
+ print_options &= ~(TEXT_SOME_EFFECTIVE |
+ TEXT_ALL_EFFECTIVE);
+ break;
+
+ case 'R': /* recursive */
+ if (posixly_correct)
+ goto synopsis;
+ walk_flags |= WALK_TREE_RECURSIVE;
+ break;
+
+ case 'L': /* follow all symlinks */
+ if (posixly_correct)
+ goto synopsis;
+ walk_flags |= WALK_TREE_LOGICAL;
+ walk_flags &= ~WALK_TREE_PHYSICAL;
+ break;
+
+ case 'P': /* skip all symlinks */
+ if (posixly_correct)
+ goto synopsis;
+ walk_flags |= WALK_TREE_PHYSICAL;
+ walk_flags &= ~WALK_TREE_LOGICAL;
+ break;
+
+ case 's': /* skip files with only base entries */
+ if (posixly_correct)
+ goto synopsis;
+ opt_skip_base = 1;
+ break;
+
+ case 'p':
+ if (posixly_correct)
+ goto synopsis;
+ opt_strip_leading_slash = 0;
+ break;
+
+ case 't':
+ if (posixly_correct)
+ goto synopsis;
+ opt_tabular = 1;
+ break;
+
+ case 'n': /* numeric */
+ opt_numeric = 1;
+ print_options |= TEXT_NUMERIC_IDS;
+ break;
+
+ case 'v': /* print version */
+ printf("%s " VERSION "\n", progname);
+ return 0;
+
+ case 'h': /* help */
+ help();
+ return 0;
+
+ case ':': /* option missing */
+ case '?': /* unknown option */
+ default:
+ goto synopsis;
+ }
+ }
+
+ if (!(opt_print_acl || opt_print_default_acl)) {
+ opt_print_acl = 1;
+ if (!posixly_correct)
+ opt_print_default_acl = 1;
+ }
+
+ if ((optind == argc) && !posixly_correct)
+ goto synopsis;
+
+ do {
+ if (optind == argc ||
+ strcmp(argv[optind], "-") == 0) {
+ while ((line = next_line(stdin)) != NULL) {
+ if (*line == '\0')
+ continue;
+
+ had_errors += walk_tree(line, walk_flags, 0,
+ do_print, NULL);
+ }
+ if (!feof(stdin)) {
+ fprintf(stderr, _("%s: Standard input: %s\n"),
+ progname, strerror(errno));
+ had_errors++;
+ }
+ } else
+ had_errors += walk_tree(argv[optind], walk_flags, 0,
+ do_print, NULL);
+ optind++;
+ } while (optind < argc);
+
+ return had_errors ? 1 : 0;
+
+synopsis:
+ fprintf(stderr, _("Usage: %s [-%s] file ...\n"),
+ progname, cmd_line_options);
+ fprintf(stderr, _("Try `%s --help' for more information.\n"),
+ progname);
+ return 2;
+}
+
diff --git a/getfacl/user_group.c b/getfacl/user_group.c
new file mode 100644
index 0000000..61fa0c3
--- /dev/null
+++ b/getfacl/user_group.c
@@ -0,0 +1,59 @@
+/*
+ File: user_group.c
+ (Linux Access Control List Management)
+
+ Copyright (C) 1999, 2000
+ Andreas Gruenbacher, <a.gruenbacher@bestbits.at>
+
+ 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 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 library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+ USA.
+*/
+
+#include <stdlib.h>
+#include <stdio.h>
+#include "user_group.h"
+
+
+const char *
+user_name(uid_t uid, int numeric)
+{
+ struct passwd *passwd = numeric ? NULL : getpwuid(uid);
+ static char uid_str[22];
+ int ret;
+
+ if (passwd != NULL)
+ return passwd->pw_name;
+ ret = snprintf(uid_str, sizeof(uid_str), "%ld", (long)uid);
+ if (ret < 1 || (size_t)ret >= sizeof(uid_str))
+ return "?";
+ return uid_str;
+}
+
+
+const char *
+group_name(gid_t gid, int numeric)
+{
+ struct group *group = numeric ? NULL : getgrgid(gid);
+ static char gid_str[22];
+ int ret;
+
+ if (group != NULL)
+ return group->gr_name;
+ ret = snprintf(gid_str, sizeof(gid_str), "%ld", (long)gid);
+ if (ret < 1 || (size_t)ret >= sizeof(gid_str))
+ return "?";
+ return gid_str;
+}
+
diff --git a/getfacl/user_group.h b/getfacl/user_group.h
new file mode 100644
index 0000000..aad5846
--- /dev/null
+++ b/getfacl/user_group.h
@@ -0,0 +1,31 @@
+/*
+ File: user_group.h
+ (Linux Access Control List Management)
+
+ Copyright (C) 1999 by Andreas Gruenbacher
+ <a.gruenbacher@computer.org>
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#include <sys/types.h>
+#include <pwd.h>
+#include <grp.h>
+
+const char *
+user_name(uid_t uid, int numeric);
+const char *
+group_name(gid_t uid, int numeric);
+
diff --git a/include/Makefile b/include/Makefile
new file mode 100644
index 0000000..328a61d
--- /dev/null
+++ b/include/Makefile
@@ -0,0 +1,40 @@
+#
+# Copyright (c) 2001-2002 Silicon Graphics, Inc. All Rights Reserved.
+#
+# 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 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, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+
+TOPDIR = ..
+include $(TOPDIR)/include/builddefs
+
+HFILES = acl.h libacl.h acl_ea.h misc.h walk_tree.h
+LSRCFILES = builddefs.in buildmacros buildrules config.h.in install-sh
+LDIRT = sys acl
+
+default: sys acl
+
+sys acl:
+ $(LN_S) . $@
+
+include $(BUILDRULES)
+
+install-dev: default
+ $(INSTALL) -m 755 -d $(PKG_INC_DIR)
+ $(INSTALL) -m 755 -d $(PKG_INC_DIR)/sys
+ $(INSTALL) -m 644 acl.h $(PKG_INC_DIR)/sys/acl.h
+ $(INSTALL) -m 755 -d $(PKG_INC_DIR)/acl
+ $(INSTALL) -m 644 libacl.h $(PKG_INC_DIR)/acl/libacl.h
+
+install install-lib:
diff --git a/include/acl.h b/include/acl.h
new file mode 100644
index 0000000..e3347e1
--- /dev/null
+++ b/include/acl.h
@@ -0,0 +1,130 @@
+/*
+ File: sys/acl.h
+
+ (C) 1999 Andreas Gruenbacher, <a.gruenbacher@computer.org>
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 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. the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#ifndef __SYS_ACL_H
+#define __SYS_ACL_H
+
+#include <sys/types.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*=== Data types ===*/
+
+struct __acl_ext;
+struct __acl_entry_ext;
+struct __acl_permset_ext;
+
+typedef unsigned int acl_type_t;
+typedef int acl_tag_t;
+typedef unsigned int acl_perm_t;
+
+typedef struct __acl_ext *acl_t;
+typedef struct __acl_entry_ext *acl_entry_t;
+typedef struct __acl_permset_ext *acl_permset_t;
+
+/*=== Constants ===*/
+
+/* 23.2.2 acl_perm_t values */
+
+#define ACL_READ (0x04)
+#define ACL_WRITE (0x02)
+#define ACL_EXECUTE (0x01)
+//#define ACL_ADD (0x08)
+//#define ACL_DELETE (0x10)
+
+/* 23.2.5 acl_tag_t values */
+
+#define ACL_UNDEFINED_TAG (0x00)
+#define ACL_USER_OBJ (0x01)
+#define ACL_USER (0x02)
+#define ACL_GROUP_OBJ (0x04)
+#define ACL_GROUP (0x08)
+#define ACL_MASK (0x10)
+#define ACL_OTHER (0x20)
+
+/* 23.3.6 acl_type_t values */
+
+#define ACL_TYPE_ACCESS (0x8000)
+#define ACL_TYPE_DEFAULT (0x4000)
+
+/* 23.2.7 ACL qualifier constants */
+
+#define ACL_UNDEFINED_ID ((id_t)-1)
+
+/* 23.2.8 ACL Entry Constants */
+
+#define ACL_FIRST_ENTRY 0
+#define ACL_NEXT_ENTRY 1
+
+/*=== ACL manipulation ===*/
+
+extern acl_t acl_init(int count);
+extern acl_t acl_dup(acl_t acl);
+extern int acl_free(void *obj_p);
+extern int acl_valid(acl_t acl);
+
+/*=== Entry manipulation ===*/
+
+extern int
+acl_copy_entry(acl_entry_t dest_d, acl_entry_t src_d);
+extern int acl_create_entry(acl_t *acl_p, acl_entry_t *entry_p);
+extern int acl_delete_entry(acl_t acl, acl_entry_t entry_d);
+extern int acl_get_entry(acl_t acl, int entry_id, acl_entry_t *entry_p);
+
+/* Manipulate ACL entry permissions */
+
+extern int acl_add_perm(acl_permset_t permset_d, acl_perm_t perm);
+extern int acl_calc_mask(acl_t *acl_p);
+extern int acl_clear_perms(acl_permset_t permset_d);
+extern int acl_delete_perm(acl_permset_t permset_d, acl_perm_t perm);
+extern int acl_get_permset(acl_entry_t entry_d, acl_permset_t *permset_p);
+extern int acl_set_permset(acl_entry_t entry_d, acl_permset_t permset_d);
+
+/* Manipulate ACL entry tag type and qualifier */
+
+extern void * acl_get_qualifier(acl_entry_t entry_d);
+extern int acl_get_tag_type(acl_entry_t entry_d, acl_tag_t *tag_type_p);
+extern int acl_set_qualifier(acl_entry_t entry_d, const void *tag_qualifier_p);
+extern int acl_set_tag_type(acl_entry_t entry_d, acl_tag_t tag_type);
+
+/*=== Format translation ===*/
+
+extern ssize_t acl_copy_ext(void *buf_p, acl_t acl, ssize_t size);
+extern acl_t acl_copy_int(const void *buf_p);
+extern acl_t acl_from_text(const char *buf_p);
+extern ssize_t acl_size(acl_t acl);
+extern char *acl_to_text(acl_t acl, ssize_t *len_p);
+
+/*=== Object manipulation ===*/
+
+extern int acl_delete_def_file(const char *path_p);
+extern acl_t acl_get_fd(int fd);
+extern acl_t acl_get_file(const char *path_p, acl_type_t type);
+extern int acl_set_fd(int fd, acl_t acl);
+extern int acl_set_file(const char *path_p, acl_type_t type, acl_t acl);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __SYS_ACL_H */
+
diff --git a/include/acl_ea.h b/include/acl_ea.h
new file mode 100644
index 0000000..eb5cc2f
--- /dev/null
+++ b/include/acl_ea.h
@@ -0,0 +1,52 @@
+/*
+ File: acl_ea.h
+
+ (extended attribute representation of access control lists)
+
+ Copyright (C) 2002 Andreas Gruenbacher, <agruen@suse.de>
+
+ This program is free software: you can redistribute it and/or modify it
+ under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation, either version 2.1 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 Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#define ACL_EA_ACCESS "system.posix_acl_access"
+#define ACL_EA_DEFAULT "system.posix_acl_default"
+
+#define ACL_EA_VERSION 0x0002
+
+typedef struct {
+ u_int16_t e_tag;
+ u_int16_t e_perm;
+ u_int32_t e_id;
+} acl_ea_entry;
+
+typedef struct {
+ u_int32_t a_version;
+ acl_ea_entry a_entries[0];
+} acl_ea_header;
+
+static inline size_t acl_ea_size(int count)
+{
+ return sizeof(acl_ea_header) + count * sizeof(acl_ea_entry);
+}
+
+static inline int acl_ea_count(size_t size)
+{
+ if (size < sizeof(acl_ea_header))
+ return -1;
+ size -= sizeof(acl_ea_header);
+ if (size % sizeof(acl_ea_entry))
+ return -1;
+ return size / sizeof(acl_ea_entry);
+}
+
diff --git a/include/builddefs.in b/include/builddefs.in
new file mode 100644
index 0000000..d054a56
--- /dev/null
+++ b/include/builddefs.in
@@ -0,0 +1,97 @@
+#
+# Copyright (c) 2002-2006 Silicon Graphics, Inc. All Rights Reserved.
+#
+# @configure_input@
+#
+
+ifndef _BUILDDEFS_INCLUDED_
+_BUILDDEFS_INCLUDED_ = 1
+
+DEBUG = @debug_build@
+OPTIMIZER = @opt_build@
+MALLOCLIB = @malloc_lib@
+LOADERFLAGS = @LDFLAGS@
+
+LIBACL = $(TOPDIR)/libacl/libacl.la
+LIBATTR = @libattr@
+LIBMISC = $(TOPDIR)/libmisc/libmisc.la
+
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+top_builddir = @top_builddir@
+datarootdir = @datarootdir@
+
+PKG_NAME = @pkg_name@
+PKG_USER = @pkg_user@
+PKG_GROUP = @pkg_group@
+PKG_RELEASE = @pkg_release@
+PKG_VERSION = @pkg_version@
+PKG_PLATFORM = @pkg_platform@
+PKG_DISTRIBUTION= @pkg_distribution@
+PKG_BIN_DIR = @bindir@
+PKG_SBIN_DIR = @sbindir@
+PKG_LIB_DIR = @libdir@@libdirsuffix@
+PKG_DEVLIB_DIR = @libexecdir@@libdirsuffix@
+PKG_INC_DIR = @includedir@
+PKG_MAN_DIR = @mandir@
+PKG_DOC_DIR = @datadir@/doc/@pkg_name@
+PKG_LOCALE_DIR = @datadir@/locale
+
+CC = @cc@
+AWK = @awk@
+SED = @sed@
+TAR = @tar@
+ZIP = @zip@
+MAKE = @make@
+ECHO = @echo@
+SORT = @sort@
+LN_S = @LN_S@
+LIBTOOL = @LIBTOOL@
+MAKEDEPEND = @makedepend@
+
+MSGFMT = @msgfmt@
+MSGMERGE = @msgmerge@
+XGETTEXT = @xgettext@
+
+RPM = @rpm@
+RPMBUILD = @rpmbuild@
+RPM_VERSION = @rpm_version@
+
+ENABLE_SHARED = @enable_shared@
+ENABLE_GETTEXT = @enable_gettext@
+
+HAVE_ZIPPED_MANPAGES = @have_zipped_manpages@
+
+ifneq "$(findstring $(PKG_PLATFORM), linux gnu gnu/kfreebsd gnu/knetbsd)" ""
+PCFLAGS = -D_GNU_SOURCE -D_FILE_OFFSET_BITS=64
+endif
+
+ifeq ($(PKG_PLATFORM),linux)
+DEPENDFLAGS = -D__linux__
+endif
+ifeq ($(PKG_PLATFORM),darwin)
+DEPENDFLAGS = -D__APPLE__
+endif
+ifeq ($(PKG_PLATFORM),irix)
+DEPENDFLAGS = -D__sgi__
+endif
+ifeq ($(PKG_PLATFORM),freebsd)
+DEPENDFLAGS = -D__FreeBSD__
+endif
+
+GCFLAGS = $(OPTIMIZER) $(DEBUG) -funsigned-char -fno-strict-aliasing -Wall \
+ -DVERSION=\"$(PKG_VERSION)\" -DLOCALEDIR=\"$(PKG_LOCALE_DIR)\" \
+ -DPACKAGE=\"$(PKG_NAME)\" -I$(TOPDIR)/include
+
+# Global, Platform, Local CFLAGS
+CFLAGS += $(GCFLAGS) $(PCFLAGS) $(LCFLAGS)
+
+include $(TOPDIR)/include/buildmacros
+
+endif
+
+#
+# For targets that should always be rebuilt,
+# define a target that is never up-to-date.
+# Targets needing this should depend on $(_FORCE)
+_FORCE = __force_build
diff --git a/include/buildmacros b/include/buildmacros
new file mode 100644
index 0000000..ab89182
--- /dev/null
+++ b/include/buildmacros
@@ -0,0 +1,162 @@
+#
+# Copyright (c) 2002-2003 Silicon Graphics, Inc. All Rights Reserved.
+#
+# 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 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 <http://www.gnu.org/licenses/>.
+#
+
+BUILDRULES = $(TOPDIR)/include/buildrules
+
+# LCFLAGS, LLDFLAGS, LLDLIBS, LSRCFILES and LDIRT may be specified in
+# user Makefiles. Note: LSRCFILES is anything other than Makefile, $(CFILES)
+# $(CXXFILES), or $(HFILES) and is used to construct the manifest list
+# during the "dist" phase (packaging).
+
+LDFLAGS += $(LOADERFLAGS) $(LLDFLAGS)
+LTLDFLAGS += $(LOADERFLAGS)
+LDLIBS = $(LLDLIBS) $(PLDLIBS) $(MALLOCLIB)
+
+MAKEOPTS = --no-print-directory
+SRCFILES = Makefile $(HFILES) $(CFILES) $(LSRCFILES) $(LFILES) $(YFILES)
+
+DEPDIRT = dep dep.bak
+MANDIRT = *.[1-9].gz
+PODIRT = *.tmpo *.mo
+CDIRT = $(OBJECTS) $(LTOBJECTS) $(LTCOMMAND) $(LTLIBRARY)
+DIRT = $(LDIRT) $(DEPDIRT) $(MANDIRT) $(PODIRT) $(CDIRT)
+
+OBJECTS = $(ASFILES:.s=.o) \
+ $(CFILES:.c=.o) \
+ $(LFILES:.l=.o) \
+ $(YFILES:%.y=%.tab.o)
+
+INSTALL = $(TOPDIR)/include/install-sh -o $(PKG_USER) -g $(PKG_GROUP)
+
+SHELL = /bin/sh
+IMAGES_DIR = $(TOPDIR)/all-images
+DIST_DIR = $(TOPDIR)/dist
+
+CCF = $(CC) $(CFLAGS) $(CPPFLAGS)
+MAKEF = $(MAKE) $(MAKEOPTS)
+CXXF = $(CXX) $(CXXFLAGS)
+
+# For libtool.
+LIBNAME = $(basename $(LTLIBRARY))
+LTOBJECTS = $(OBJECTS:.o=.lo)
+LTVERSION = $(LT_CURRENT):$(LT_REVISION):$(LT_AGE)
+
+LTLINK = $(LIBTOOL) --mode=link $(CC)
+LTEXEC = $(LIBTOOL) --mode=execute
+LTINSTALL = $(LIBTOOL) --mode=install $(INSTALL)
+LTCOMPILE = $(LIBTOOL) --mode=compile $(CCF)
+
+ifeq ($(ENABLE_SHARED),yes)
+LTLDFLAGS += -rpath $(PKG_LIB_DIR)
+LTLDFLAGS += -version-info $(LTVERSION)
+endif
+
+ifeq ($(ENABLE_SHARED),yes)
+INSTALL_LTLIB = \
+ cd $(TOPDIR)/$(LIBNAME)/.libs; \
+ ../$(INSTALL) -m 755 -d $(PKG_LIB_DIR); \
+ ../$(INSTALL) -m 644 -T so_dot_version $(LIBNAME).lai $(PKG_LIB_DIR); \
+ ../$(INSTALL) -T so_dot_current $(LIBNAME).lai $(PKG_LIB_DIR)
+endif
+
+# Libtool thinks the static and shared libs should be in the same dir, so
+# make the static lib appear in the place we chose as rpath (using the two
+# symlinks below).
+# Other things want the shared libs to appear in /usr/lib, else they'll
+# link with the static libs there. So, another symlink to get the .so into
+# /usr/lib.
+ifeq ($(ENABLE_SHARED),yes)
+INSTALL_LTLIB_DEV = \
+ cd $(TOPDIR)/$(LIBNAME)/.libs; \
+ ../$(INSTALL) -m 755 -d $(PKG_DEVLIB_DIR); \
+ ../$(INSTALL) -m 644 -T old_lib $(LIBNAME).lai $(PKG_DEVLIB_DIR); \
+ ../$(INSTALL) -m 644 $(LIBNAME).lai $(PKG_DEVLIB_DIR)/$(LIBNAME).la ; \
+ ../$(INSTALL) -m 755 -d $(PKG_LIB_DIR); \
+ ../$(INSTALL) -T so_base $(LIBNAME).lai $(PKG_LIB_DIR); \
+ if test "x$(PKG_DEVLIB_DIR)" != "x$(PKG_LIB_DIR)" ; then \
+ ../$(INSTALL) -S $(PKG_DEVLIB_DIR)/$(LIBNAME).a $(PKG_LIB_DIR)/$(LIBNAME).a; \
+ ../$(INSTALL) -S $(PKG_DEVLIB_DIR)/$(LIBNAME).la $(PKG_LIB_DIR)/$(LIBNAME).la; \
+ ../$(INSTALL) -S $(PKG_LIB_DIR)/$(LIBNAME).so $(PKG_DEVLIB_DIR)/$(LIBNAME).so; \
+ fi
+else
+INSTALL_LTLIB_DEV = $(INSTALL_LTLIB_STATIC)
+endif
+
+INSTALL_LTLIB_STATIC = \
+ cd $(TOPDIR)/$(LIBNAME)/.libs; \
+ ../$(INSTALL) -m 755 -d $(PKG_DEVLIB_DIR); \
+ ../$(INSTALL) -m 644 -T old_lib $(LIBNAME).lai $(PKG_DEVLIB_DIR)
+
+INSTALL_MAN = \
+ @for d in $(MAN_PAGES); do \
+ first=true; \
+ for m in `$(AWK) \
+ '/^\.S[h|H] NAME/ {ok=1; next} ok {print; exit}' $$d \
+ | $(SED) \
+ -e 's/^\.Nm //' -e 's/,/ /g' -e 's/\\-.*//' \
+ -e 's/\\\f[0-9]//g' -e 's/ / /g;q'`; \
+ do \
+ [ -z "$$m" -o "$$m" = "\\" ] && continue; \
+ t=$(MAN_DEST)/$$m.$(MAN_SECTION); \
+ if $$first; then \
+ if $(HAVE_ZIPPED_MANPAGES); then \
+ $(ZIP) -9 -c $$d > $$d.gz; _sfx=.gz; \
+ fi; \
+ u=$$m.$(MAN_SECTION)$$_sfx; \
+ echo $(INSTALL) -m 644 $${d}$$_sfx $${t}$$_sfx;\
+ $(INSTALL) -m 644 $${d}$$_sfx $${t}$$_sfx; \
+ else \
+ echo $(INSTALL) -S $$u $${t}$$_sfx; \
+ $(INSTALL) -S $$u $${t}$$_sfx; \
+ fi; \
+ first=false; \
+ done; \
+ done
+
+ifeq ($(ENABLE_GETTEXT),yes)
+INSTALL_LINGUAS = \
+ @for l in $(LINGUAS) ""; do \
+ if test -f "$$l.mo" ; then \
+ ldir=$(PKG_LOCALE_DIR)/$$l/LC_MESSAGES; \
+ $(INSTALL) -m 755 -d $$ldir; \
+ $(INSTALL) -m 644 $$l.mo $$ldir/$(PKG_NAME).mo; \
+ fi; \
+ done
+endif
+
+MAN_MAKERULE = \
+ @for f in *.[12345678] ""; do \
+ if test ! -z "$$f"; then \
+ $(ZIP) --best -c < $$f > $$f.gz; \
+ fi; \
+ done
+
+DIST_MAKERULE = \
+ $(MAKEF) -C build dist
+
+SOURCE_MAKERULE = \
+ @test -z "$$DIR" && DIR="."; \
+ for f in $(SRCFILES) ""; do \
+ test -z "$$f" && break; \
+ test -L "$$f" || $(ECHO) $$DIR/$$f; \
+ done; \
+ for d in `echo $(SUBDIRS)` ""; do \
+ test -z "$$d" && break; \
+ if test -d "$$d"; then \
+ $(MAKEF) DIR=$$DIR/$$d -C $$d $@ || exit $$?; \
+ fi; \
+ done
diff --git a/include/buildrules b/include/buildrules
new file mode 100644
index 0000000..159d70c
--- /dev/null
+++ b/include/buildrules
@@ -0,0 +1,104 @@
+#
+# Copyright (c) 1999, 2001-2003 Silicon Graphics, Inc. All Rights Reserved.
+#
+# 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 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 <http://www.gnu.org/licenses/>.
+#
+ifndef _BUILDRULES_INCLUDED_
+_BUILDRULES_INCLUDED_ = 1
+
+include $(TOPDIR)/include/builddefs
+
+clean clobber : $(addsuffix -clean,$(SUBDIRS))
+ rm -f $(DIRT)
+ @rm -fr .libs
+
+%-clean:
+ $(MAKE) -C $* clean
+
+# Never blow away subdirs
+ifdef SUBDIRS
+.PRECIOUS: $(SUBDIRS)
+.PHONY: $(SUBDIRS)
+
+$(SUBDIRS):
+ $(MAKE) -C $@
+endif
+
+#
+# Standard targets
+#
+
+ifdef LTCOMMAND
+$(LTCOMMAND) : $(SUBDIRS) $(OBJECTS) $(LTDEPENDENCIES)
+ $(LTLINK) -o $@ $(LDFLAGS) $(OBJECTS) $(LDLIBS)
+endif
+
+ifdef LTLIBRARY
+$(LTLIBRARY) : $(SUBDIRS) $(LTOBJECTS)
+ $(LTLINK) $(LTLDFLAGS) -o $(LTLIBRARY) $(LTOBJECTS) $(LTLIBS)
+
+%.lo: %.c
+ $(LTCOMPILE) -c $<
+endif
+
+ifdef POTHEAD
+%.pot: $(XGETTEXTFILES)
+ $(XGETTEXT) --language=C --keyword=_ -o $@ $(XGETTEXTFILES)
+
+# Generate temp .po files, to check whether translations need updating.
+# Not by default, due to gettext output differences between versions.
+%.po: $(POTHEAD)
+# $(MSGMERGE) -o $@.tmpo $@ $(POTHEAD)
+# if ! diff $@.tmpo $@ >/dev/null; then echo "$@ dated, see $@.tmpo"; fi
+
+%.mo: %.po
+ $(MSGFMT) -o $@ $<
+endif
+
+source :
+ $(SOURCE_MAKERULE)
+
+endif # _BUILDRULES_INCLUDED_
+
+$(_FORCE):
+
+.PHONY : depend
+
+DEPENDSCRIPT := $(MAKEDEPEND) $(DEPENDFLAGS) -f - -- $(CFLAGS) -- $(CFILES) | \
+ $(SED) -e 's,`pwd`,$(TOPDIR),g' \
+ -e 's, */[^ ]*,,g' \
+ -e '/^[^ ]*: *$$/d' \
+ -e '/^ *$$/d'
+
+ifdef LTLIBRARY
+DEPENDSCRIPT := $(DEPENDSCRIPT) | $(SED) -e 's,^\([^:]*\)\.o,\1.lo,'
+endif
+
+depend : $(CFILES) $(HFILES) $(addsuffix -depend,$(SUBDIRS))
+ $(DEPENDSCRIPT) > .dep
+ test -s .dep || rm -f .dep
+
+%-depend:
+ $(MAKE) -C $* depend
+
+# Include dep, but only if it exists
+ifeq ($(shell test -f .dep && echo .dep), .dep)
+include .dep
+else
+ifdef LTLIBRARY
+$(LTOBJECTS): $(HFILES)
+else
+$(OBJECTS): $(HFILES)
+endif
+endif
diff --git a/include/config.h.in b/include/config.h.in
new file mode 100644
index 0000000..6787b6e
--- /dev/null
+++ b/include/config.h.in
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2002 Silicon Graphics, Inc. All Rights Reserved.
+ *
+ * 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 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 <http://www.gnu.org/licenses/>.
+ *
+ * @configure_input@
+ */
+
+/* Define if you have the attr/error_context.h header */
+#undef HAVE_ATTR_ERROR_CONTEXT_H
+
+/* Define if you want Posix compliant getfacl and setfacl utilities
+ without extensions */
+#undef POSIXLY_CORRECT
+
+/* The number of bytes in a int. */
+#undef SIZEOF_INT
+
+/* The number of bytes in a long. */
+#undef SIZEOF_LONG
+
+/* The number of bytes in a short. */
+#undef SIZEOF_SHORT
+
+/* Define if you have attribute((visibility(hidden))) in gcc. */
+#undef HAVE_VISIBILITY_ATTRIBUTE
+
+/* Define if you want gettext (I18N) support */
+#undef ENABLE_GETTEXT
+
+#ifdef ENABLE_GETTEXT
+# include <libintl.h>
+# define _(x) gettext(x)
+#else
+# define _(x) (x)
+# define textdomain(d) do { } while (0)
+# define bindtextdomain(d,dir) do { } while (0)
+#endif
+#include <locale.h>
+
+/* On GNU/kFreeBSD, ENODATA is not defined in the system headers */
+#include <errno.h>
+#ifndef ENODATA
+# define ENODATA ENOATTR
+#endif
diff --git a/include/install-sh b/include/install-sh
new file mode 100755
index 0000000..86093a0
--- /dev/null
+++ b/include/install-sh
@@ -0,0 +1,363 @@
+#! /bin/sh
+#
+# Copyright (c) 2000-2001 Silicon Graphics, Inc. All Rights Reserved.
+#
+# 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 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, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+# This script emulates bsd install and also recognises
+# two environment variables, with the following semantics :-
+#
+# $DIST_MANIFEST - if set, the name of the file to append manifest
+# information in the following format:
+# File : f mode owner group src target
+# Directory: d mode owner group target
+# Symlink : l linkval target
+#
+# $DIST_ROOT - if set, prepend to target
+#
+# The sematics of all combinations of these two variables
+# are as follows:
+#
+# $DIST_MANIFEST? $DIST_ROOT? | Copy? Append Manifest?
+# -----------------------------+--------------------------
+# not set not set | yes no
+# not set set | yes no
+# set not set | no yes
+# set set | yes yes
+#
+_usage() {
+ echo "Usage: $prog [-o owner] [-g group] [-m mode] -d directory"
+ echo "or $prog [-D] [-o owner] [-g group] [-m mode] file directory/file"
+ echo "or $prog [-o owner] [-g group] [-m mode] file [file ...] directory"
+ echo "or $prog -S file target (creates \"target\" symlink)"
+ echo "or $prog -T lt_arg [-o owner] [-g group] [-m mode] libtool.lai directory"
+ echo ""
+ echo "The \$DIST_MANIFEST and \$DIST_ROOT environment variables affect the"
+ echo "behaviour of this command - see comments in the script."
+ echo "The -D flag is only available for the second usage, and causes"
+ echo "the target directory to be created before installing the file."
+ echo ""
+ exit 1
+}
+
+_chown ()
+{
+ _st=255
+ if [ $# -eq 3 ] ; then
+ chown $1:$2 $3
+ _st=$?
+ if [ $_st -ne 0 ] ; then
+ if [ $REAL_UID != '0' ] ; then
+ if [ ! -f $DIST_ROOT/.chown.quiet ] ; then
+ echo '==============================================='
+ echo Ownership of files under ${DIST_ROOT:-/}
+ echo cannot be changed
+ echo '==============================================='
+ if [ -n "$DIST_ROOT" ] ; then
+ touch $DIST_ROOT/.chown.quiet
+ fi
+ fi
+ _st=0
+ fi
+ fi
+ fi
+
+ return $_st
+}
+
+
+_manifest ()
+{
+ echo $* | sed -e 's/\/\//\//g' >>${DIST_MANIFEST:-/dev/null}
+}
+
+prog=`basename $0`
+HERE=`pwd`
+dflag=false
+Dflag=false
+Sflag=false
+Tflag=false
+DIRMODE=755
+FILEMODE=644
+OWNER=`id -u`
+GROUP=`id -g`
+REAL_UID=$OWNER
+
+# default is to install and don't append manifest
+INSTALL=true
+MANIFEST=:
+
+[ -n "$DIST_MANIFEST" -a -z "$DIST_ROOT" ] && INSTALL=false
+[ -n "$DIST_MANIFEST" ] && MANIFEST="_manifest"
+
+[ $# -eq 0 ] && _usage
+
+if $INSTALL
+then
+ CP=cp; LN=ln; MKDIR=mkdir; CHMOD=chmod; CHOWN=_chown
+else
+ CP=true; LN=true; MKDIR=true; CHMOD=true; CHOWN=true
+fi
+
+[ -n "$DIST_ROOT" -a $REAL_UID -ne 0 ] && CHOWN=true
+
+while getopts "Dcm:d:S:o:g:T:" c $*
+do
+ case $c in
+ c)
+ ;;
+ g)
+ GROUP=$OPTARG
+ ;;
+ o)
+ OWNER=$OPTARG
+ ;;
+ m)
+ DIRMODE=`expr $OPTARG`
+ FILEMODE=$DIRMODE
+ ;;
+ D)
+ Dflag=true
+ ;;
+ S)
+ symlink=$OPTARG
+ Sflag=true
+ ;;
+ d)
+ dir=$DIST_ROOT/$OPTARG
+ dflag=true
+ ;;
+ T)
+ lt_install=$OPTARG
+ Tflag=true
+ ;;
+ *)
+ _usage
+ ;;
+ esac
+done
+
+shift `expr $OPTIND - 1`
+
+status=0
+if $dflag
+then
+ #
+ # first usage
+ #
+ $MKDIR -p $dir
+ status=$?
+ if [ $status -eq 0 ]
+ then
+ $CHMOD $DIRMODE $dir
+ status=$?
+ fi
+ if [ $status -eq 0 ]
+ then
+ $CHOWN $OWNER $GROUP $dir
+ status=$?
+ fi
+ $MANIFEST d $DIRMODE $OWNER $GROUP ${dir#$DIST_ROOT}
+elif $Sflag
+then
+ #
+ # fourth usage (symlink)
+ #
+ if [ $# -ne 1 ]
+ then
+ _usage
+ else
+ target=$DIST_ROOT/$1
+ fi
+ $LN -s -f $symlink $target
+ status=$?
+ $MANIFEST l $symlink ${target#$DIST_ROOT}
+elif $Tflag
+then
+ #
+ # -T (install libs built by libtool)
+ #
+ if [ $# -ne 2 ]
+ then
+ _usage
+ else
+ libtool_lai=$1
+ # source the libtool variables
+ if [ ! -f $libtool_lai ]
+ then
+ echo "$prog: Unable to find libtool library file $libtool_lai"
+ exit 2
+ fi
+ . ./$libtool_lai
+ target=$DIST_ROOT/$2
+ fi
+ case $lt_install in
+ so_dot_version)
+ # Loop until we find libfoo.so.x.y.z, then break out.
+ for solib in $library_names
+ do
+ # does it have enough parts? libfoo.so.x.y.z == 5
+ cnt=`echo "$solib" | sed -e 's/\./ /g' | wc -w`
+ if [ $cnt -eq 5 ]
+ then
+ install_name=$target/$solib
+ $CP $solib $install_name
+ status=$?
+ $MANIFEST f $FILEMODE $OWNER $GROUP $HERE/$solib ${install_name#$DIST_ROOT}
+ break
+ fi
+ done
+ ;;
+
+ so_*)
+ case $lt_install in
+ so_dot_current)
+ # ln -s libfoo.so.x.y.z to libfoo.so.x
+ from_parts=5 # libfoo.so.x.y.z
+ to_parts=3 # libfoo.so.x
+ ;;
+ so_base)
+ # ln -s libfoo.so.x to libfoo.so
+ from_parts=3 # libfoo.so.x
+ to_parts=2 # libfoo.so
+ ;;
+ *)
+ echo "$prog: -T $lt_install invalid"
+ exit 2
+ ;;
+ esac
+
+ # Loop until we find the names, then break out.
+ for solib in $library_names
+ do
+ # does it have enough parts?
+ cnt=`echo "$solib" | sed -e 's/\./ /g' | wc -w`
+ if [ $cnt -eq $from_parts ]
+ then
+ from_name=$solib
+ elif [ $cnt -eq $to_parts ]
+ then
+ to_name=$solib
+ fi
+
+ if [ -n "$from_name" ] && [ -n "$to_name" ]
+ then
+ install_name=$target/$to_name
+ $LN -s -f $from_name $install_name
+ status=$?
+ $MANIFEST l $from_name ${install_name#$DIST_ROOT}
+ break
+ fi
+ done
+ ;;
+ old_lib)
+ install_name=$target/$old_library
+ $CP $old_library $install_name
+ status=$?
+ $MANIFEST f $FILEMODE $OWNER $GROUP $HERE/$old_library ${install_name#$DIST_ROOT}
+ ;;
+ *)
+ echo "$prog: -T $lt_install invalid"
+ exit 2
+ ;;
+ esac
+
+ case $lt_install in
+ old_lib|so_dot_version)
+ if [ $status -eq 0 ]
+ then
+ $CHMOD $FILEMODE $install_name
+ $CHOWN $OWNER $GROUP $install_name
+ fi
+ ;;
+ esac
+
+else
+ list=""
+ dir=""
+ if [ $# -eq 2 ]
+ then
+ #
+ # second usage
+ #
+ f=$1
+ dir=$DIST_ROOT/$2
+ if $Dflag
+ then
+ mkdir -p `dirname $dir`
+ fi
+ $CP $f $dir
+ status=$?
+ if [ $status -eq 0 ]
+ then
+ if [ -f $dir/$f ]
+ then
+ $CHMOD $FILEMODE $dir/$f
+ status=$?
+ if [ $status -eq 0 ]
+ then
+ $CHOWN $OWNER $GROUP $dir/$f
+ status=$?
+ fi
+ $MANIFEST f $FILEMODE $OWNER $GROUP $HERE/$f ${dir#$DIST_ROOT}/$f
+ else
+ $CHMOD $FILEMODE $dir
+ status=$?
+ if [ $status -eq 0 ]
+ then
+ $CHOWN $OWNER $GROUP $dir
+ status=$?
+ fi
+ $MANIFEST f $FILEMODE $OWNER $GROUP $HERE/$dir ${dir#$DIST_ROOT}
+ fi
+ fi
+ else
+ #
+ # third usage
+ #
+ n=1
+ while [ $# -gt 0 ]
+ do
+ if [ $# -gt 1 ]
+ then
+ list="$list $1"
+ else
+ dir=$DIST_ROOT/$1
+ fi
+ shift
+ done
+
+ # echo DIR=$dir list=\"$list\"
+ for f in $list
+ do
+ $CP $f $dir
+ status=$?
+ if [ $status -eq 0 ]
+ then
+ $CHMOD $FILEMODE $dir/$f
+ status=$?
+ if [ $status -eq 0 ]
+ then
+ $CHOWN $OWNER $GROUP $dir/$f
+ status=$?
+ fi
+ $MANIFEST f $FILEMODE $OWNER $GROUP $HERE/$f ${dir#$DIST_ROOT}/$f
+ fi
+ [ $status -ne 0 ] && break
+ done
+ fi
+fi
+
+exit $status
diff --git a/include/libacl.h b/include/libacl.h
new file mode 100644
index 0000000..41ec48e
--- /dev/null
+++ b/include/libacl.h
@@ -0,0 +1,79 @@
+/*
+ File: libacl.h
+
+ (C) 1999, 2000 Andreas Gruenbacher, <a.gruenbacher@computer.org>
+
+ This program is free software: you can redistribute it and/or modify it
+ under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation, either version 2.1 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 <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef __ACL_LIBACL_H
+#define __ACL_LIBACL_H
+
+#include <sys/acl.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Flags for acl_to_any_text() */
+
+/* Print NO, SOME or ALL effective permissions comments. SOME prints
+ effective rights comments for entries which have different permissions
+ than effective permissions. */
+#define TEXT_SOME_EFFECTIVE 0x01
+#define TEXT_ALL_EFFECTIVE 0x02
+
+/* Align effective permission comments to column 32 using tabs or
+ use a single tab. */
+#define TEXT_SMART_INDENT 0x04
+
+/* User and group IDs instead of names. */
+#define TEXT_NUMERIC_IDS 0x08
+
+/* Only output the first letter of entry types
+ ("u::rwx" instead of "user::rwx"). */
+#define TEXT_ABBREVIATE 0x10
+
+/* acl_check error codes */
+
+#define ACL_MULTI_ERROR (0x1000) /* multiple unique objects */
+#define ACL_DUPLICATE_ERROR (0x2000) /* duplicate Id's in entries */
+#define ACL_MISS_ERROR (0x3000) /* missing required entry */
+#define ACL_ENTRY_ERROR (0x4000) /* wrong entry type */
+
+extern char *acl_to_any_text(acl_t acl, const char *prefix,
+ char separator, int options);
+extern int acl_cmp(acl_t acl1, acl_t acl2);
+extern int acl_check(acl_t acl, int *last);
+extern acl_t acl_from_mode(mode_t mode);
+extern int acl_equiv_mode(acl_t acl, mode_t *mode_p);
+int acl_extended_file(const char *path_p);
+int acl_extended_fd(int fd);
+extern int acl_entries(acl_t acl);
+extern const char *acl_error(int code);
+extern int acl_get_perm(acl_permset_t permset_d, acl_perm_t perm);
+
+/* Copying permissions between files */
+struct error_context;
+extern int perm_copy_file (const char *, const char *,
+ struct error_context *);
+extern int perm_copy_fd (const char *, int, const char *, int,
+ struct error_context *);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __ACL_LIBACL_H */
+
diff --git a/libacl/Makefile b/libacl/Makefile
new file mode 100644
index 0000000..1224b65
--- /dev/null
+++ b/libacl/Makefile
@@ -0,0 +1,67 @@
+#
+# Copyright (c) 2000-2002 Silicon Graphics, Inc. All Rights Reserved.
+#
+# 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 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, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+
+TOPDIR = ..
+
+LTLDFLAGS += -Wl,--version-script,$(TOPDIR)/exports
+include $(TOPDIR)/include/builddefs
+
+LTLIBRARY = libacl.la
+LTLIBS = -lattr $(LIBMISC)
+LTDEPENDENCIES = $(LIBMISC)
+LT_CURRENT = 2
+LT_REVISION = 0
+LT_AGE = 1
+
+CFILES = $(POSIX_CFILES) $(LIBACL_CFILES) $(INTERNAL_CFILES) \
+ perm_copy_fd.c perm_copy_file.c
+HFILES = libobj.h libacl.h byteorder.h __acl_from_xattr.h __acl_to_xattr.h \
+ perm_copy.h
+
+LCFLAGS = -include perm_copy.h
+
+POSIX_CFILES = \
+ acl_add_perm.c acl_calc_mask.c acl_clear_perms.c acl_copy_entry.c \
+ acl_copy_ext.c acl_copy_int.c acl_create_entry.c acl_delete_def_file.c \
+ acl_delete_entry.c acl_delete_perm.c acl_dup.c acl_free.c \
+ acl_from_text.c acl_get_entry.c acl_get_fd.c acl_get_file.c \
+ acl_get_perm.c acl_get_permset.c acl_get_qualifier.c \
+ acl_get_tag_type.c acl_init.c acl_set_fd.c acl_set_file.c \
+ acl_set_permset.c acl_set_qualifier.c acl_set_tag_type.c acl_to_text.c \
+ acl_valid.c acl_size.c
+
+LIBACL_CFILES = \
+ acl_to_any_text.c acl_entries.c acl_check.c acl_error.c acl_cmp.c \
+ acl_extended_fd.c acl_extended_file.c acl_equiv_mode.c acl_from_mode.c
+
+INTERNAL_CFILES = \
+ __acl_to_any_text.c __acl_to_xattr.c __acl_from_xattr.c \
+ __acl_reorder_obj_p.c __libobj.c __apply_mask_to_mode.c
+
+
+default: $(LTLIBRARY)
+
+include $(BUILDRULES)
+
+install:
+
+install-dev: default
+ $(INSTALL_LTLIB_DEV)
+
+install-lib: default
+ $(INSTALL_LTLIB)
diff --git a/libacl/__acl_from_xattr.c b/libacl/__acl_from_xattr.c
new file mode 100644
index 0000000..34f14a0
--- /dev/null
+++ b/libacl/__acl_from_xattr.c
@@ -0,0 +1,93 @@
+/*
+ File: __acl_from_xattr.c
+
+ Copyright (C) 1999, 2000
+ Andreas Gruenbacher, <a.gruenbacher@bestbits.at>
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#include "libacl.h"
+
+#include "byteorder.h"
+#include "acl_ea.h"
+
+
+acl_t
+__acl_from_xattr(const char *ext_acl_p, size_t size)
+{
+ acl_ea_header *ext_header_p = (acl_ea_header *)ext_acl_p;
+ acl_ea_entry *ext_entry_p = (acl_ea_entry *)(ext_header_p+1);
+ acl_ea_entry *ext_end_p;
+ acl_obj *acl_obj_p;
+ acl_entry_obj *entry_obj_p;
+ int entries, error;
+
+ if (size < sizeof(acl_ea_header)) {
+ errno = EINVAL;
+ return NULL;
+ }
+ if (ext_header_p->a_version != cpu_to_le32(ACL_EA_VERSION)) {
+ errno = EINVAL;
+ return NULL;
+ }
+ size -= sizeof(acl_ea_header);
+ if (size % sizeof(acl_ea_entry)) {
+ errno = EINVAL;
+ return NULL;
+ }
+ entries = size / sizeof(acl_ea_entry);
+ ext_end_p = ext_entry_p + entries;
+
+ acl_obj_p = __acl_init_obj(entries);
+ if (acl_obj_p == NULL)
+ return NULL;
+ while (ext_end_p != ext_entry_p) {
+ entry_obj_p = __acl_create_entry_obj(acl_obj_p);
+ if (!entry_obj_p)
+ goto fail;
+
+ entry_obj_p->etag = le16_to_cpu(ext_entry_p->e_tag);
+ entry_obj_p->eperm.sperm = le16_to_cpu(ext_entry_p->e_perm);
+
+ switch(entry_obj_p->etag) {
+ case ACL_USER_OBJ:
+ case ACL_GROUP_OBJ:
+ case ACL_MASK:
+ case ACL_OTHER:
+ entry_obj_p->eid.qid = ACL_UNDEFINED_ID;
+ break;
+
+ case ACL_USER:
+ case ACL_GROUP:
+ entry_obj_p->eid.qid =
+ le32_to_cpu(ext_entry_p->e_id);
+ break;
+
+ default:
+ error = EINVAL;
+ goto fail;
+ }
+ ext_entry_p++;
+ }
+ if (__acl_reorder_obj_p(acl_obj_p))
+ goto fail;
+ return int2ext(acl_obj_p);
+
+fail:
+ __acl_free_acl_obj(acl_obj_p);
+ return NULL;
+}
+
diff --git a/libacl/__acl_from_xattr.h b/libacl/__acl_from_xattr.h
new file mode 100644
index 0000000..4492a34
--- /dev/null
+++ b/libacl/__acl_from_xattr.h
@@ -0,0 +1 @@
+acl_t __acl_from_xattr(const char *ext_acl_p, size_t size);
diff --git a/libacl/__acl_reorder_obj_p.c b/libacl/__acl_reorder_obj_p.c
new file mode 100644
index 0000000..c03fea5
--- /dev/null
+++ b/libacl/__acl_reorder_obj_p.c
@@ -0,0 +1,134 @@
+/*
+ File: __acl_reorder_obj_p.c
+ (Linux Access Control List Management, Posix Library Functions)
+
+ Copyright (C) 1999, 2000
+ Andreas Gruenbacher, <a.gruenbacher@bestbits.at>
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#include <alloca.h>
+#include "libacl.h"
+
+
+static inline int
+__acl_entry_p_compare(const acl_entry_obj *a_p, const acl_entry_obj *b_p)
+{
+ if (a_p->etag < b_p->etag)
+ return -1;
+ else if (a_p->etag > b_p->etag)
+ return 1;
+
+ if (a_p->eid.qid < b_p->eid.qid)
+ return -1;
+ else if (a_p->eid.qid > b_p->eid.qid)
+ return 1;
+ else
+ return 0;
+}
+
+
+static int
+__acl_entry_pp_compare(const void *a, const void *b)
+{
+ return __acl_entry_p_compare(*(const acl_entry_obj **)a,
+ *(const acl_entry_obj **)b);
+}
+
+
+/*
+ Take an ACL entry form its current place in the entry ring,
+ and insert it at its proper place. Entries that are not valid
+ (yet) are not reordered.
+*/
+int
+__acl_reorder_entry_obj_p(acl_entry_obj *entry_obj_p)
+{
+ acl_obj *acl_obj_p = entry_obj_p->econtainer;
+ acl_entry_obj *here_obj_p;
+
+ if (acl_obj_p->aused <= 1)
+ return 0;
+ switch(entry_obj_p->etag) {
+ case ACL_UNDEFINED_TAG:
+ return 1;
+ case ACL_USER:
+ case ACL_GROUP:
+ if (qualifier_obj_id(entry_obj_p->eid) ==
+ ACL_UNDEFINED_ID)
+ return 1;
+ }
+
+ /* Remove entry from ring */
+ entry_obj_p->eprev->enext = entry_obj_p->enext;
+ entry_obj_p->enext->eprev = entry_obj_p->eprev;
+
+ /* Search for next greater entry */
+ FOREACH_ACL_ENTRY(here_obj_p, acl_obj_p) {
+ if (__acl_entry_p_compare(here_obj_p, entry_obj_p) > 0)
+ break;
+ }
+
+ /* Re-insert entry into ring */
+ entry_obj_p->eprev = here_obj_p->eprev;
+ entry_obj_p->enext = here_obj_p;
+ entry_obj_p->eprev->enext = entry_obj_p;
+ entry_obj_p->enext->eprev = entry_obj_p;
+
+ return 0;
+}
+
+
+/*
+ Sort all ACL entries at once, after initializing them. This function is
+ only used when converting complete ACLs from external formats to ACLs;
+ the ACL entries are always kept in canonical order while an ACL is
+ manipulated.
+*/
+int
+__acl_reorder_obj_p(acl_obj *acl_obj_p)
+{
+ acl_entry_obj **vector = alloca(sizeof(acl_entry_obj *) *
+ acl_obj_p->aused), **v, *x;
+ acl_entry_obj *entry_obj_p;
+
+ if (acl_obj_p->aused <= 1)
+ return 0;
+
+ v = vector;
+ FOREACH_ACL_ENTRY(entry_obj_p, acl_obj_p) {
+ *v++ = entry_obj_p;
+ }
+
+ qsort(vector, acl_obj_p->aused, sizeof(acl_entry_obj *),
+ __acl_entry_pp_compare);
+
+ x = (acl_entry_obj *)acl_obj_p;
+ for (v = vector; v != vector + acl_obj_p->aused; v++) {
+ (*v)->eprev = x;
+ x = *v;
+ }
+ acl_obj_p->aprev = *(vector + acl_obj_p->aused - 1);
+
+ x = (acl_entry_obj *)acl_obj_p;
+ for (v = vector + acl_obj_p->aused - 1; v != vector - 1; v--) {
+ (*v)->enext = x;
+ x = *v;
+ }
+ acl_obj_p->anext = *vector;
+ return 0;
+}
+
diff --git a/libacl/__acl_to_any_text.c b/libacl/__acl_to_any_text.c
new file mode 100644
index 0000000..22abc97
--- /dev/null
+++ b/libacl/__acl_to_any_text.c
@@ -0,0 +1,345 @@
+/*
+ File: __acl_to_any_text.c
+
+ Copyright (C) 1999, 2000
+ Andreas Gruenbacher, <a.gruenbacher@bestbits.at>
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#include <stdio.h>
+#include <errno.h>
+#include <string.h>
+#include <pwd.h>
+#include <grp.h>
+#include <acl/libacl.h>
+#include "libacl.h"
+#include "misc.h"
+
+static ssize_t acl_entry_to_any_str(const acl_entry_t entry_d, char *text_p,
+ ssize_t size, const acl_entry_t mask_d,
+ const char *prefix, int options);
+static ssize_t snprint_uint(char *text_p, ssize_t size, unsigned int i);
+static const char *user_name(uid_t uid);
+static const char *group_name(gid_t uid);
+
+char *
+__acl_to_any_text(acl_t acl, ssize_t *len_p, const char *prefix,
+ char separator, const char *suffix, int options)
+{
+ acl_obj *acl_obj_p = ext2int(acl, acl);
+ ssize_t size, len = 0, entry_len = 0,
+ suffix_len = suffix ? strlen(suffix) : 0;
+ string_obj *string_obj_p, *tmp;
+ acl_entry_obj *entry_obj_p, *mask_obj_p = NULL;
+ if (!acl_obj_p)
+ return NULL;
+ size = acl->a_used * 15 + 1;
+ string_obj_p = new_var_obj_p(string, size);
+ if (!string_obj_p)
+ return NULL;
+
+ if (options & (TEXT_SOME_EFFECTIVE|TEXT_ALL_EFFECTIVE)) {
+ /* fetch the ACL_MASK entry */
+ FOREACH_ACL_ENTRY(entry_obj_p, acl_obj_p) {
+ if (entry_obj_p->etag == ACL_MASK) {
+ mask_obj_p = entry_obj_p;
+ break;
+ }
+ }
+ }
+
+ FOREACH_ACL_ENTRY(entry_obj_p, acl_obj_p) {
+ repeat:
+ entry_len = acl_entry_to_any_str(int2ext(entry_obj_p),
+ string_obj_p->sstr + len,
+ size-len,
+ int2ext(mask_obj_p),
+ prefix,
+ options);
+ if (entry_len < 0)
+ goto fail;
+ else if (len + entry_len + suffix_len + 1 > size) {
+ while (len + entry_len + suffix_len + 1 > size)
+ size <<= 1;
+ tmp = realloc_var_obj_p(string, string_obj_p, size);
+ if (tmp == NULL)
+ goto fail;
+ string_obj_p = tmp;
+ goto repeat;
+ } else
+ len += entry_len;
+ string_obj_p->sstr[len] = separator;
+ len++;
+ }
+ if (len)
+ len--;
+ if (len && suffix) {
+ strcpy(string_obj_p->sstr + len, suffix);
+ len += suffix_len;
+ } else
+ string_obj_p->sstr[len] = '\0';
+
+ if (len_p)
+ *len_p = len;
+ return (char *)int2ext(string_obj_p);
+
+fail:
+ free_obj_p(string_obj_p);
+ return NULL;
+}
+
+#define ADVANCE(x) \
+ text_p += (x); \
+ size -= (x); \
+ if (size < 0) \
+ size = 0;
+
+#define ABBREV(s, str_len) \
+ if (options & TEXT_ABBREVIATE) { \
+ if (size > 0) \
+ text_p[0] = *(s); \
+ if (size > 1) \
+ text_p[1] = ':'; \
+ ADVANCE(2); \
+ } else { \
+ strncpy(text_p, (s), size); \
+ ADVANCE(str_len); \
+ }
+
+#define EFFECTIVE_STR "#effective:"
+
+static ssize_t
+acl_entry_to_any_str(const acl_entry_t entry_d, char *text_p, ssize_t size,
+ const acl_entry_t mask_d, const char *prefix, int options)
+{
+ #define TABS 4
+ static const char *tabs = "\t\t\t\t";
+ acl_entry_obj *entry_obj_p = ext2int(acl_entry, entry_d);
+ acl_entry_obj *mask_obj_p = NULL;
+ permset_t effective;
+ acl_tag_t type;
+ ssize_t x;
+ const char *orig_text_p = text_p, *str;
+ if (!entry_obj_p)
+ return -1;
+ if (mask_d) {
+ mask_obj_p = ext2int(acl_entry, mask_d);
+ if (!mask_obj_p)
+ return -1;
+ }
+ if (text_p == NULL)
+ size = 0;
+
+ if (prefix) {
+ strncpy(text_p, prefix, size);
+ ADVANCE(strlen(prefix));
+ }
+
+ type = entry_obj_p->etag;
+ switch (type) {
+ case ACL_USER_OBJ: /* owner */
+ mask_obj_p = NULL;
+ /* fall through */
+ case ACL_USER: /* additional user */
+ ABBREV("user:", 5);
+ if (type == ACL_USER) {
+ if (options & TEXT_NUMERIC_IDS)
+ str = NULL;
+ else
+ str = quote(user_name(
+ entry_obj_p->eid.qid));
+ if (str != NULL) {
+ strncpy(text_p, str, size);
+ ADVANCE(strlen(str));
+ } else {
+ x = snprint_uint(text_p, size,
+ entry_obj_p->eid.qid);
+ ADVANCE(x);
+ }
+ }
+ if (size > 0)
+ *text_p = ':';
+ ADVANCE(1);
+ break;
+
+ case ACL_GROUP_OBJ: /* owning group */
+ case ACL_GROUP: /* additional group */
+ ABBREV("group:", 6);
+ if (type == ACL_GROUP) {
+ if (options & TEXT_NUMERIC_IDS)
+ str = NULL;
+ else
+ str = quote(group_name(
+ entry_obj_p->eid.qid));
+ if (str != NULL) {
+ strncpy(text_p, str, size);
+ ADVANCE(strlen(str));
+ } else {
+ x = snprint_uint(text_p, size,
+ entry_obj_p->eid.qid);
+ ADVANCE(x);
+ }
+ }
+ if (size > 0)
+ *text_p = ':';
+ ADVANCE(1);
+ break;
+
+ case ACL_MASK: /* acl mask */
+ mask_obj_p = NULL;
+ ABBREV("mask:", 5);
+ if (size > 0)
+ *text_p = ':';
+ ADVANCE(1);
+ break;
+
+ case ACL_OTHER: /* other users */
+ mask_obj_p = NULL;
+ /* fall through */
+ ABBREV("other:", 6);
+ if (size > 0)
+ *text_p = ':';
+ ADVANCE(1);
+ break;
+
+ default:
+ return 0;
+ }
+
+ switch ((size >= 3) ? 3 : size) {
+ case 3:
+ text_p[2] = (entry_obj_p->eperm.sperm &
+ ACL_EXECUTE) ? 'x' : '-';
+ /* fall through */
+ case 2:
+ text_p[1] = (entry_obj_p->eperm.sperm &
+ ACL_WRITE) ? 'w' : '-';
+ /* fall through */
+ case 1:
+ text_p[0] = (entry_obj_p->eperm.sperm &
+ ACL_READ) ? 'r' : '-';
+ break;
+ }
+ ADVANCE(3);
+
+ if (mask_obj_p &&
+ (options & (TEXT_SOME_EFFECTIVE|TEXT_ALL_EFFECTIVE))) {
+ mask_obj_p = ext2int(acl_entry, mask_d);
+ if (!mask_obj_p)
+ return -1;
+
+ effective = entry_obj_p->eperm.sperm &
+ mask_obj_p->eperm.sperm;
+ if (effective != entry_obj_p->eperm.sperm ||
+ options & TEXT_ALL_EFFECTIVE) {
+ x = (options & TEXT_SMART_INDENT) ?
+ ((text_p - orig_text_p)/8) : TABS-1;
+ strncpy(text_p, tabs+x, size);
+ ADVANCE(TABS-x);
+
+ strncpy(text_p, EFFECTIVE_STR, size);
+ ADVANCE(sizeof(EFFECTIVE_STR)-1);
+
+ switch ((size >= 3) ? 3 : size) {
+ case 3:
+ text_p[2] = (effective &
+ ACL_EXECUTE) ? 'x' : '-';
+ /* fall through */
+ case 2:
+ text_p[1] = (effective &
+ ACL_WRITE) ? 'w' : '-';
+ /* fall through */
+ case 1:
+ text_p[0] = (effective &
+ ACL_READ) ? 'r' : '-';
+ break;
+ }
+ ADVANCE(3);
+
+ }
+ }
+
+ /* zero-terminate string (but don't count '\0' character) */
+ if (size > 0)
+ *text_p = '\0';
+
+ return (text_p - orig_text_p); /* total size required, excluding
+ final NULL character. */
+}
+
+#undef ADVANCE
+
+
+
+/*
+ This function is equivalent to the proposed changes to snprintf:
+ snprintf(text_p, size, "%u", i)
+ (The current snprintf returns -1 if the buffer is too small; the proposal
+ is to return the number of characters that would be required. See the
+ snprintf manual page.)
+*/
+
+static ssize_t
+snprint_uint(char *text_p, ssize_t size, unsigned int i)
+{
+ unsigned int tmp = i;
+ int digits = 1;
+ unsigned int factor = 1;
+
+ while ((tmp /= 10) != 0) {
+ digits++;
+ factor *= 10;
+ }
+ if (size && (i == 0)) {
+ *text_p++ = '0';
+ } else {
+ while (size > 0 && factor > 0) {
+ *text_p++ = '0' + (i / factor);
+ size--;
+ i %= factor;
+ factor /= 10;
+ }
+ }
+ if (size)
+ *text_p = '\0';
+
+ return digits;
+}
+
+
+static const char *
+user_name(uid_t uid)
+{
+ struct passwd *passwd = getpwuid(uid);
+
+ if (passwd != NULL)
+ return passwd->pw_name;
+ else
+ return NULL;
+}
+
+
+static const char *
+group_name(gid_t gid)
+{
+ struct group *group = getgrgid(gid);
+
+ if (group != NULL)
+ return group->gr_name;
+ else
+ return NULL;
+}
+
diff --git a/libacl/__acl_to_xattr.c b/libacl/__acl_to_xattr.c
new file mode 100644
index 0000000..afd8116
--- /dev/null
+++ b/libacl/__acl_to_xattr.c
@@ -0,0 +1,63 @@
+/*
+ File: __acl_to_xattr.c
+
+ Copyright (C) 1999, 2000
+ Andreas Gruenbacher, <a.gruenbacher@bestbits.at>
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#include <errno.h>
+#include <sys/acl.h>
+#include "libacl.h"
+
+#include "byteorder.h"
+#include "acl_ea.h"
+
+
+char *
+__acl_to_xattr(const acl_obj *acl_obj_p, size_t *size)
+{
+ const acl_entry_obj *entry_obj_p;
+ acl_ea_header *ext_header_p;
+ acl_ea_entry *ext_ent_p;
+
+ *size = sizeof(acl_ea_header) + acl_obj_p->aused * sizeof(acl_ea_entry);
+ ext_header_p = (acl_ea_header *)malloc(*size);
+ if (!ext_header_p)
+ return NULL;
+
+ ext_header_p->a_version = cpu_to_le32(ACL_EA_VERSION);
+ ext_ent_p = (acl_ea_entry *)(ext_header_p+1);
+ FOREACH_ACL_ENTRY(entry_obj_p, acl_obj_p) {
+ ext_ent_p->e_tag = cpu_to_le16(entry_obj_p->etag);
+ ext_ent_p->e_perm = cpu_to_le16(entry_obj_p->eperm.sperm);
+
+ switch(entry_obj_p->etag) {
+ case ACL_USER:
+ case ACL_GROUP:
+ ext_ent_p->e_id =
+ cpu_to_le32(entry_obj_p->eid.qid);
+ break;
+
+ default:
+ ext_ent_p->e_id = ACL_UNDEFINED_ID;
+ break;
+ }
+ ext_ent_p++;
+ }
+ return (char *)ext_header_p;
+}
+
diff --git a/libacl/__acl_to_xattr.h b/libacl/__acl_to_xattr.h
new file mode 100644
index 0000000..c8fd0b4
--- /dev/null
+++ b/libacl/__acl_to_xattr.h
@@ -0,0 +1 @@
+char *__acl_to_xattr(const acl_obj *acl_obj_p, size_t *size);
diff --git a/libacl/__apply_mask_to_mode.c b/libacl/__apply_mask_to_mode.c
new file mode 100644
index 0000000..3e5421b
--- /dev/null
+++ b/libacl/__apply_mask_to_mode.c
@@ -0,0 +1,68 @@
+/*
+ File: __apply_mask_to_mode.c
+ (Linux Access Control List Management)
+
+ Copyright (C) 1999-2002
+ Andreas Gruenbacher, <a.gruenbacher@bestbits.at>
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#include <sys/stat.h>
+#include <acl/libacl.h>
+#include "libacl.h"
+
+#if defined(HAVE_ACL_ENTRIES) && \
+ defined (HAVE_ACL_GET_ENTRY) && defined(HAVE_ACL_GET_TAG_TYPE) && \
+ defined (HAVE_ACL_GET_PERMSET) && defined(HAVE_ACL_GET_PERM)
+int
+__apply_mask_to_mode(mode_t *mode, acl_t acl)
+{
+ acl_entry_t entry;
+ int entry_id=ACL_FIRST_ENTRY;
+
+ /* A mimimal ACL which has three entries has no mask entry; the
+ group file mode permission bits are exact. */
+ if (acl_entries(acl) == 3)
+ return 0;
+
+ while (acl_get_entry(acl, entry_id, &entry) == 1) {
+ acl_tag_t tag_type;
+
+ acl_get_tag_type(entry, &tag_type);
+ if (tag_type == ACL_MASK) {
+ acl_permset_t permset;
+
+ acl_get_permset(entry, &permset);
+ if (acl_get_perm(permset, ACL_READ) != 1)
+ *mode &= ~S_IRGRP;
+ if (acl_get_perm(permset, ACL_WRITE) != 1)
+ *mode &= ~S_IWGRP;
+ if (acl_get_perm(permset, ACL_EXECUTE) != 1)
+ *mode &= ~S_IXGRP;
+
+ return 0;
+ }
+ entry_id = ACL_NEXT_ENTRY;
+ }
+
+ /* This is unexpected; if the ACL didn't include a mask entry
+ we should have exited before the loop! */
+ *mode &= ~S_IRWXG;
+ return 1;
+}
+#endif
+
+
diff --git a/libacl/__libobj.c b/libacl/__libobj.c
new file mode 100644
index 0000000..c3bc1e8
--- /dev/null
+++ b/libacl/__libobj.c
@@ -0,0 +1,93 @@
+/*
+ File: __libobj.c
+ (Linux Access Control List Management)
+
+ Copyright (C) 1999-2002
+ Andreas Gruenbacher, <a.gruenbacher@bestbits.at>
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#include <errno.h>
+#include <stdlib.h>
+#include "libobj.h"
+
+#ifdef LIBACL_DEBUG
+# include <stdio.h>
+#endif
+
+/* object creation, destruction, conversion and validation */
+
+void *
+__new_var_obj_p(int magic, size_t size)
+{
+ obj_prefix *obj_p = (obj_prefix *)malloc(size);
+ if (obj_p) {
+ obj_p->p_magic = (long)magic;
+ obj_p->p_flags = OBJ_MALLOC_FLAG;
+ }
+ return obj_p;
+}
+
+
+void
+__new_obj_p_here(int magic, void *here)
+{
+ obj_prefix *obj_p = here;
+ obj_p->p_magic = (long)magic;
+ obj_p->p_flags = 0;
+}
+
+
+void
+__free_obj_p(obj_prefix *obj_p)
+{
+ obj_p->p_magic = 0;
+ if (obj_p->p_flags & OBJ_MALLOC_FLAG)
+ free(obj_p);
+}
+
+
+obj_prefix *
+__check_obj_p(obj_prefix *obj_p, int magic)
+{
+ if (!obj_p || obj_p->p_magic != (long)magic) {
+ errno = EINVAL;
+ return NULL;
+ }
+ return obj_p;
+}
+
+
+#ifdef LIBACL_DEBUG
+obj_prefix *
+__ext2int_and_check(void *ext_p, int magic, const char *typename)
+#else
+obj_prefix *
+__ext2int_and_check(void *ext_p, int magic)
+#endif
+{
+ obj_prefix *obj_p = ((obj_prefix *)ext_p)-1;
+ if (!ext_p) {
+#ifdef LIBACL_DEBUG
+ fprintf(stderr, "invalid %s object at %p\n",
+ typename, obj_p);
+#endif
+ errno = EINVAL;
+ return NULL;
+ }
+ return __check_obj_p(obj_p, magic);
+}
+
diff --git a/libacl/acl_add_perm.c b/libacl/acl_add_perm.c
new file mode 100644
index 0000000..20818db
--- /dev/null
+++ b/libacl/acl_add_perm.c
@@ -0,0 +1,35 @@
+/*
+ File: acl_add_perm.c
+
+ Copyright (C) 1999, 2000
+ Andreas Gruenbacher, <a.gruenbacher@bestbits.at>
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#include "libacl.h"
+
+
+/* 23.4.1 */
+int
+acl_add_perm(acl_permset_t permset_d, acl_perm_t perm)
+{
+ acl_permset_obj *acl_permset_obj_p = ext2int(acl_permset, permset_d);
+ if (!acl_permset_obj_p || (perm & !(ACL_READ|ACL_WRITE|ACL_EXECUTE)))
+ return -1;
+ acl_permset_obj_p->sperm |= perm;
+ return 0;
+}
+
diff --git a/libacl/acl_calc_mask.c b/libacl/acl_calc_mask.c
new file mode 100644
index 0000000..b2ec91a
--- /dev/null
+++ b/libacl/acl_calc_mask.c
@@ -0,0 +1,67 @@
+/*
+ File: acl_calc_mask.c
+
+ Copyright (C) 1999, 2000
+ Andreas Gruenbacher, <a.gruenbacher@bestbits.at>
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#include "libacl.h"
+
+
+/* 23.4.2 */
+int
+acl_calc_mask(acl_t *acl_p)
+{
+ acl_obj *acl_obj_p;
+ acl_entry_obj *entry_obj_p, *mask_obj_p = NULL;
+ permset_t perm = ACL_PERM_NONE;
+ if (!acl_p) {
+ errno = EINVAL;
+ return -1;
+ }
+ acl_obj_p = ext2int(acl, *acl_p);
+ if (!acl_obj_p)
+ return -1;
+ FOREACH_ACL_ENTRY(entry_obj_p, acl_obj_p) {
+ switch(entry_obj_p->etag) {
+ case ACL_USER_OBJ:
+ case ACL_OTHER:
+ break;
+ case ACL_MASK:
+ mask_obj_p = entry_obj_p;
+ break;
+ case ACL_USER:
+ case ACL_GROUP_OBJ:
+ case ACL_GROUP:
+ perm |= entry_obj_p->eperm.sperm;
+ break;
+ default:
+ errno = EINVAL;
+ return -1;
+ }
+ }
+ if (mask_obj_p == NULL) {
+ mask_obj_p = __acl_create_entry_obj(acl_obj_p);
+ if (mask_obj_p == NULL)
+ return -1;
+ mask_obj_p->etag = ACL_MASK;
+ __acl_reorder_entry_obj_p(mask_obj_p);
+ }
+ mask_obj_p->eperm.sperm = perm;
+ return 0;
+}
+
diff --git a/libacl/acl_check.c b/libacl/acl_check.c
new file mode 100644
index 0000000..ebbc050
--- /dev/null
+++ b/libacl/acl_check.c
@@ -0,0 +1,128 @@
+/*
+ File: acl_check.c
+
+ Copyright (C) 1999, 2000
+ Andreas Gruenbacher, <a.gruenbacher@bestbits.at>
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#include <stdio.h>
+#include <errno.h>
+#include <acl/libacl.h>
+#include "libacl.h"
+
+
+#define FAIL_CHECK(error) \
+ do { return error; } while (0)
+
+/*
+ Check if an ACL is valid.
+
+ The e_id fields of ACL entries that don't use them are ignored.
+
+ last
+ contains the index of the last valid entry found
+ after acl_check returns.
+ returns
+ 0 on success, -1 on error, or an ACL_*_ERROR value for invalid ACLs.
+*/
+
+int
+acl_check(acl_t acl, int *last)
+{
+ acl_obj *acl_obj_p = ext2int(acl, acl);
+ id_t qual = 0;
+ int state = ACL_USER_OBJ;
+ acl_entry_obj *entry_obj_p;
+ int needs_mask = 0;
+
+ if (!acl_obj_p)
+ return -1;
+ if (last)
+ *last = 0;
+ FOREACH_ACL_ENTRY(entry_obj_p, acl_obj_p) {
+ /* Check permissions for ~(ACL_READ|ACL_WRITE|ACL_EXECUTE) */
+ switch (entry_obj_p->etag) {
+ case ACL_USER_OBJ:
+ if (state == ACL_USER_OBJ) {
+ qual = 0;
+ state = ACL_USER;
+ break;
+ }
+ FAIL_CHECK(ACL_MULTI_ERROR);
+
+ case ACL_USER:
+ if (state != ACL_USER)
+ FAIL_CHECK(ACL_MISS_ERROR);
+ if (qualifier_obj_id(entry_obj_p->eid) < qual ||
+ qualifier_obj_id(entry_obj_p->eid) ==
+ ACL_UNDEFINED_ID)
+ FAIL_CHECK(ACL_DUPLICATE_ERROR);
+ qual = qualifier_obj_id(entry_obj_p->eid)+1;
+ needs_mask = 1;
+ break;
+
+ case ACL_GROUP_OBJ:
+ if (state == ACL_USER) {
+ qual = 0;
+ state = ACL_GROUP;
+ break;
+ }
+ if (state >= ACL_GROUP)
+ FAIL_CHECK(ACL_MULTI_ERROR);
+ FAIL_CHECK(ACL_MISS_ERROR);
+
+ case ACL_GROUP:
+ if (state != ACL_GROUP)
+ FAIL_CHECK(ACL_MISS_ERROR);
+ if (qualifier_obj_id(entry_obj_p->eid) < qual ||
+ qualifier_obj_id(entry_obj_p->eid) ==
+ ACL_UNDEFINED_ID)
+ FAIL_CHECK(ACL_DUPLICATE_ERROR);
+ qual = qualifier_obj_id(entry_obj_p->eid)+1;
+ needs_mask = 1;
+ break;
+
+ case ACL_MASK:
+ if (state == ACL_GROUP) {
+ state = ACL_OTHER;
+ break;
+ }
+ if (state >= ACL_OTHER)
+ FAIL_CHECK(ACL_MULTI_ERROR);
+ FAIL_CHECK(ACL_MISS_ERROR);
+
+ case ACL_OTHER:
+ if (state == ACL_OTHER ||
+ (state == ACL_GROUP && !needs_mask)) {
+ state = 0;
+ break;
+ }
+ FAIL_CHECK(ACL_MISS_ERROR);
+
+ default:
+ FAIL_CHECK(ACL_ENTRY_ERROR);
+ }
+ if (last)
+ (*last)++;
+ }
+
+ if (state != 0)
+ FAIL_CHECK(ACL_MISS_ERROR);
+ return 0;
+}
+#undef FAIL_CHECK
+
diff --git a/libacl/acl_clear_perms.c b/libacl/acl_clear_perms.c
new file mode 100644
index 0000000..106e2d1
--- /dev/null
+++ b/libacl/acl_clear_perms.c
@@ -0,0 +1,35 @@
+/*
+ File: acl_clear_perms.c
+
+ Copyright (C) 1999, 2000
+ Andreas Gruenbacher, <a.gruenbacher@bestbits.at>
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#include "libacl.h"
+
+
+/* 23.4.3 */
+int
+acl_clear_perms(acl_permset_t permset_d)
+{
+ acl_permset_obj *acl_permset_obj_p = ext2int(acl_permset, permset_d);
+ if (!acl_permset_obj_p)
+ return -1;
+ acl_permset_obj_p->sperm = ACL_PERM_NONE;
+ return 0;
+}
+
diff --git a/libacl/acl_cmp.c b/libacl/acl_cmp.c
new file mode 100644
index 0000000..ae42284
--- /dev/null
+++ b/libacl/acl_cmp.c
@@ -0,0 +1,53 @@
+/*
+ File: acl_cmp.c
+
+ Copyright (C) 1999, 2000
+ Andreas Gruenbacher, <a.gruenbacher@bestbits.at>
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#include "libacl.h"
+
+
+int
+acl_cmp(acl_t acl1, acl_t acl2)
+{
+ acl_obj *acl1_obj_p = ext2int(acl, acl1),
+ *acl2_obj_p = ext2int(acl, acl2);
+ acl_entry_obj *p1_obj_p, *p2_obj_p;
+ if (!acl1_obj_p || !acl2_obj_p)
+ return -1;
+ if (acl1_obj_p->aused != acl2_obj_p->aused)
+ return 1;
+ p2_obj_p = acl2_obj_p->anext;
+ FOREACH_ACL_ENTRY(p1_obj_p, acl1_obj_p) {
+ if (p1_obj_p->etag != p2_obj_p->etag)
+ return 1;
+ if (!permset_obj_equal(p1_obj_p->eperm,p2_obj_p->eperm))
+ return 1;
+ switch(p1_obj_p->etag) {
+ case ACL_USER:
+ case ACL_GROUP:
+ if (qualifier_obj_id(p1_obj_p->eid) !=
+ qualifier_obj_id(p2_obj_p->eid))
+ return 1;
+
+ }
+ p2_obj_p = p2_obj_p->enext;
+ }
+ return 0;
+}
+
diff --git a/libacl/acl_copy_entry.c b/libacl/acl_copy_entry.c
new file mode 100644
index 0000000..85cebc8
--- /dev/null
+++ b/libacl/acl_copy_entry.c
@@ -0,0 +1,40 @@
+/*
+ File: acl_copy_entry.c
+
+ Copyright (C) 1999, 2000
+ Andreas Gruenbacher, <a.gruenbacher@bestbits.at>
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#include "libacl.h"
+
+
+/* 23.4.4 */
+int
+acl_copy_entry(acl_entry_t dest_d, acl_entry_t src_d)
+{
+ acl_entry_obj *dest_p = ext2int(acl_entry, dest_d),
+ *src_p = ext2int(acl_entry, src_d);
+ if (!dest_d || !src_p)
+ return -1;
+
+ dest_p->etag = src_p->etag;
+ dest_p->eid = src_p->eid;
+ dest_p->eperm = src_p->eperm;
+ __acl_reorder_entry_obj_p(dest_p);
+ return 0;
+}
+
diff --git a/libacl/acl_copy_ext.c b/libacl/acl_copy_ext.c
new file mode 100644
index 0000000..7f51185
--- /dev/null
+++ b/libacl/acl_copy_ext.c
@@ -0,0 +1,52 @@
+/*
+ File: acl_copy_ext.c
+
+ Copyright (C) 1999, 2000
+ Andreas Gruenbacher, <a.gruenbacher@bestbits.at>
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#include "libacl.h"
+
+
+/* 23.4.5 */
+ssize_t
+acl_copy_ext(void *buf_p, acl_t acl, ssize_t size)
+{
+ struct __acl *acl_ext = (struct __acl *)buf_p;
+ struct __acl_entry *ent_p = acl_ext->x_entries;
+ acl_obj *acl_obj_p = ext2int(acl, acl);
+ acl_entry_obj *entry_obj_p;
+ ssize_t size_required;
+
+ if (!acl_obj_p)
+ return -1;
+ size_required = sizeof(struct __acl) +
+ acl_obj_p->aused * sizeof(struct __acl_entry);
+ if (size < size_required) {
+ errno = ERANGE;
+ return -1;
+ }
+ acl_ext->x_size = size_required;
+ FOREACH_ACL_ENTRY(entry_obj_p, acl_obj_p) {
+ //ent_p->e_tag = cpu_to_le16(entry_obj_p->etag);
+ //ent_p->e_perm = cpu_to_le16(entry_obj_p->eperm.sperm);
+ //ent_p->e_id = cpu_to_le32(entry_obj_p->eid.quid);
+ *ent_p++ = entry_obj_p->eentry;
+ }
+ return 0;
+}
+
diff --git a/libacl/acl_copy_int.c b/libacl/acl_copy_int.c
new file mode 100644
index 0000000..e58bbe3
--- /dev/null
+++ b/libacl/acl_copy_int.c
@@ -0,0 +1,65 @@
+/*
+ File: acl_copy_int.c
+
+ Copyright (C) 1999, 2000
+ Andreas Gruenbacher, <a.gruenbacher@bestbits.at>
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#include "libacl.h"
+
+
+/* 23.4.6 */
+acl_t
+acl_copy_int(const void *buf_p)
+{
+ const struct __acl *ext_acl = (struct __acl *)buf_p;
+ const struct __acl_entry *ent_p = ext_acl->x_entries, *end_p;
+ size_t size = ext_acl ? ext_acl->x_size : 0;
+ int entries;
+ acl_obj *acl_obj_p;
+ acl_entry_obj *entry_obj_p;
+
+ if (!ext_acl || size < sizeof(struct __acl)) {
+ errno = EINVAL;
+ return NULL;
+ }
+ size -= sizeof(struct __acl);
+ if (size % sizeof(struct __acl_entry)) {
+ errno = EINVAL;
+ return NULL;
+ }
+ entries = size / sizeof(struct __acl_entry);
+ acl_obj_p = __acl_init_obj(entries);
+ if (acl_obj_p == NULL)
+ goto fail;
+ end_p = ext_acl->x_entries + entries;
+ for(; ent_p != end_p; ent_p++) {
+ entry_obj_p = __acl_create_entry_obj(acl_obj_p);
+ if (!entry_obj_p)
+ goto fail;
+ /* XXX Convert to machine endianness */
+ entry_obj_p->eentry = *ent_p;
+ }
+ if (__acl_reorder_obj_p(acl_obj_p))
+ goto fail;
+ return int2ext(acl_obj_p);
+
+fail:
+ __acl_free_acl_obj(acl_obj_p);
+ return NULL;
+}
+
diff --git a/libacl/acl_create_entry.c b/libacl/acl_create_entry.c
new file mode 100644
index 0000000..a1c4908
--- /dev/null
+++ b/libacl/acl_create_entry.c
@@ -0,0 +1,73 @@
+/*
+ File: acl_create_entry.c
+
+ Copyright (C) 1999, 2000
+ Andreas Gruenbacher <a.gruenbacher@bestbits.at>
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#include "libacl.h"
+
+
+acl_entry_obj *
+__acl_create_entry_obj(acl_obj *acl_obj_p)
+{
+ acl_entry_obj *entry_obj_p;
+
+ if (acl_obj_p->aprealloc == acl_obj_p->aprealloc_end) {
+ entry_obj_p = new_obj_p(acl_entry);
+ if (!entry_obj_p)
+ return NULL;
+ } else {
+ entry_obj_p = --acl_obj_p->aprealloc_end;
+ new_obj_p_here(acl_entry, entry_obj_p);
+ }
+ acl_obj_p->aused++;
+
+ /* Insert at the end of the entry ring */
+ entry_obj_p->eprev = acl_obj_p->aprev;
+ entry_obj_p->enext = (acl_entry_obj *)acl_obj_p;
+ entry_obj_p->eprev->enext = entry_obj_p;
+ entry_obj_p->enext->eprev = entry_obj_p;
+
+ entry_obj_p->econtainer = acl_obj_p;
+ init_acl_entry_obj(*entry_obj_p);
+
+ return entry_obj_p;
+}
+
+/* 23.4.7 */
+int
+acl_create_entry(acl_t *acl_p, acl_entry_t *entry_p)
+{
+ acl_obj *acl_obj_p;
+ acl_entry_obj *entry_obj_p;
+ if (!acl_p || !entry_p) {
+ if (entry_p)
+ *entry_p = NULL;
+ errno = EINVAL;
+ return -1;
+ }
+ acl_obj_p = ext2int(acl, *acl_p);
+ if (!acl_obj_p)
+ return -1;
+ entry_obj_p = __acl_create_entry_obj(acl_obj_p);
+ if (entry_obj_p == NULL)
+ return -1;
+ *entry_p = int2ext(entry_obj_p);
+ return 0;
+}
+
diff --git a/libacl/acl_delete_def_file.c b/libacl/acl_delete_def_file.c
new file mode 100644
index 0000000..fae4460
--- /dev/null
+++ b/libacl/acl_delete_def_file.c
@@ -0,0 +1,40 @@
+/*
+ File: acl_delete_def_file.c
+
+ Copyright (C) 1999, 2000
+ Andreas Gruenbacher, <a.gruenbacher@bestbits.at>
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#include <sys/types.h>
+#include <attr/xattr.h>
+#include "byteorder.h"
+#include "acl_ea.h"
+#include "config.h"
+
+
+/* 23.4.8 */
+int
+acl_delete_def_file(const char *path_p)
+{
+ int error;
+
+ error = removexattr(path_p, ACL_EA_DEFAULT);
+ if (error < 0 && errno != ENOATTR && errno != ENODATA)
+ return -1;
+ return 0;
+}
+
diff --git a/libacl/acl_delete_entry.c b/libacl/acl_delete_entry.c
new file mode 100644
index 0000000..a1ae6db
--- /dev/null
+++ b/libacl/acl_delete_entry.c
@@ -0,0 +1,44 @@
+/*
+ File: acl_delete_entry.c
+
+ Copyright (C) 1999, 2000
+ Andreas Gruenbacher, <a.gruenbacher@bestbits.at>
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#include "libacl.h"
+
+
+/* 23.4.9 */
+int
+acl_delete_entry(acl_t acl, acl_entry_t entry_d)
+{
+ acl_obj *acl_obj_p = ext2int(acl, acl);
+ acl_entry_obj *entry_obj_p = ext2int(acl_entry, entry_d);
+ if (!acl_obj_p || !entry_obj_p)
+ return -1;
+
+
+ if (acl_obj_p->acurr == entry_obj_p)
+ acl_obj_p->acurr = acl_obj_p->acurr->eprev;
+ entry_obj_p->eprev->enext = entry_obj_p->enext;
+ entry_obj_p->enext->eprev = entry_obj_p->eprev;
+
+ free_obj_p(entry_obj_p);
+ acl_obj_p->aused--;
+ return 0;
+}
+
diff --git a/libacl/acl_delete_perm.c b/libacl/acl_delete_perm.c
new file mode 100644
index 0000000..475ce26
--- /dev/null
+++ b/libacl/acl_delete_perm.c
@@ -0,0 +1,35 @@
+/*
+ File: acl_delete_perm.c
+
+ Copyright (C) 1999, 2000
+ Andreas Gruenbacher, <a.gruenbacher@bestbits.at>
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#include "libacl.h"
+
+
+/* 23.4.10 */
+int
+acl_delete_perm(acl_permset_t permset_d, acl_perm_t perm)
+{
+ acl_permset_obj *acl_permset_obj_p = ext2int(acl_permset, permset_d);
+ if (!acl_permset_obj_p || (perm & !(ACL_READ|ACL_WRITE|ACL_EXECUTE)))
+ return -1;
+ acl_permset_obj_p->sperm &= ~perm;
+ return 0;
+}
+
diff --git a/libacl/acl_dup.c b/libacl/acl_dup.c
new file mode 100644
index 0000000..cb73cee
--- /dev/null
+++ b/libacl/acl_dup.c
@@ -0,0 +1,54 @@
+/*
+ File: acl_dup.c
+
+ Copyright (C) 1999, 2000
+ Andreas Gruenbacher, <a.gruenbacher@bestbits.at>
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#include "libacl.h"
+
+
+/* 23.4.11 */
+acl_t
+acl_dup(acl_t acl)
+{
+ acl_entry_obj *entry_obj_p, *dup_entry_obj_p;
+ acl_obj *acl_obj_p = ext2int(acl, acl);
+ acl_obj *dup_obj_p;
+
+ if (!acl_obj_p)
+ return NULL;
+ dup_obj_p = __acl_init_obj(acl_obj_p->aused);
+ if (!dup_obj_p)
+ return NULL;
+
+ FOREACH_ACL_ENTRY(entry_obj_p, acl_obj_p) {
+ dup_entry_obj_p = __acl_create_entry_obj(dup_obj_p);
+ if (dup_entry_obj_p == NULL)
+ goto fail;
+
+ dup_entry_obj_p->etag = entry_obj_p->etag;
+ dup_entry_obj_p->eid = entry_obj_p->eid;
+ dup_entry_obj_p->eperm = entry_obj_p->eperm;
+ }
+ return int2ext(dup_obj_p);
+
+fail:
+ __acl_free_acl_obj(dup_obj_p);
+ return NULL;
+}
+
diff --git a/libacl/acl_entries.c b/libacl/acl_entries.c
new file mode 100644
index 0000000..fc4dcbf
--- /dev/null
+++ b/libacl/acl_entries.c
@@ -0,0 +1,33 @@
+/*
+ File: acl_entries.c
+
+ Copyright (C) 1999, 2000
+ Andreas Gruenbacher, <a.gruenbacher@bestbits.at>
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#include "libacl.h"
+
+
+int
+acl_entries(acl_t acl)
+{
+ acl_obj *acl_obj_p = ext2int(acl, acl);
+ if (!acl_obj_p)
+ return -1;
+ return acl_obj_p->aused;
+}
+
diff --git a/libacl/acl_equiv_mode.c b/libacl/acl_equiv_mode.c
new file mode 100644
index 0000000..b4c6de3
--- /dev/null
+++ b/libacl/acl_equiv_mode.c
@@ -0,0 +1,72 @@
+/*
+ File: acl_equiv_mode.c
+
+ Copyright (C) 1999, 2000
+ Andreas Gruenbacher, <a.gruenbacher@bestbits.at>
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#include <stdio.h>
+#include <errno.h>
+#include <sys/stat.h>
+#include <acl/libacl.h>
+#include "libacl.h"
+
+
+int
+acl_equiv_mode(acl_t acl, mode_t *mode_p)
+{
+ acl_obj *acl_obj_p = ext2int(acl, acl);
+ acl_entry_obj *entry_obj_p, *mask_obj_p = NULL;
+ int not_equiv = 0;
+ mode_t mode = 0;
+ if (!acl_obj_p)
+ return -1;
+ FOREACH_ACL_ENTRY(entry_obj_p, acl_obj_p) {
+ switch(entry_obj_p->etag) {
+ case ACL_USER_OBJ:
+ mode |= (entry_obj_p->eperm.sperm
+ & S_IRWXO) << 6;
+ break;
+ case ACL_GROUP_OBJ:
+ mode |= (entry_obj_p->eperm.sperm &
+ S_IRWXO) << 3;
+ break;
+ case ACL_OTHER:
+ mode |= (entry_obj_p->eperm.sperm &
+ S_IRWXO);
+ break;
+ case ACL_MASK:
+ mask_obj_p = entry_obj_p;
+ /* fall through */
+ case ACL_USER:
+ case ACL_GROUP:
+ not_equiv = 1;
+ break;
+ default:
+ errno = EINVAL;
+ return -1;
+ }
+ }
+ if (mode_p) {
+ if (mask_obj_p)
+ mode = (mode & ~S_IRWXG) |
+ ((mask_obj_p->eperm.sperm & S_IRWXO) << 3);
+ *mode_p = mode;
+ }
+ return not_equiv;
+}
+
diff --git a/libacl/acl_error.c b/libacl/acl_error.c
new file mode 100644
index 0000000..8a361b0
--- /dev/null
+++ b/libacl/acl_error.c
@@ -0,0 +1,45 @@
+/*
+ File: acl_error.c
+
+ Copyright (C) 1999, 2000
+ Andreas Gruenbacher, <a.gruenbacher@bestbits.at>
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#include <stdio.h>
+#include <errno.h>
+#include <acl/libacl.h>
+#include "libacl.h"
+#include "config.h"
+
+
+const char *
+acl_error(int code)
+{
+ switch(code) {
+ case ACL_MULTI_ERROR:
+ return _("Multiple entries of same type");
+ case ACL_DUPLICATE_ERROR:
+ return _("Duplicate entries");
+ case ACL_MISS_ERROR:
+ return _("Missing or wrong entry");
+ case ACL_ENTRY_ERROR:
+ return _("Invalid entry type");
+ default:
+ return NULL;
+ }
+}
+
diff --git a/libacl/acl_extended_fd.c b/libacl/acl_extended_fd.c
new file mode 100644
index 0000000..f19ad7b
--- /dev/null
+++ b/libacl/acl_extended_fd.c
@@ -0,0 +1,48 @@
+/*
+ File: acl_extended_fd.c
+
+ Copyright (C) 2000
+ Andreas Gruenbacher, <a.gruenbacher@bestbits.at>
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#include <unistd.h>
+#include <attr/xattr.h>
+#include "libacl.h"
+
+#include "byteorder.h"
+#include "acl_ea.h"
+
+
+int
+acl_extended_fd(int fd)
+{
+ int base_size = sizeof(acl_ea_header) + 3 * sizeof(acl_ea_entry);
+ int retval;
+
+ retval = fgetxattr(fd, ACL_EA_ACCESS, NULL, 0);
+ if (retval < 0 && errno != ENOATTR && errno != ENODATA)
+ return -1;
+ if (retval > base_size)
+ return 1;
+ retval = fgetxattr(fd, ACL_EA_DEFAULT, NULL, 0);
+ if (retval < 0 && errno != ENOATTR && errno != ENODATA)
+ return -1;
+ if (retval >= base_size)
+ return 1;
+ return 0;
+}
+
diff --git a/libacl/acl_extended_file.c b/libacl/acl_extended_file.c
new file mode 100644
index 0000000..d1cb85d
--- /dev/null
+++ b/libacl/acl_extended_file.c
@@ -0,0 +1,48 @@
+/*
+ File: acl_extended_file.c
+
+ Copyright (C) 2000
+ Andreas Gruenbacher, <a.gruenbacher@bestbits.at>
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#include <unistd.h>
+#include <attr/xattr.h>
+#include "libacl.h"
+
+#include "byteorder.h"
+#include "acl_ea.h"
+
+
+int
+acl_extended_file(const char *path_p)
+{
+ int base_size = sizeof(acl_ea_header) + 3 * sizeof(acl_ea_entry);
+ int retval;
+
+ retval = getxattr(path_p, ACL_EA_ACCESS, NULL, 0);
+ if (retval < 0 && errno != ENOATTR && errno != ENODATA)
+ return -1;
+ if (retval > base_size)
+ return 1;
+ retval = getxattr(path_p, ACL_EA_DEFAULT, NULL, 0);
+ if (retval < 0 && errno != ENOATTR && errno != ENODATA)
+ return -1;
+ if (retval >= base_size)
+ return 1;
+ return 0;
+}
+
diff --git a/libacl/acl_free.c b/libacl/acl_free.c
new file mode 100644
index 0000000..8510bbf
--- /dev/null
+++ b/libacl/acl_free.c
@@ -0,0 +1,76 @@
+/*
+ File: acl_free.c
+
+ Copyright (C) 1999, 2000
+ Andreas Gruenbacher <a.gruenbacher@bestbits.at>
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#include "libacl.h"
+
+
+void
+__acl_free_acl_obj(acl_obj *acl_obj_p)
+{
+ acl_entry_obj *entry_obj_p;
+ while (acl_obj_p->anext != (acl_entry_obj *)acl_obj_p) {
+ entry_obj_p = acl_obj_p->anext;
+ acl_obj_p->anext = acl_obj_p->anext->enext;
+ free_obj_p(entry_obj_p);
+ }
+ free(acl_obj_p->aprealloc);
+ free_obj_p(acl_obj_p);
+}
+
+
+/* 23.4.12 */
+int
+acl_free(void *obj_p)
+{
+ obj_prefix *int_p = ((obj_prefix *)obj_p)-1;
+ if (!obj_p || !int_p) {
+ errno = EINVAL;
+ return -1;
+ }
+
+
+ switch(int_p->p_magic) {
+ case acl_MAGIC:
+ __acl_free_acl_obj((acl_obj *)int_p);
+ return 0;
+ case qualifier_MAGIC:
+ case string_MAGIC:
+ free_obj_p(int_p);
+ return 0;
+ case acl_entry_MAGIC:
+ case acl_permset_MAGIC:
+#ifdef LIBACL_DEBUG
+ fprintf(stderr, "object (magic=0x%X) "
+ "at %p cannot be freed\n",
+ int_p->p_magic, int_p);
+#endif
+ break;
+ default:
+#ifdef LIBACL_DEBUG
+ fprintf(stderr, "invalid object (magic=0x%X) "
+ "at %p\n", int_p->p_magic, int_p);
+#endif
+ break;
+ }
+ errno = EINVAL;
+ return -1;
+}
+
diff --git a/libacl/acl_from_mode.c b/libacl/acl_from_mode.c
new file mode 100644
index 0000000..93dc689
--- /dev/null
+++ b/libacl/acl_from_mode.c
@@ -0,0 +1,73 @@
+/*
+ File: acl_from_mode.c
+
+ Copyright (C) 1999, 2000
+ Andreas Gruenbacher, <a.gruenbacher@bestbits.at>
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#include <unistd.h>
+#include <stdio.h>
+#include <errno.h>
+#include <sys/stat.h>
+#include <acl/libacl.h>
+#include "libacl.h"
+
+
+/*
+ Create an ACL from a file mode.
+
+ returns
+ the new ACL.
+*/
+
+acl_t
+acl_from_mode(mode_t mode)
+{
+ acl_obj *acl_obj_p;
+ acl_entry_obj *entry_obj_p;
+
+ acl_obj_p = __acl_init_obj(3);
+ if (!acl_obj_p)
+ goto fail;
+
+ entry_obj_p = __acl_create_entry_obj(acl_obj_p);
+ if (!entry_obj_p)
+ goto fail;
+ entry_obj_p->etag = ACL_USER_OBJ;
+ entry_obj_p->eid.qid = ACL_UNDEFINED_ID;
+ entry_obj_p->eperm.sperm = (mode & S_IRWXU) >> 6;
+
+ entry_obj_p = __acl_create_entry_obj(acl_obj_p);
+ if (!entry_obj_p)
+ goto fail;
+ entry_obj_p->etag = ACL_GROUP_OBJ;
+ entry_obj_p->eid.qid = ACL_UNDEFINED_ID;
+ entry_obj_p->eperm.sperm = (mode & S_IRWXG) >> 3;
+
+ entry_obj_p = __acl_create_entry_obj(acl_obj_p);
+ if (!entry_obj_p)
+ goto fail;
+ entry_obj_p->etag = ACL_OTHER;
+ entry_obj_p->eid.qid = ACL_UNDEFINED_ID;
+ entry_obj_p->eperm.sperm = mode & S_IRWXO;
+ return int2ext(acl_obj_p);
+
+fail:
+ __acl_free_acl_obj(acl_obj_p);
+ return NULL;
+}
+
diff --git a/libacl/acl_from_text.c b/libacl/acl_from_text.c
new file mode 100644
index 0000000..1e05322
--- /dev/null
+++ b/libacl/acl_from_text.c
@@ -0,0 +1,308 @@
+/*
+ File: acl_from_text.c
+
+ Copyright (C) 1999, 2000, 2001
+ Andreas Gruenbacher, <a.gruenbacher@bestbits.at>
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#include <string.h>
+#include <pwd.h>
+#include <grp.h>
+#include "libacl.h"
+#include "misc.h"
+
+
+#define SKIP_WS(x) do { \
+ while (*(x)==' ' || *(x)=='\t' || *(x)=='\n' || *(x)=='\r') \
+ (x)++; \
+ if (*(x)=='#') { \
+ while (*(x)!='\n' && *(x)!='\0') \
+ (x)++; \
+ } \
+ } while (0)
+
+
+static int parse_acl_entry(const char **text_p, acl_t *acl_p);
+
+
+/* 23.4.13 */
+acl_t
+acl_from_text(const char *buf_p)
+{
+ acl_t acl;
+ acl = acl_init(0);
+ if (!acl)
+ return NULL;
+ if (!buf_p) {
+ errno = EINVAL;
+ return NULL;
+ }
+ while (*buf_p != '\0') {
+ if (parse_acl_entry(&buf_p, &acl) != 0)
+ goto fail;
+ SKIP_WS(buf_p);
+ if (*buf_p == ',') {
+ buf_p++;
+ SKIP_WS(buf_p);
+ }
+ }
+ if (*buf_p != '\0') {
+ errno = EINVAL;
+ goto fail;
+ }
+
+ return acl;
+
+fail:
+ acl_free(acl);
+ return NULL;
+}
+
+
+static int
+skip_tag_name(const char **text_p, const char *token)
+{
+ size_t len = strlen(token);
+ const char *text = *text_p;
+
+ SKIP_WS(text);
+ if (strncmp(text, token, len) == 0) {
+ text += len;
+ goto delimiter;
+ }
+ if (*text == *token) {
+ text++;
+ goto delimiter;
+ }
+ return 0;
+
+delimiter:
+ SKIP_WS(text);
+ if (*text == ':')
+ text++;
+ *text_p = text;
+ return 1;
+}
+
+
+static char *
+get_token(const char **text_p)
+{
+ char *token = NULL;
+ const char *ep;
+
+ ep = *text_p;
+ SKIP_WS(ep);
+
+ while (*ep!='\0' && *ep!='\r' && *ep!='\n' && *ep!=':' && *ep!=',')
+ ep++;
+ if (ep == *text_p)
+ goto after_token;
+ token = (char*)malloc(ep - *text_p + 1);
+ if (token == 0)
+ goto after_token;
+ memcpy(token, *text_p, (ep - *text_p));
+ token[ep - *text_p] = '\0';
+after_token:
+ if (*ep == ':')
+ ep++;
+ *text_p = ep;
+ return token;
+}
+
+
+static int
+get_id(const char *token, id_t *id_p)
+{
+ char *ep;
+ long l;
+ l = strtol(token, &ep, 0);
+ if (*ep != '\0')
+ return -1;
+ if (l < 0) {
+ /*
+ Negative values are interpreted as 16-bit numbers,
+ so that id -2 maps to 65534 (nobody/nogroup), etc.
+ */
+ l &= 0xFFFF;
+ }
+ *id_p = l;
+ return 0;
+}
+
+
+static int
+get_uid(const char *token, uid_t *uid_p)
+{
+ struct passwd *passwd;
+
+ if (get_id(token, uid_p) == 0)
+ return 0;
+ passwd = getpwnam(token);
+ if (passwd) {
+ *uid_p = passwd->pw_uid;
+ return 0;
+ }
+ return -1;
+}
+
+
+static int
+get_gid(const char *token, gid_t *gid_p)
+{
+ struct group *group;
+
+ if (get_id(token, (uid_t *)gid_p) == 0)
+ return 0;
+ group = getgrnam(token);
+ if (group) {
+ *gid_p = group->gr_gid;
+ return 0;
+ }
+ return -1;
+}
+
+
+/*
+ Parses the next acl entry in text_p.
+
+ Returns:
+ -1 on error, 0 on success.
+*/
+
+static int
+parse_acl_entry(const char **text_p, acl_t *acl_p)
+{
+ acl_entry_obj entry_obj;
+ acl_entry_t entry_d;
+ char *str;
+ const char *backup;
+ int error, perm_chars;
+
+ new_obj_p_here(acl_entry, &entry_obj);
+ init_acl_entry_obj(entry_obj);
+
+ /* parse acl entry type */
+ SKIP_WS(*text_p);
+ switch (**text_p) {
+ case 'u': /* user */
+ if (!skip_tag_name(text_p, "user"))
+ goto fail;
+ backup = *text_p;
+ str = get_token(text_p);
+ if (str) {
+ entry_obj.etag = ACL_USER;
+ error = get_uid(unquote(str),
+ &entry_obj.eid.qid);
+ free(str);
+ if (error) {
+ *text_p = backup;
+ return -1;
+ }
+ } else {
+ entry_obj.etag = ACL_USER_OBJ;
+ }
+ break;
+
+ case 'g': /* group */
+ if (!skip_tag_name(text_p, "group"))
+ goto fail;
+ backup = *text_p;
+ str = get_token(text_p);
+ if (str) {
+ entry_obj.etag = ACL_GROUP;
+ error = get_gid(unquote(str),
+ &entry_obj.eid.qid);
+ free(str);
+ if (error) {
+ *text_p = backup;
+ return -1;
+ }
+ } else {
+ entry_obj.etag = ACL_GROUP_OBJ;
+ }
+ break;
+
+ case 'm': /* mask */
+ if (!skip_tag_name(text_p, "mask"))
+ goto fail;
+ /* skip empty entry qualifier field (this field may
+ be missing for compatibility with Solaris.) */
+ SKIP_WS(*text_p);
+ if (**text_p == ':')
+ (*text_p)++;
+ entry_obj.etag = ACL_MASK;
+ break;
+
+ case 'o': /* other */
+ if (!skip_tag_name(text_p, "other"))
+ goto fail;
+ /* skip empty entry qualifier field (this field may
+ be missing for compatibility with Solaris.) */
+ SKIP_WS(*text_p);
+ if (**text_p == ':')
+ (*text_p)++;
+ entry_obj.etag = ACL_OTHER;
+ break;
+
+ default:
+ goto fail;
+ }
+
+ for (perm_chars=0; perm_chars<3; perm_chars++, (*text_p)++) {
+ switch(**text_p) {
+ case 'r':
+ if (entry_obj.eperm.sperm & ACL_READ)
+ goto fail;
+ entry_obj.eperm.sperm |= ACL_READ;
+ break;
+
+ case 'w':
+ if (entry_obj.eperm.sperm & ACL_WRITE)
+ goto fail;
+ entry_obj.eperm.sperm |= ACL_WRITE;
+ break;
+
+ case 'x':
+ if (entry_obj.eperm.sperm & ACL_EXECUTE)
+ goto fail;
+ entry_obj.eperm.sperm |= ACL_EXECUTE;
+ break;
+
+ case '-':
+ /* ignore */
+ break;
+
+ default:
+ if (perm_chars == 0)
+ goto fail;
+ goto create_entry;
+ }
+ }
+
+create_entry:
+ if (acl_create_entry(acl_p, &entry_d) != 0)
+ return -1;
+ if (acl_copy_entry(entry_d, int2ext(&entry_obj)) != 0)
+ return -1;
+ return 0;
+
+fail:
+ errno = EINVAL;
+ return -1;
+}
+
diff --git a/libacl/acl_get_entry.c b/libacl/acl_get_entry.c
new file mode 100644
index 0000000..2a0de66
--- /dev/null
+++ b/libacl/acl_get_entry.c
@@ -0,0 +1,59 @@
+/*
+ File: acl_get_entry.c
+
+ Copyright (C) 1999, 2000
+ Andreas Gruenbacher, <a.gruenbacher@bestbits.at>
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#include "libacl.h"
+
+
+/* 23.4.14 */
+int
+acl_get_entry(acl_t acl, int entry_id, acl_entry_t *entry_p)
+{
+ acl_obj *acl_obj_p = ext2int(acl, acl);
+ if (!acl_obj_p) {
+ if (entry_p)
+ *entry_p = NULL;
+ return -1;
+ }
+ if (!entry_p) {
+ errno = EINVAL;
+ return -1;
+ }
+
+ if (entry_id == ACL_FIRST_ENTRY) {
+ acl_obj_p->acurr = acl_obj_p->anext;
+ } else if (entry_id == ACL_NEXT_ENTRY) {
+ /*if (acl_obj_p->acurr == (acl_entry_obj *)acl_obj_p) {
+ errno = EINVAL;
+ return -1;
+ }*/
+ acl_obj_p->acurr = acl_obj_p->acurr->enext;
+ }
+ if (acl_obj_p->acurr == (acl_entry_obj *)acl_obj_p) {
+ *entry_p = NULL;
+ return 0;
+ }
+ if (!check_obj_p(acl_entry, acl_obj_p->acurr)) {
+ return -1;
+ }
+ *entry_p = int2ext(acl_obj_p->acurr);
+ return 1;
+}
+
diff --git a/libacl/acl_get_fd.c b/libacl/acl_get_fd.c
new file mode 100644
index 0000000..f2525ef
--- /dev/null
+++ b/libacl/acl_get_fd.c
@@ -0,0 +1,68 @@
+/*
+ File: acl_get_fd.c
+
+ Copyright (C) 1999, 2000
+ Andreas Gruenbacher, <a.gruenbacher@bestbits.at>
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <attr/xattr.h>
+#include <acl/libacl.h>
+#include "libacl.h"
+#include "__acl_from_xattr.h"
+
+#include "byteorder.h"
+#include "acl_ea.h"
+
+
+/* 23.4.15 */
+acl_t
+acl_get_fd(int fd)
+{
+ const size_t size_guess = acl_ea_size(16);
+ char *ext_acl_p = alloca(size_guess);
+ int retval;
+
+ if (!ext_acl_p)
+ return NULL;
+ retval = fgetxattr(fd, ACL_EA_ACCESS, ext_acl_p, size_guess);
+ if (retval == -1 && errno == ERANGE) {
+ retval = fgetxattr(fd, ACL_EA_ACCESS, NULL, 0);
+ if (retval > 0) {
+ ext_acl_p = alloca(retval);
+ if (!ext_acl_p)
+ return NULL;
+ retval = fgetxattr(fd, ACL_EA_ACCESS, ext_acl_p,retval);
+ }
+ }
+ if (retval > 0) {
+ acl_t acl = __acl_from_xattr(ext_acl_p, retval);
+ return acl;
+ } else if (retval == 0 || errno == ENOATTR || errno == ENODATA) {
+ struct stat st;
+
+ if (fstat(fd, &st) == 0)
+ return acl_from_mode(st.st_mode);
+ else
+ return NULL;
+ } else
+ return NULL;
+}
+
diff --git a/libacl/acl_get_file.c b/libacl/acl_get_file.c
new file mode 100644
index 0000000..110ef2e
--- /dev/null
+++ b/libacl/acl_get_file.c
@@ -0,0 +1,89 @@
+/*
+ File: acl_get_file.c
+
+ Copyright (C) 1999, 2000
+ Andreas Gruenbacher, <a.gruenbacher@bestbits.at>
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <attr/xattr.h>
+#include <acl/libacl.h>
+#include "libacl.h"
+#include "__acl_from_xattr.h"
+
+#include "byteorder.h"
+#include "acl_ea.h"
+
+
+/* 23.4.16 */
+acl_t
+acl_get_file(const char *path_p, acl_type_t type)
+{
+ const size_t size_guess = acl_ea_size(16);
+ char *ext_acl_p = alloca(size_guess);
+ const char *name;
+ int retval;
+
+ switch(type) {
+ case ACL_TYPE_ACCESS:
+ name = ACL_EA_ACCESS;
+ break;
+ case ACL_TYPE_DEFAULT:
+ name = ACL_EA_DEFAULT;
+ break;
+ default:
+ errno = EINVAL;
+ return NULL;
+ }
+
+ if (!ext_acl_p)
+ return NULL;
+ retval = getxattr(path_p, name, ext_acl_p, size_guess);
+ if (retval == -1 && errno == ERANGE) {
+ retval = getxattr(path_p, name, NULL, 0);
+ if (retval > 0) {
+ ext_acl_p = alloca(retval);
+ if (!ext_acl_p)
+ return NULL;
+ retval = getxattr(path_p, name, ext_acl_p, retval);
+ }
+ }
+ if (retval > 0) {
+ acl_t acl = __acl_from_xattr(ext_acl_p, retval);
+ return acl;
+ } else if (retval == 0 || errno == ENOATTR || errno == ENODATA) {
+ struct stat st;
+
+ if (stat(path_p, &st) != 0)
+ return NULL;
+
+ if (type == ACL_TYPE_DEFAULT) {
+ if (S_ISDIR(st.st_mode))
+ return acl_init(0);
+ else {
+ errno = EACCES;
+ return NULL;
+ }
+ } else
+ return acl_from_mode(st.st_mode);
+ } else
+ return NULL;
+}
+
diff --git a/libacl/acl_get_perm.c b/libacl/acl_get_perm.c
new file mode 100644
index 0000000..be492b6
--- /dev/null
+++ b/libacl/acl_get_perm.c
@@ -0,0 +1,33 @@
+/*
+ File: acl_get_perm.c
+
+ Copyright (C) 2000
+ Andreas Gruenbacher, <a.gruenbacher@bestbits.at>
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#include "libacl.h"
+
+
+int
+acl_get_perm(acl_permset_t permset_d, acl_perm_t perm)
+{
+ acl_permset_obj *acl_permset_obj_p = ext2int(acl_permset, permset_d);
+ if (!acl_permset_obj_p || (perm & !(ACL_READ|ACL_WRITE|ACL_EXECUTE)))
+ return -1;
+ return (acl_permset_obj_p->sperm & perm) != 0;
+}
+
diff --git a/libacl/acl_get_permset.c b/libacl/acl_get_permset.c
new file mode 100644
index 0000000..85749f2
--- /dev/null
+++ b/libacl/acl_get_permset.c
@@ -0,0 +1,42 @@
+/*
+ File: acl_get_permset.c
+
+ Copyright (C) 1999, 2000
+ Andreas Gruenbacher, <a.gruenbacher@bestbits.at>
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#include "libacl.h"
+
+
+/* 23.4.17 */
+int
+acl_get_permset(acl_entry_t entry_d, acl_permset_t *permset_p)
+{
+ acl_entry_obj *entry_obj_p = ext2int(acl_entry, entry_d);
+ if (!entry_obj_p) {
+ if (permset_p)
+ *permset_p = NULL;
+ return -1;
+ }
+ if (!permset_p) {
+ errno = EINVAL;
+ return -1;
+ }
+ *permset_p = int2ext(&entry_obj_p->eperm);
+ return 0;
+}
+
diff --git a/libacl/acl_get_qualifier.c b/libacl/acl_get_qualifier.c
new file mode 100644
index 0000000..0961acf
--- /dev/null
+++ b/libacl/acl_get_qualifier.c
@@ -0,0 +1,48 @@
+/*
+ File: acl_get_qualifier.c
+
+ Copyright (C) 1999, 2000
+ Andreas Gruenbacher, <a.gruenbacher@bestbits.at>
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#include "libacl.h"
+
+
+/* 23.4.18 */
+void *
+acl_get_qualifier(acl_entry_t entry_d)
+{
+ acl_entry_obj *entry_obj_p = ext2int(acl_entry, entry_d);
+ qualifier_obj *qualifier_obj_p;
+ if (!entry_obj_p)
+ return NULL;
+
+ switch(entry_obj_p->etag) {
+ case ACL_USER:
+ case ACL_GROUP:
+ break;
+ default:
+ errno = EINVAL;
+ return NULL;
+ }
+ qualifier_obj_p = new_obj_p(qualifier);
+ if (!qualifier_obj_p)
+ return NULL;
+ qualifier_obj_p->qid = entry_obj_p->eid.qid;
+ return int2ext(qualifier_obj_p);
+}
+
diff --git a/libacl/acl_get_tag_type.c b/libacl/acl_get_tag_type.c
new file mode 100644
index 0000000..3075178
--- /dev/null
+++ b/libacl/acl_get_tag_type.c
@@ -0,0 +1,39 @@
+/*
+ File: acl_get_tag_type.c
+
+ Copyright (C) 1999, 2000
+ Andreas Gruenbacher, <a.gruenbacher@bestbits.at>
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#include "libacl.h"
+
+
+/* 23.4.19 */
+int
+acl_get_tag_type(acl_entry_t entry_d, acl_tag_t *tag_type_p)
+{
+ acl_entry_obj *entry_obj_p = ext2int(acl_entry, entry_d);
+ if (!entry_obj_p)
+ return -1;
+ if (!tag_type_p) {
+ errno = EINVAL;
+ return -1;
+ }
+ *tag_type_p = entry_obj_p->etag;
+ return 0;
+}
+
diff --git a/libacl/acl_init.c b/libacl/acl_init.c
new file mode 100644
index 0000000..5880c10
--- /dev/null
+++ b/libacl/acl_init.c
@@ -0,0 +1,69 @@
+/*
+ File: acl_init.c
+
+ Copyright (C) 1999, 2000
+ Andreas Gruenbacher, <a.gruenbacher@bestbits.at>
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#include "libacl.h"
+
+
+acl_obj *
+__acl_init_obj(int count)
+{
+ acl_obj *acl_obj_p = new_obj_p(acl);
+ if (!acl_obj_p)
+ return NULL;
+ acl_obj_p->aused = 0;
+ acl_obj_p->aprev = acl_obj_p->anext = (acl_entry_obj *)acl_obj_p;
+ acl_obj_p->acurr = (acl_entry_obj *)acl_obj_p;
+
+ /* aprealloc points to an array of pre-allocated ACL entries.
+ Entries between [aprealloc, aprealloc_end) are still available.
+ Pre-allocated entries are consumed from the last entry to the
+ first and aprealloc_end decremented. After all pre-allocated
+ entries are consumed, further entries are malloc'ed.
+ aprealloc == aprealloc_end is true when no more pre-allocated
+ entries are available. */
+
+ if (count > 0)
+ acl_obj_p->aprealloc = (acl_entry_obj *)
+ malloc(count * sizeof(acl_entry_obj));
+ else
+ acl_obj_p->aprealloc = NULL;
+ if (acl_obj_p->aprealloc != NULL)
+ acl_obj_p->aprealloc_end = acl_obj_p->aprealloc + count;
+ else
+ acl_obj_p->aprealloc_end = NULL;
+
+ return acl_obj_p;
+}
+
+
+/* 23.4.20 */
+acl_t
+acl_init(int count)
+{
+ acl_obj *obj;
+ if (count < 0) {
+ errno = EINVAL;
+ return NULL;
+ }
+ obj = __acl_init_obj(count);
+ return int2ext(obj);
+}
+
diff --git a/libacl/acl_set_fd.c b/libacl/acl_set_fd.c
new file mode 100644
index 0000000..e6413ad
--- /dev/null
+++ b/libacl/acl_set_fd.c
@@ -0,0 +1,50 @@
+/*
+ File: acl_set_fd.c
+
+ Copyright (C) 1999, 2000
+ Andreas Gruenbacher, <a.gruenbacher@bestbits.at>
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#include <unistd.h>
+#include <attr/xattr.h>
+#include "libacl.h"
+#include "__acl_to_xattr.h"
+
+#include "byteorder.h"
+#include "acl_ea.h"
+
+
+/* 23.4.21 */
+int
+acl_set_fd(int fd, acl_t acl)
+{
+ acl_obj *acl_obj_p = ext2int(acl, acl);
+ char *ext_acl_p;
+ const char *name = ACL_EA_ACCESS;
+ size_t size;
+ int error;
+
+ if (!acl_obj_p)
+ return -1;
+ ext_acl_p = __acl_to_xattr(acl_obj_p, &size);
+ if (!ext_acl_p)
+ return -1;
+ error = fsetxattr(fd, name, (char *)ext_acl_p, size, 0);
+ free(ext_acl_p);
+ return error;
+}
+
diff --git a/libacl/acl_set_file.c b/libacl/acl_set_file.c
new file mode 100644
index 0000000..6821851
--- /dev/null
+++ b/libacl/acl_set_file.c
@@ -0,0 +1,77 @@
+/*
+ File: acl_set_file.c
+
+ Copyright (C) 1999, 2000
+ Andreas Gruenbacher, <a.gruenbacher@bestbits.at>
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <attr/xattr.h>
+#include "libacl.h"
+#include "__acl_to_xattr.h"
+
+#include "byteorder.h"
+#include "acl_ea.h"
+
+
+/* 23.4.22 */
+int
+acl_set_file(const char *path_p, acl_type_t type, acl_t acl)
+{
+ acl_obj *acl_obj_p = ext2int(acl, acl);
+ char *ext_acl_p;
+ const char *name;
+ size_t size;
+ int error;
+
+ if (!acl_obj_p)
+ return -1;
+ switch (type) {
+ case ACL_TYPE_ACCESS:
+ name = ACL_EA_ACCESS;
+ break;
+ case ACL_TYPE_DEFAULT:
+ name = ACL_EA_DEFAULT;
+ break;
+ default:
+ errno = EINVAL;
+ return -1;
+ }
+
+ if (type == ACL_TYPE_DEFAULT) {
+ struct stat st;
+
+ if (stat(path_p, &st) != 0)
+ return -1;
+
+ /* Only directories may have default ACLs. */
+ if (!S_ISDIR(st.st_mode)) {
+ errno = EACCES;
+ return -1;
+ }
+ }
+
+ ext_acl_p = __acl_to_xattr(acl_obj_p, &size);
+ if (!ext_acl_p)
+ return -1;
+ error = setxattr(path_p, name, (char *)ext_acl_p, size, 0);
+ free(ext_acl_p);
+ return error;
+}
+
diff --git a/libacl/acl_set_permset.c b/libacl/acl_set_permset.c
new file mode 100644
index 0000000..67bb520
--- /dev/null
+++ b/libacl/acl_set_permset.c
@@ -0,0 +1,36 @@
+/*
+ File: acl_set_permset.c
+
+ Copyright (C) 1999, 2000
+ Andreas Gruenbacher, <a.gruenbacher@bestbits.at>
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#include "libacl.h"
+
+
+/* 23.4.23 */
+int
+acl_set_permset(acl_entry_t entry_d, acl_permset_t permset_d)
+{
+ acl_entry_obj *entry_obj_p = ext2int(acl_entry, entry_d);
+ acl_permset_obj *acl_permset_obj_p = ext2int(acl_permset, permset_d);
+ if (!entry_obj_p || !acl_permset_obj_p)
+ return -1;
+ entry_obj_p->eperm.i = acl_permset_obj_p->i;
+ return 0;
+}
+
diff --git a/libacl/acl_set_qualifier.c b/libacl/acl_set_qualifier.c
new file mode 100644
index 0000000..59e86ff
--- /dev/null
+++ b/libacl/acl_set_qualifier.c
@@ -0,0 +1,48 @@
+/*
+ File: acl_set_qualifier.c
+
+ Copyright (C) 1999, 2000
+ Andreas Gruenbacher, <a.gruenbacher@bestbits.at>
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#include "libacl.h"
+
+
+/* 23.4.24 */
+int
+acl_set_qualifier(acl_entry_t entry_d, const void *tag_qualifier_p)
+{
+ acl_entry_obj *entry_obj_p = ext2int(acl_entry, entry_d);
+ if (!entry_obj_p)
+ return -1;
+
+
+ switch(entry_obj_p->etag) {
+ case ACL_USER:
+ entry_obj_p->eid.qid = *(id_t *)tag_qualifier_p;
+ break;
+ case ACL_GROUP:
+ entry_obj_p->eid.qid = *(id_t *)tag_qualifier_p;
+ break;
+ default:
+ errno = EINVAL;
+ return -1;
+ }
+ __acl_reorder_entry_obj_p(entry_obj_p);
+ return 0;
+}
+
diff --git a/libacl/acl_set_tag_type.c b/libacl/acl_set_tag_type.c
new file mode 100644
index 0000000..d2f2d67
--- /dev/null
+++ b/libacl/acl_set_tag_type.c
@@ -0,0 +1,47 @@
+/*
+ File: acl_set_tag_type.c
+
+ Copyright (C) 1999, 2000
+ Andreas Gruenbacher, <a.gruenbacher@bestbits.at>
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#include "libacl.h"
+
+
+/* 23.4.25 */
+int
+acl_set_tag_type(acl_entry_t entry_d, acl_tag_t tag_type)
+{
+ acl_entry_obj *entry_obj_p = ext2int(acl_entry, entry_d);
+ if (!entry_obj_p)
+ return -1;
+ switch(tag_type) {
+ case ACL_USER_OBJ:
+ case ACL_USER:
+ case ACL_GROUP_OBJ:
+ case ACL_GROUP:
+ case ACL_MASK:
+ case ACL_OTHER:
+ entry_obj_p->etag = tag_type;
+ __acl_reorder_entry_obj_p(entry_obj_p);
+ return 0;
+ default:
+ errno = EINVAL;
+ return -1;
+ }
+}
+
diff --git a/libacl/acl_size.c b/libacl/acl_size.c
new file mode 100644
index 0000000..20aa692
--- /dev/null
+++ b/libacl/acl_size.c
@@ -0,0 +1,35 @@
+/*
+ File: acl_size.c
+
+ Copyright (C) 1999, 2000
+ Andreas Gruenbacher, <a.gruenbacher@bestbits.at>
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#include "libacl.h"
+
+
+/* 23.4.26 */
+ssize_t
+acl_size(acl_t acl)
+{
+ acl_obj *acl_obj_p = ext2int(acl, acl);
+ if (!acl_obj_p)
+ return -1;
+ return sizeof(struct __acl) +
+ acl_obj_p->aused * sizeof(struct __acl_entry);
+}
+
diff --git a/libacl/acl_to_any_text.c b/libacl/acl_to_any_text.c
new file mode 100644
index 0000000..0d12539
--- /dev/null
+++ b/libacl/acl_to_any_text.c
@@ -0,0 +1,34 @@
+/*
+ File: acl_to_any_text.c
+
+ Copyright (C) 1999, 2000
+ Andreas Gruenbacher, <a.gruenbacher@bestbits.at>
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#include <stdio.h>
+#include <errno.h>
+#include <string.h>
+#include <pwd.h>
+#include <grp.h>
+#include <acl/libacl.h>
+#include "libacl.h"
+
+char *
+acl_to_any_text(acl_t acl, const char *prefix, char separator, int options)
+{
+ return __acl_to_any_text(acl, NULL, prefix, separator, NULL, options);
+}
diff --git a/libacl/acl_to_text.c b/libacl/acl_to_text.c
new file mode 100644
index 0000000..1285b55
--- /dev/null
+++ b/libacl/acl_to_text.c
@@ -0,0 +1,33 @@
+/*
+ File: acl_to_text.c
+
+ Copyright (C) 1999, 2000
+ Andreas Gruenbacher, <a.gruenbacher@bestbits.at>
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#include <stdio.h>
+#include <errno.h>
+#include <acl/libacl.h>
+#include "libacl.h"
+
+char *
+acl_to_text(acl_t acl, ssize_t *len_p)
+{
+ return __acl_to_any_text(acl, len_p, NULL, '\n', "\n",
+ TEXT_SOME_EFFECTIVE);
+}
+
diff --git a/libacl/acl_valid.c b/libacl/acl_valid.c
new file mode 100644
index 0000000..2dda372
--- /dev/null
+++ b/libacl/acl_valid.c
@@ -0,0 +1,41 @@
+/*
+ File: acl_valid.c
+
+ Copyright (C) 1999, 2000
+ Andreas Gruenbacher, <a.gruenbacher@bestbits.at>
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#include <errno.h>
+#include <stdio.h>
+#include <acl/libacl.h>
+
+
+/* 23.4.28 */
+int
+acl_valid(acl_t acl)
+{
+ int result;
+
+ result = acl_check(acl, NULL);
+ if (result != 0) {
+ if (result > 0)
+ errno = EINVAL;
+ return -1;
+ }
+ return 0;
+}
+
diff --git a/libacl/byteorder.h b/libacl/byteorder.h
new file mode 100644
index 0000000..05f5d87
--- /dev/null
+++ b/libacl/byteorder.h
@@ -0,0 +1,37 @@
+/*
+ Copyright (C) 2000, 2002 Andreas Gruenbacher <agruen@suse.de>
+
+ This program is free software: you can redistribute it and/or modify it
+ under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation, either version 2.1 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 Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <endian.h>
+
+#if __BYTE_ORDER == __BIG_ENDIAN
+# define cpu_to_le16(w16) le16_to_cpu(w16)
+# define le16_to_cpu(w16) ((u_int16_t)((u_int16_t)(w16) >> 8) | \
+ (u_int16_t)((u_int16_t)(w16) << 8))
+# define cpu_to_le32(w32) le32_to_cpu(w32)
+# define le32_to_cpu(w32) ((u_int32_t)( (u_int32_t)(w32) >>24) | \
+ (u_int32_t)(((u_int32_t)(w32) >> 8) & 0xFF00) | \
+ (u_int32_t)(((u_int32_t)(w32) << 8) & 0xFF0000) | \
+ (u_int32_t)( (u_int32_t)(w32) <<24))
+#elif __BYTE_ORDER == __LITTLE_ENDIAN
+# define cpu_to_le16(w16) ((u_int16_t)(w16))
+# define le16_to_cpu(w16) ((u_int16_t)(w16))
+# define cpu_to_le32(w32) ((u_int32_t)(w32))
+# define le32_to_cpu(w32) ((u_int32_t)(w32))
+#else
+# error unknown endianess?
+#endif
+
diff --git a/libacl/libacl.h b/libacl/libacl.h
new file mode 100644
index 0000000..e79575d
--- /dev/null
+++ b/libacl/libacl.h
@@ -0,0 +1,140 @@
+/*
+ Copyright (C) 2000, 2002, 2003 Andreas Gruenbacher <agruen@suse.de>
+
+ This program is free software: you can redistribute it and/or modify it
+ under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation, either version 2.1 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 Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <errno.h>
+#include <sys/acl.h>
+#include "libobj.h"
+
+typedef unsigned int permset_t;
+
+#define ACL_PERM_NONE (0x0000)
+
+/* object types */
+struct acl_permset_obj_tag;
+typedef struct acl_permset_obj_tag acl_permset_obj;
+struct qualifier_obj_tag;
+typedef struct qualifier_obj_tag qualifier_obj;
+struct acl_entry_obj_tag;
+typedef struct acl_entry_obj_tag acl_entry_obj;
+struct acl_obj_tag;
+typedef struct acl_obj_tag acl_obj;
+
+/* permset_t object */
+struct __acl_permset_ext {
+ permset_t s_perm;
+};
+struct acl_permset_obj_tag {
+ obj_prefix o_prefix;
+ struct __acl_permset_ext i;
+};
+
+#define sperm i.s_perm
+#define oprefix i.o_prefix
+
+#define permset_obj_equal(s1, s2) \
+ ((s1).sperm == (s2).sperm)
+
+/* qualifier object */
+struct __qualifier_ext {
+ id_t q_id;
+};
+
+struct qualifier_obj_tag {
+ obj_prefix o_prefix;
+ struct __qualifier_ext i;
+};
+
+#define qid i.q_id
+
+#define qualifier_obj_id(q) \
+ ((q).qid)
+
+/* acl_entry object */
+struct __acl_entry {
+ acl_tag_t e_tag;
+ qualifier_obj e_id;
+ acl_permset_obj e_perm;
+};
+
+struct __acl_entry_ext {
+ acl_entry_obj *e_prev, *e_next;
+ acl_obj *e_container;
+ struct __acl_entry e_entry;
+};
+
+struct acl_entry_obj_tag {
+ obj_prefix o_prefix;
+ struct __acl_entry_ext i;
+};
+
+#define econtainer i.e_container
+#define eprev i.e_prev
+#define enext i.e_next
+#define eentry i.e_entry
+#define etag i.e_entry.e_tag
+#define eperm i.e_entry.e_perm
+#define eid i.e_entry.e_id
+
+#define init_acl_entry_obj(entry) do { \
+ (entry).etag = ACL_UNDEFINED_TAG; \
+ new_obj_p_here(acl_permset, &(entry).eperm); \
+ (entry).eperm.sperm = ACL_PERM_NONE; \
+ new_obj_p_here(qualifier, &(entry).eid); \
+ (entry).eid.qid = ACL_UNDEFINED_ID; \
+ } while(0)
+
+/* acl object */
+struct __acl_ext {
+ acl_entry_obj *a_prev, *a_next;
+ acl_entry_obj *a_curr;
+ acl_entry_obj *a_prealloc, *a_prealloc_end;
+ size_t a_used;
+};
+struct acl_obj_tag {
+ obj_prefix o_prefix;
+ struct __acl_ext i;
+};
+
+#define aprev i.a_prev
+#define anext i.a_next
+#define acurr i.a_curr
+#define aused i.a_used
+#define aprealloc i.a_prealloc
+#define aprealloc_end i.a_prealloc_end
+
+/* external ACL representation */
+struct __acl {
+ size_t x_size;
+ struct __acl_entry x_entries[0];
+};
+
+extern int __acl_reorder_entry_obj_p(acl_entry_obj *acl_entry_obj_p) hidden;
+extern int __acl_reorder_obj_p(acl_obj *acl_obj_p) hidden;
+
+extern acl_obj *__acl_init_obj(int count) hidden;
+extern acl_entry_obj *__acl_create_entry_obj(acl_obj *acl_obj_p) hidden;
+extern void __acl_free_acl_obj(acl_obj *acl_obj_p) hidden;
+
+extern char *__acl_to_any_text(acl_t acl, ssize_t *len_p,
+ const char *prefix, char separator,
+ const char *suffix, int options) hidden;
+extern int __apply_mask_to_mode(mode_t *mode, acl_t acl) hidden;
+
+#define FOREACH_ACL_ENTRY(entry_obj_p, acl_obj_p) \
+ for( (entry_obj_p) = (acl_obj_p)->anext; \
+ (entry_obj_p) != (acl_entry_obj *)(acl_obj_p); \
+ (entry_obj_p) = (entry_obj_p)->enext )
diff --git a/libacl/libobj.h b/libacl/libobj.h
new file mode 100644
index 0000000..5480a0e
--- /dev/null
+++ b/libacl/libobj.h
@@ -0,0 +1,108 @@
+/*
+ Copyright (C) 2000, 2002, 2003 Andreas Gruenbacher <agruen@suse.de>
+
+ This program is free software: you can redistribute it and/or modify it
+ under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation, either version 2.1 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 Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef __LIBOBJ_H
+#define __LIBOBJ_H
+
+#include <stdlib.h>
+
+#include "config.h"
+
+/* Mark library internal functions as hidden */
+#if defined(HAVE_VISIBILITY_ATTRIBUTE)
+# define hidden __attribute__((visibility("hidden")))
+#else
+# define hidden /* hidden */
+#endif
+
+/* Ugly pointer manipulation */
+
+#ifdef LIBACL_DEBUG
+# define ext2int(T, ext_p) \
+ ((T##_obj *)__ext2int_and_check(ext_p, T##_MAGIC, #T))
+#else
+# define ext2int(T, ext_p) \
+ ((T##_obj *)__ext2int_and_check(ext_p, T##_MAGIC))
+#endif
+
+#define int2ext(int_p) \
+ ((int_p) ? &(int_p)->i : NULL)
+#define new_var_obj_p(T, sz) \
+ ((T##_obj *)__new_var_obj_p(T##_MAGIC, sizeof(T##_obj) + sz))
+#define realloc_var_obj_p(T, p, sz) \
+ ((T##_obj *)realloc(p, sizeof(T##_obj) + sz))
+#define new_obj_p(T) \
+ new_var_obj_p(T, 0)
+#define new_obj_p_here(T, p) \
+ __new_obj_p_here(T##_MAGIC, p)
+#define check_obj_p(T, obj_p) \
+ ((T##_obj *)__check_obj_p((obj_prefix *)(obj_p), T##_MAGIC))
+#define free_obj_p(obj_p) \
+ (__free_obj_p((obj_prefix *)(obj_p)))
+
+
+/* prefix for all objects */
+/* [Note: p_magic is a long rather than int so that this structure */
+/* does not become padded by the compiler on 64-bit architectures] */
+
+typedef struct {
+ unsigned long p_magic:16;
+ unsigned long p_flags:16;
+} obj_prefix;
+
+#define pmagic o_prefix.p_magic
+#define pflags o_prefix.p_flags
+
+/* magic object values */
+#define acl_MAGIC (0x712C)
+#define acl_entry_MAGIC (0x9D6B)
+#define acl_permset_MAGIC (0x1ED5)
+#define qualifier_MAGIC (0x1C27)
+#define string_MAGIC (0xD5F2)
+#define cap_MAGIC (0x6CA8)
+
+/* object flags */
+#define OBJ_MALLOC_FLAG 1
+
+/* object types */
+struct string_obj_tag;
+typedef struct string_obj_tag string_obj;
+
+/* string object */
+struct __string_ext {
+ char s_str[0];
+};
+struct string_obj_tag {
+ obj_prefix o_prefix;
+ struct __string_ext i;
+};
+
+#define sstr i.s_str
+
+/* object creation, destruction, conversion and validation */
+void *__new_var_obj_p(int magic, size_t size) hidden;
+void __new_obj_p_here(int magic, void *here) hidden;
+void __free_obj_p(obj_prefix *obj_p) hidden;
+obj_prefix *__check_obj_p(obj_prefix *obj_p, int magic) hidden;
+#ifdef LIBACL_DEBUG
+obj_prefix *__ext2int_and_check(void *ext_p, int magic,
+ const char *typename) hidden;
+#else
+obj_prefix *__ext2int_and_check(void *ext_p, int magic) hidden;
+#endif
+
+#endif /* __LIBOBJ_H */
diff --git a/libacl/perm_copy.h b/libacl/perm_copy.h
new file mode 100644
index 0000000..87b1566
--- /dev/null
+++ b/libacl/perm_copy.h
@@ -0,0 +1,37 @@
+/*
+ Copyright (C) 2003 Andreas Gruenbacher <agruen@suse.de>
+
+ This program is free software: you can redistribute it and/or modify it
+ under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation, either version 2.1 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 Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/* Features we always have */
+
+#define HAVE_ACL_LIBACL_H 1
+#define HAVE_CONFIG_H 1
+#define HAVE_SYS_ACL_H 1
+#define HAVE_LIBACL_LIBACL_H 1
+
+#define HAVE_ACL_DELETE_DEF_FILE 1
+#define HAVE_ACL_ENTRIES 1
+#define HAVE_ACL_FREE 1
+#define HAVE_ACL_FROM_MODE 1
+#define HAVE_ACL_FROM_TEXT 1
+#define HAVE_ACL_GET_ENTRY 1
+#define HAVE_ACL_GET_FD 1
+#define HAVE_ACL_GET_FILE 1
+#define HAVE_ACL_GET_PERM 1
+#define HAVE_ACL_GET_PERMSET 1
+#define HAVE_ACL_GET_TAG_TYPE 1
+#define HAVE_ACL_SET_FD 1
+#define HAVE_ACL_SET_FILE 1
diff --git a/libacl/perm_copy_fd.c b/libacl/perm_copy_fd.c
new file mode 100644
index 0000000..f9ae690
--- /dev/null
+++ b/libacl/perm_copy_fd.c
@@ -0,0 +1,204 @@
+/* Copy POSIX 1003.1e draft 17 (abandoned) ACLs 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 Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#if defined (HAVE_CONFIG_H)
+#include "config.h"
+#endif
+#if defined(HAVE_LIBACL_LIBACL_H)
+# include "libacl.h"
+#endif
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <errno.h>
+
+#if defined(HAVE_SYS_ACL_H)
+#include <sys/acl.h>
+#endif
+
+#if defined(HAVE_ACL_LIBACL_H)
+#include <acl/libacl.h>
+#endif
+
+#define ERROR_CONTEXT_MACROS
+#ifdef HAVE_ATTR_ERROR_CONTEXT_H
+#include <attr/error_context.h>
+#else
+#include "error_context.h"
+#endif
+
+#if !defined(ENOTSUP)
+# define ENOTSUP (-1)
+#endif
+
+#if !defined(HAVE_ACL_FREE)
+static int
+acl_free(void *obj_p)
+{
+ free (obj_p);
+ return 0;
+}
+#endif
+
+#if !defined(HAVE_ACL_ENTRIES)
+static int
+acl_entries(acl_t acl)
+{
+# if defined(HAVE_ACL_GET_ENTRY)
+ /* POSIX 1003.1e draft 17 (abandoned) compatible version. */
+ acl_entry_t entry;
+ int entries = 0;
+
+ int entries = acl_get_entry(acl, ACL_FIRST_ENTRY, &entry);
+ if (entries > 0) {
+ while (acl_get_entry(acl, ACL_NEXT_ENTRY, &entry) > 0)
+ entries++;
+ }
+ return entries;
+# else
+ return -1;
+# endif
+}
+#endif
+
+#if !defined(HAVE_ACL_FROM_MODE) && defined(HAVE_ACL_FROM_TEXT)
+# define HAVE_ACL_FROM_MODE
+static acl_t
+acl_from_mode(mode_t mode)
+{
+ char acl_text[] = "u::---,g::---,o::---";
+ acl_t acl;
+
+ if (mode & S_IRUSR) acl_text[ 3] = 'r';
+ if (mode & S_IWUSR) acl_text[ 4] = 'w';
+ if (mode & S_IXUSR) acl_text[ 5] = 'x';
+ if (mode & S_IRGRP) acl_text[10] = 'r';
+ if (mode & S_IWGRP) acl_text[11] = 'w';
+ if (mode & S_IXGRP) acl_text[12] = 'x';
+ if (mode & S_IROTH) acl_text[17] = 'r';
+ if (mode & S_IWOTH) acl_text[18] = 'w';
+ if (mode & S_IXOTH) acl_text[19] = 'x';
+
+ return acl_from_text (acl_text);
+}
+#endif
+
+/* Set the access control list of path to the permissions defined by mode. */
+static int
+set_acl_fd (char const *path, int fd, mode_t mode, struct error_context *ctx)
+{
+ int ret = 0;
+#if defined(HAVE_ACL_FROM_MODE) && defined(HAVE_ACL_SET_FD)
+ /* POSIX 1003.1e draft 17 (abandoned) specific version. */
+ acl_t acl = acl_from_mode (mode);
+ if (!acl) {
+ error (ctx, "");
+ return -1;
+ }
+
+ if (acl_set_fd (fd, acl) != 0) {
+ ret = -1;
+ if (errno == ENOTSUP || errno == ENOSYS) {
+ (void) acl_free (acl);
+ goto chmod_only;
+ } else {
+ const char *qpath = quote (ctx, path);
+ error (ctx, _("setting permissions for %s"), qpath);
+ quote_free (ctx, qpath);
+ }
+ }
+ (void) acl_free (acl);
+ return ret;
+#endif
+
+chmod_only:
+ ret = fchmod (fd, mode);
+ if (ret != 0) {
+ const char *qpath = quote (ctx, path);
+ error (ctx, _("setting permissions for %s"), qpath);
+ quote_free (ctx, qpath);
+ }
+ return ret;
+}
+
+/* Copy the permissions of src_path to dst_path. This includes the
+ file mode permission bits and ACLs. File ownership is not copied.
+ */
+int
+perm_copy_fd (const char *src_path, int src_fd,
+ const char *dst_path, int dst_fd,
+ struct error_context *ctx)
+{
+#if defined(HAVE_ACL_GET_FD) && defined(HAVE_ACL_SET_FD)
+ acl_t acl;
+#endif
+ struct stat st;
+ int ret = 0;
+
+ ret = fstat(src_fd, &st);
+ if (ret != 0) {
+ const char *qpath = quote (ctx, src_path);
+ error (ctx, "%s", qpath);
+ quote_free (ctx, qpath);
+ return -1;
+ }
+#if defined(HAVE_ACL_GET_FD) && defined(HAVE_ACL_SET_FD)
+ /* POSIX 1003.1e draft 17 (abandoned) specific version. */
+ acl = acl_get_fd (src_fd);
+ if (acl == NULL) {
+ ret = -1;
+ if (errno == ENOSYS || errno == ENOTSUP)
+ ret = set_acl_fd (dst_path, dst_fd, st.st_mode, ctx);
+ else {
+ const char *qpath = quote (ctx, src_path);
+ error (ctx, "%s", qpath);
+ quote_free (ctx, qpath);
+ }
+ return ret;
+ }
+
+ if (acl_set_fd (dst_fd, acl) != 0) {
+ int saved_errno = errno;
+ __apply_mask_to_mode(&st.st_mode, acl);
+ ret = fchmod (dst_fd, st.st_mode);
+ if ((errno != ENOSYS && errno != ENOTSUP) ||
+ acl_entries (acl) != 3) {
+ const char *qpath = quote (ctx, dst_path);
+ errno = saved_errno;
+ error (ctx, _("preserving permissions for %s"), qpath);
+ quote_free (ctx, qpath);
+ ret = -1;
+ }
+ }
+ (void) acl_free (acl);
+ return ret;
+#else
+ /* POSIX.1 version. */
+ ret = fchmod (dst_fd, st.st_mode);
+ if (ret != 0) {
+ const char *qpath = quote (ctx, dst_path);
+ error (ctx, _("setting permissions for %s"), qpath);
+ quote_free (ctx, qpath);
+ }
+ return ret;
+#endif
+}
+
diff --git a/libacl/perm_copy_file.c b/libacl/perm_copy_file.c
new file mode 100644
index 0000000..023294d
--- /dev/null
+++ b/libacl/perm_copy_file.c
@@ -0,0 +1,241 @@
+/* Copy POSIX 1003.1e draft 17 (abandoned) ACLs 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 Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#if defined (HAVE_CONFIG_H)
+#include "config.h"
+#endif
+#if defined(HAVE_LIBACL_LIBACL_H)
+# include "libacl.h"
+#endif
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <errno.h>
+
+#if defined(HAVE_SYS_ACL_H)
+#include <sys/acl.h>
+#endif
+
+#if defined(HAVE_ACL_LIBACL_H)
+#include <acl/libacl.h>
+#endif
+
+#define ERROR_CONTEXT_MACROS
+#ifdef HAVE_ATTR_ERROR_CONTEXT_H
+#include <attr/error_context.h>
+#else
+#include "error_context.h"
+#endif
+
+#if !defined(ENOTSUP)
+# define ENOTSUP (-1)
+#endif
+
+#if !defined(HAVE_ACL_FREE)
+static int
+acl_free(void *obj_p)
+{
+ free (obj_p);
+ return 0;
+}
+#endif
+
+#if !defined(HAVE_ACL_ENTRIES)
+static int
+acl_entries(acl_t acl)
+{
+# if defined(HAVE_ACL_GET_ENTRY)
+ /* POSIX 1003.1e draft 17 (abandoned) compatible version. */
+ acl_entry_t entry;
+ int entries = 0;
+
+ int entries = acl_get_entry(acl, ACL_FIRST_ENTRY, &entry);
+ if (entries > 0) {
+ while (acl_get_entry(acl, ACL_NEXT_ENTRY, &entry) > 0)
+ entries++;
+ }
+ return entries;
+# else
+ return -1;
+# endif
+}
+#endif
+
+#if !defined(HAVE_ACL_FROM_MODE) && defined(HAVE_ACL_FROM_TEXT)
+# define HAVE_ACL_FROM_MODE
+static acl_t
+acl_from_mode(mode_t mode)
+{
+ char acl_text[] = "u::---,g::---,o::---";
+ acl_t acl;
+
+ if (mode & S_IRUSR) acl_text[ 3] = 'r';
+ if (mode & S_IWUSR) acl_text[ 4] = 'w';
+ if (mode & S_IXUSR) acl_text[ 5] = 'x';
+ if (mode & S_IRGRP) acl_text[10] = 'r';
+ if (mode & S_IWGRP) acl_text[11] = 'w';
+ if (mode & S_IXGRP) acl_text[12] = 'x';
+ if (mode & S_IROTH) acl_text[17] = 'r';
+ if (mode & S_IWOTH) acl_text[18] = 'w';
+ if (mode & S_IXOTH) acl_text[19] = 'x';
+
+ return acl_from_text (acl_text);
+}
+#endif
+
+/* Set the access control list of path to the permissions defined by mode. */
+static int
+set_acl (char const *path, mode_t mode, struct error_context *ctx)
+{
+ int ret = 0;
+#if defined(HAVE_ACL_FROM_MODE) && defined(HAVE_ACL_SET_FILE)
+ /* POSIX 1003.1e draft 17 (abandoned) specific version. */
+ acl_t acl = acl_from_mode (mode);
+ if (!acl) {
+ error (ctx, "");
+ return -1;
+ }
+
+ if (acl_set_file (path, ACL_TYPE_ACCESS, acl) != 0) {
+ ret = -1;
+ if (errno == ENOTSUP || errno == ENOSYS) {
+ (void) acl_free (acl);
+ goto chmod_only;
+ } else {
+ const char *qpath = quote (ctx, path);
+ error (ctx, _("setting permissions for %s"), qpath);
+ quote_free (ctx, qpath);
+ }
+ }
+ (void) acl_free (acl);
+ if (ret == 0 && S_ISDIR (mode)) {
+# if defined(HAVE_ACL_DELETE_DEF_FILE)
+ ret = acl_delete_def_file (path);
+# else
+ acl = acl_init (0);
+ ret = acl_set_file (path, ACL_TYPE_DEFAULT, acl);
+ (void) acl_free (acl);
+# endif
+ if (ret != 0) {
+ const char *qpath = quote (ctx, path);
+ error (ctx, _( "setting permissions for %s"), qpath);
+ quote_free (ctx, qpath);
+ }
+ }
+ return ret;
+#endif
+
+chmod_only:
+ ret = chmod (path, mode);
+ if (ret != 0) {
+ const char *qpath = quote (ctx, path);
+ error (ctx, _("setting permissions for %s"), qpath);
+ quote_free (ctx, qpath);
+ }
+ return ret;
+}
+
+/* Copy the permissions of src_path to dst_path. This includes the
+ file mode permission bits and ACLs. File ownership is not copied.
+ */
+int
+perm_copy_file (const char *src_path, const char *dst_path,
+ struct error_context *ctx)
+{
+#if defined(HAVE_ACL_GET_FILE) && defined(HAVE_ACL_SET_FILE)
+ acl_t acl;
+#endif
+ struct stat st;
+ int ret = 0;
+
+ ret = stat(src_path, &st);
+ if (ret != 0) {
+ const char *qpath = quote (ctx, src_path);
+ error (ctx, "%s", qpath);
+ quote_free (ctx, qpath);
+ return -1;
+ }
+#if defined(HAVE_ACL_GET_FILE) && defined(HAVE_ACL_SET_FILE)
+ /* POSIX 1003.1e draft 17 (abandoned) specific version. */
+ acl = acl_get_file (src_path, ACL_TYPE_ACCESS);
+ if (acl == NULL) {
+ ret = -1;
+ if (errno == ENOSYS || errno == ENOTSUP)
+ ret = set_acl (dst_path, st.st_mode, ctx);
+ else {
+ const char *qpath = quote (ctx, src_path);
+ error (ctx, "%s", qpath);
+ quote_free (ctx, qpath);
+ }
+ return ret;
+ }
+
+ if (acl_set_file (dst_path, ACL_TYPE_ACCESS, acl) != 0) {
+ int saved_errno = errno;
+ __apply_mask_to_mode(&st.st_mode, acl);
+ ret = chmod (dst_path, st.st_mode);
+ if ((errno != ENOSYS && errno != ENOTSUP) ||
+ acl_entries (acl) != 3) {
+ const char *qpath = quote (ctx, dst_path);
+ errno = saved_errno;
+ error (ctx, _("preserving permissions for %s"), qpath);
+ quote_free (ctx, qpath);
+ ret = -1;
+ }
+ }
+ (void) acl_free (acl);
+
+ if (ret == 0 && S_ISDIR (st.st_mode)) {
+ acl = acl_get_file (src_path, ACL_TYPE_DEFAULT);
+ if (acl == NULL) {
+ const char *qpath = quote (ctx, src_path);
+ error (ctx, "%s", qpath);
+ quote_free (ctx, qpath);
+ return -1;
+ }
+# if defined(HAVE_ACL_DELETE_DEF_FILE)
+ if (acl_entries(acl) == 0)
+ ret = acl_delete_def_file(dst_path);
+ else
+ ret = acl_set_file (dst_path, ACL_TYPE_DEFAULT, acl);
+# else
+ ret = acl_set_file (dst_path, ACL_TYPE_DEFAULT, acl);
+# endif
+ if (ret != 0) {
+ const char *qpath = quote (ctx, dst_path);
+ error (ctx, _("preserving permissions for %s"), qpath);
+ quote_free (ctx, qpath);
+ }
+ (void) acl_free(acl);
+ }
+ return ret;
+#else
+ /* POSIX.1 version. */
+ ret = chmod (dst_path, st.st_mode);
+ if (ret != 0) {
+ const char *qpath = quote (ctx, dst_path);
+ error (ctx, _("setting permissions for %s"), qpath);
+ quote_free (ctx, qpath);
+ }
+ return ret;
+#endif
+}
+
diff --git a/m4/Makefile b/m4/Makefile
new file mode 100644
index 0000000..9748f11
--- /dev/null
+++ b/m4/Makefile
@@ -0,0 +1,34 @@
+#
+# Copyright (c) 2003-2006 Silicon Graphics, Inc. All Rights Reserved.
+#
+# 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 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, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+
+TOPDIR = ..
+include $(TOPDIR)/include/builddefs
+
+LSRCFILES = \
+ manual_format.m4 \
+ package_attrdev.m4 \
+ package_globals.m4 \
+ package_utilies.m4 \
+ visibility_hidden.m4 \
+ multilib.m4
+
+default:
+
+include $(BUILDRULES)
+
+install install-dev install-lib: default
diff --git a/m4/manual_format.m4 b/m4/manual_format.m4
new file mode 100644
index 0000000..34aa466
--- /dev/null
+++ b/m4/manual_format.m4
@@ -0,0 +1,31 @@
+dnl Copyright (C) 2003 Silicon Graphics, Inc.
+dnl
+dnl This program is free software: you can redistribute it and/or modify it
+dnl under the terms of the GNU General Public License as published by
+dnl the Free Software Foundation, either version 2 of the License, or
+dnl (at your option) any later version.
+dnl
+dnl This program is distributed in the hope that it will be useful,
+dnl but WITHOUT ANY WARRANTY; without even the implied warranty of
+dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+dnl GNU General Public License for more details.
+dnl
+dnl You should have received a copy of the GNU General Public License
+dnl along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+# Find format of installed man pages.
+# Always gzipped on Debian, but not Redhat pre-7.0.
+# We don't deal with bzip2'd man pages, which Mandrake uses,
+# someone will send us a patch sometime hopefully. :-)
+#
+AC_DEFUN([AC_MANUAL_FORMAT],
+ [ have_zipped_manpages=false
+ for d in ${prefix}/share/man ${prefix}/man ; do
+ if test -f $d/man1/man.1.gz
+ then
+ have_zipped_manpages=true
+ break
+ fi
+ done
+ AC_SUBST(have_zipped_manpages)
+ ])
diff --git a/m4/multilib.m4 b/m4/multilib.m4
new file mode 100644
index 0000000..8d991d8
--- /dev/null
+++ b/m4/multilib.m4
@@ -0,0 +1,43 @@
+# The AC_MULTILIB macro was extracted and modified from
+# gettext-0.15's AC_LIB_PREPARE_MULTILIB macro in the lib-prefix.m4 file
+# so that the correct paths can be used for 64-bit libraries.
+#
+dnl Copyright (C) 2001-2005 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+dnl From Bruno Haible.
+
+dnl AC_MULTILIB creates a variable libdirsuffix, containing
+dnl the suffix of the libdir, either "" or "64".
+dnl Only do this if the given enable parameter is "yes".
+AC_DEFUN([AC_MULTILIB],
+[
+ dnl There is no formal standard regarding lib and lib64. The current
+ dnl practice is that on a system supporting 32-bit and 64-bit instruction
+ dnl sets or ABIs, 64-bit libraries go under $prefix/lib64 and 32-bit
+ dnl libraries go under $prefix/lib. We determine the compiler's default
+ dnl mode by looking at the compiler's library search path. If at least
+ dnl of its elements ends in /lib64 or points to a directory whose absolute
+ dnl pathname ends in /lib64, we assume a 64-bit ABI. Otherwise we use the
+ dnl default, namely "lib".
+ enable_lib64="$1"
+ libdirsuffix=""
+ searchpath=`(LC_ALL=C $CC -print-search-dirs) 2>/dev/null | sed -n -e 's,^libraries: ,,p' | sed -e 's,^=,,'`
+ if test "$enable_lib64" = "yes" -a -n "$searchpath"; then
+ save_IFS="${IFS= }"; IFS=":"
+ for searchdir in $searchpath; do
+ if test -d "$searchdir"; then
+ case "$searchdir" in
+ */lib64/ | */lib64 ) libdirsuffix=64 ;;
+ *) searchdir=`cd "$searchdir" && pwd`
+ case "$searchdir" in
+ */lib64 ) libdirsuffix=64 ;;
+ esac ;;
+ esac
+ fi
+ done
+ IFS="$save_IFS"
+ fi
+ AC_SUBST(libdirsuffix)
+])
diff --git a/m4/package_attrdev.m4 b/m4/package_attrdev.m4
new file mode 100644
index 0000000..92c9135
--- /dev/null
+++ b/m4/package_attrdev.m4
@@ -0,0 +1,93 @@
+dnl Copyright (C) 2003, 2004, 2006, 2007 Silicon Graphics, Inc.
+dnl
+dnl This program is free software: you can redistribute it and/or modify it
+dnl under the terms of the GNU General Public License as published by
+dnl the Free Software Foundation, either version 2 of the License, or
+dnl (at your option) any later version.
+dnl
+dnl This program is distributed in the hope that it will be useful,
+dnl but WITHOUT ANY WARRANTY; without even the implied warranty of
+dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+dnl GNU General Public License for more details.
+dnl
+dnl You should have received a copy of the GNU General Public License
+dnl along with this program. If not, see <http://www.gnu.org/licenses/>.
+AC_DEFUN([AC_PACKAGE_NEED_ATTR_XATTR_H],
+ [ AC_CHECK_HEADERS([attr/xattr.h])
+ if test "$ac_cv_header_attr_xattr_h" != "yes"; then
+ echo
+ echo 'FATAL ERROR: attr/xattr.h does not exist.'
+ echo 'Install the extended attributes (attr) development package.'
+ echo 'Alternatively, run "make install-dev" from the attr source.'
+ exit 1
+ fi
+ ])
+
+AC_DEFUN([AC_PACKAGE_NEED_ATTR_ERROR_H],
+ [ AC_CHECK_HEADERS([attr/error_context.h])
+ if test "$ac_cv_header_attr_error_context_h" != "yes"; then
+ echo
+ echo 'FATAL ERROR: attr/error_context.h does not exist.'
+ echo 'Install the extended attributes (attr) development package.'
+ echo 'Alternatively, run "make install-dev" from the attr source.'
+ exit 1
+ fi
+ ])
+
+AC_DEFUN([AC_PACKAGE_NEED_ATTRIBUTES_H],
+ [ have_attributes_h=false
+ AC_CHECK_HEADERS([attr/attributes.h sys/attributes.h], [have_attributes_h=true], )
+ if test "$have_attributes_h" = "false"; then
+ echo
+ echo 'FATAL ERROR: attributes.h does not exist.'
+ echo 'Install the extended attributes (attr) development package.'
+ echo 'Alternatively, run "make install-dev" from the attr source.'
+ exit 1
+ fi
+ ])
+
+AC_DEFUN([AC_PACKAGE_WANT_ATTRLIST_LIBATTR],
+ [ AC_CHECK_LIB(attr, attr_list, [have_attr_list=true], [have_attr_list=false])
+ AC_SUBST(have_attr_list)
+ ])
+
+AC_DEFUN([AC_PACKAGE_NEED_GETXATTR_LIBATTR],
+ [ AC_CHECK_LIB(attr, getxattr,, [
+ echo
+ echo 'FATAL ERROR: could not find a valid Extended Attributes library.'
+ echo 'Install the extended attributes (attr) development package.'
+ echo 'Alternatively, run "make install-lib" from the attr source.'
+ exit 1
+ ])
+ libattr="-lattr"
+ test -f `pwd`/../attr/libattr/libattr.la && \
+ libattr="`pwd`/../attr/libattr/libattr.la"
+ AC_SUBST(libattr)
+ ])
+
+AC_DEFUN([AC_PACKAGE_NEED_ATTRGET_LIBATTR],
+ [ AC_CHECK_LIB(attr, attr_get,, [
+ echo
+ echo 'FATAL ERROR: could not find a valid Extended Attributes library.'
+ echo 'Install the extended attributes (attr) development package.'
+ echo 'Alternatively, run "make install-lib" from the attr source.'
+ exit 1
+ ])
+ libattr="-lattr"
+ test -f `pwd`/../attr/libattr/libattr.la && \
+ libattr="`pwd`/../attr/libattr/libattr.la"
+ AC_SUBST(libattr)
+ ])
+
+AC_DEFUN([AC_PACKAGE_NEED_ATTRIBUTES_MACROS],
+ [ AC_MSG_CHECKING([macros in attr/attributes.h])
+ AC_TRY_LINK([
+#include <sys/types.h>
+#include <attr/attributes.h>],
+ [ int x = ATTR_SECURE; ], [ echo ok ], [
+ echo
+ echo 'FATAL ERROR: could not find a current attributes header.'
+ echo 'Upgrade the extended attributes (attr) development package.'
+ echo 'Alternatively, run "make install-dev" from the attr source.'
+ exit 1 ])
+ ])
diff --git a/m4/package_globals.m4 b/m4/package_globals.m4
new file mode 100644
index 0000000..e5c2418
--- /dev/null
+++ b/m4/package_globals.m4
@@ -0,0 +1,61 @@
+dnl Copyright (C) 2003, 2005, 2006, 2007 Silicon Graphics, Inc.
+dnl
+dnl This program is free software: you can redistribute it and/or modify it
+dnl under the terms of the GNU General Public License as published by
+dnl the Free Software Foundation, either version 2 of the License, or
+dnl (at your option) any later version.
+dnl
+dnl This program is distributed in the hope that it will be useful,
+dnl but WITHOUT ANY WARRANTY; without even the implied warranty of
+dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+dnl GNU General Public License for more details.
+dnl
+dnl You should have received a copy of the GNU General Public License
+dnl along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+# Generic macro, sets up all of the global packaging variables.
+# The following environment variables may be set to override defaults:
+# DEBUG OPTIMIZER MALLOCLIB PLATFORM DISTRIBUTION INSTALL_USER INSTALL_GROUP
+# BUILD_VERSION
+#
+AC_DEFUN([AC_PACKAGE_GLOBALS],
+ [ pkg_name="$1"
+ AC_SUBST(pkg_name)
+
+ AC_PROG_CC
+
+ . ./VERSION
+ pkg_version=${PKG_MAJOR}.${PKG_MINOR}.${PKG_REVISION}
+ AC_SUBST(pkg_version)
+ pkg_release=$PKG_BUILD
+ test -z "$BUILD_VERSION" || pkg_release="$BUILD_VERSION"
+ AC_SUBST(pkg_release)
+
+ DEBUG=${DEBUG:-'-DDEBUG'} dnl -DNDEBUG
+ debug_build="$DEBUG"
+ AC_SUBST(debug_build)
+
+ OPTIMIZER=${OPTIMIZER:-'-g -O2'}
+ opt_build="$OPTIMIZER"
+ AC_SUBST(opt_build)
+
+ MALLOCLIB=${MALLOCLIB:-''} dnl /usr/lib/libefence.a
+ malloc_lib="$MALLOCLIB"
+ AC_SUBST(malloc_lib)
+
+ pkg_user=`id -u -n`
+ test -z "$INSTALL_USER" || pkg_user="$INSTALL_USER"
+ AC_SUBST(pkg_user)
+
+ pkg_group=`id -g -n`
+ test -z "$INSTALL_GROUP" || pkg_group="$INSTALL_GROUP"
+ AC_SUBST(pkg_group)
+
+ pkg_distribution=`uname -s`
+ test -z "$DISTRIBUTION" || pkg_distribution="$DISTRIBUTION"
+ AC_SUBST(pkg_distribution)
+
+ pkg_platform=`uname -s | tr 'A-Z' 'a-z' | sed -e 's/irix64/irix/'`
+ test -z "$PLATFORM" || pkg_platform="$PLATFORM"
+ AC_SUBST(pkg_platform)
+ ])
diff --git a/m4/package_utilies.m4 b/m4/package_utilies.m4
new file mode 100644
index 0000000..d8f0726
--- /dev/null
+++ b/m4/package_utilies.m4
@@ -0,0 +1,140 @@
+dnl Copyright (C) 2003, 2004, 2005, 2006, 2007 Silicon Graphics, Inc.
+dnl
+dnl This program is free software: you can redistribute it and/or modify it
+dnl under the terms of the GNU General Public License as published by
+dnl the Free Software Foundation, either version 2 of the License, or
+dnl (at your option) any later version.
+dnl
+dnl This program is distributed in the hope that it will be useful,
+dnl but WITHOUT ANY WARRANTY; without even the implied warranty of
+dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+dnl GNU General Public License for more details.
+dnl
+dnl You should have received a copy of the GNU General Public License
+dnl along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+# Check for specified utility (env var) - if unset, fail.
+#
+AC_DEFUN([AC_PACKAGE_NEED_UTILITY],
+ [ if test -z "$2"; then
+ echo
+ echo FATAL ERROR: $3 does not seem to be installed.
+ echo $1 cannot be built without a working $4 installation.
+ exit 1
+ fi
+ ])
+
+#
+# Generic macro, sets up all of the global build variables.
+# The following environment variables may be set to override defaults:
+# CC MAKE LIBTOOL TAR ZIP MAKEDEPEND AWK SED ECHO SORT
+# MSGFMT MSGMERGE XGETTEXT RPM
+#
+AC_DEFUN([AC_PACKAGE_UTILITIES],
+ [ AC_PROG_CC
+ cc="$CC"
+ AC_SUBST(cc)
+ AC_PACKAGE_NEED_UTILITY($1, "$cc", cc, [C compiler])
+
+ if test -z "$MAKE"; then
+ AC_PATH_PROG(MAKE, gmake,, /usr/bin:/usr/local/bin:/usr/freeware/bin)
+ fi
+ if test -z "$MAKE"; then
+ AC_PATH_PROG(MAKE, make,, /usr/bin)
+ fi
+ make=$MAKE
+ AC_SUBST(make)
+ AC_PACKAGE_NEED_UTILITY($1, "$make", make, [GNU make])
+
+ if test -z "$TAR"; then
+ AC_PATH_PROG(TAR, tar,, /usr/freeware/bin:/bin:/usr/local/bin:/usr/bin)
+ fi
+ tar=$TAR
+ AC_SUBST(tar)
+ if test -z "$ZIP"; then
+ AC_PATH_PROG(ZIP, gzip,, /bin:/usr/bin:/usr/local/bin:/usr/freeware/bin)
+ fi
+
+ zip=$ZIP
+ AC_SUBST(zip)
+
+ if test -z "$MAKEDEPEND"; then
+ AC_PATH_PROG(MAKEDEPEND, makedepend, /bin/true)
+ fi
+ makedepend=$MAKEDEPEND
+ AC_SUBST(makedepend)
+
+ if test -z "$AWK"; then
+ AC_PATH_PROG(AWK, awk,, /bin:/usr/bin)
+ fi
+ awk=$AWK
+ AC_SUBST(awk)
+
+ if test -z "$SED"; then
+ AC_PATH_PROG(SED, sed,, /bin:/usr/bin)
+ fi
+ sed=$SED
+ AC_SUBST(sed)
+
+ if test -z "$ECHO"; then
+ AC_PATH_PROG(ECHO, echo,, /bin:/usr/bin)
+ fi
+ echo=$ECHO
+ AC_SUBST(echo)
+
+ if test -z "$SORT"; then
+ AC_PATH_PROG(SORT, sort,, /bin:/usr/bin)
+ fi
+ sort=$SORT
+ AC_SUBST(sort)
+
+ dnl check if symbolic links are supported
+ AC_PROG_LN_S
+
+ if test "$enable_gettext" = yes; then
+ if test -z "$MSGFMT"; then
+ AC_PATH_PROG(MSGFMT, msgfmt,, /usr/bin:/usr/local/bin:/usr/freeware/bin)
+ fi
+ msgfmt=$MSGFMT
+ AC_SUBST(msgfmt)
+ AC_PACKAGE_NEED_UTILITY($1, "$msgfmt", msgfmt, gettext)
+
+ if test -z "$MSGMERGE"; then
+ AC_PATH_PROG(MSGMERGE, msgmerge,, /usr/bin:/usr/local/bin:/usr/freeware/bin)
+ fi
+ msgmerge=$MSGMERGE
+ AC_SUBST(msgmerge)
+ AC_PACKAGE_NEED_UTILITY($1, "$msgmerge", msgmerge, gettext)
+
+ if test -z "$XGETTEXT"; then
+ AC_PATH_PROG(XGETTEXT, xgettext,, /usr/bin:/usr/local/bin:/usr/freeware/bin)
+ fi
+ xgettext=$XGETTEXT
+ AC_SUBST(xgettext)
+ AC_PACKAGE_NEED_UTILITY($1, "$xgettext", xgettext, gettext)
+
+ AC_DEFINE([ENABLE_GETTEXT], 1, [enable gettext])
+ fi
+
+ if test -z "$RPM"; then
+ AC_PATH_PROG(RPM, rpm,, /bin:/usr/bin:/usr/freeware/bin)
+ fi
+ rpm=$RPM
+ AC_SUBST(rpm)
+
+ dnl .. and what version is rpm
+ rpm_version=0
+ test -n "$RPM" && test -x "$RPM" && rpm_version=`$RPM --version \
+ | awk '{print $NF}' | awk -F. '{V=1; print $V}'`
+ AC_SUBST(rpm_version)
+ dnl At some point in rpm 4.0, rpm can no longer build rpms, and
+ dnl rpmbuild is needed (rpmbuild may go way back; not sure)
+ dnl So, if rpm version >= 4.0, look for rpmbuild. Otherwise build w/ rpm
+ if test $rpm_version -ge 4; then
+ AC_PATH_PROG(RPMBUILD, rpmbuild)
+ rpmbuild=$RPMBUILD
+ else
+ rpmbuild=$RPM
+ fi
+ AC_SUBST(rpmbuild)
+ ])
diff --git a/m4/visibility_hidden.m4 b/m4/visibility_hidden.m4
new file mode 100644
index 0000000..808a8e3
--- /dev/null
+++ b/m4/visibility_hidden.m4
@@ -0,0 +1,36 @@
+dnl Copyright (C) 2003, 2008 Silicon Graphics, Inc.
+dnl
+dnl This program is free software: you can redistribute it and/or modify it
+dnl under the terms of the GNU General Public License as published by
+dnl the Free Software Foundation, either version 2 of the License, or
+dnl (at your option) any later version.
+dnl
+dnl This program is distributed in the hope that it will be useful,
+dnl but WITHOUT ANY WARRANTY; without even the implied warranty of
+dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+dnl GNU General Public License for more details.
+dnl
+dnl You should have received a copy of the GNU General Public License
+dnl along with this program. If not, see <http://www.gnu.org/licenses/>.
+AC_DEFUN([AC_FUNC_GCC_VISIBILITY],
+ [AC_CACHE_CHECK(whether __attribute__((visibility())) is supported,
+ libc_cv_visibility_attribute,
+ [cat > conftest.c <<EOF
+ int foo __attribute__ ((visibility ("hidden"))) = 1;
+ int bar __attribute__ ((visibility ("protected"))) = 1;
+EOF
+ libc_cv_visibility_attribute=no
+ if ${CC-cc} -Werror -S conftest.c -o conftest.s \
+ >/dev/null 2>&1; then
+ if grep '\.hidden.*foo' conftest.s >/dev/null; then
+ if grep '\.protected.*bar' conftest.s >/dev/null; then
+ libc_cv_visibility_attribute=yes
+ fi
+ fi
+ fi
+ rm -f conftest.[cs]
+ ])
+ if test $libc_cv_visibility_attribute = yes; then
+ AC_DEFINE(HAVE_VISIBILITY_ATTRIBUTE, [], [GCC supports visibility attributes])
+ fi
+ ])
diff --git a/man/Makefile b/man/Makefile
new file mode 100644
index 0000000..a2e7546
--- /dev/null
+++ b/man/Makefile
@@ -0,0 +1,41 @@
+#
+# Copyright (c) 2000-2002 Silicon Graphics, Inc. All Rights Reserved.
+#
+# 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 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, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+
+TOPDIR = ..
+include $(TOPDIR)/include/builddefs
+
+SUBDIRS = man1 man3 man5
+
+default : $(SUBDIRS)
+
+install : $(addsuffix -install,$(SUBDIRS))
+
+install-dev : $(addsuffix -install-dev,$(SUBDIRS))
+
+install-lib: $(addsuffix -install-lib,$(SUBDIRS))
+
+%-install:
+ $(MAKE) -C $* install
+
+%-install-dev:
+ $(MAKE) -C $* install-dev
+
+%-install-lib:
+ $(MAKE) -C $* install-lib
+
+include $(BUILDRULES)
diff --git a/man/man1/Makefile b/man/man1/Makefile
new file mode 100644
index 0000000..2fd48eb
--- /dev/null
+++ b/man/man1/Makefile
@@ -0,0 +1,35 @@
+#
+# Copyright (c) 2000-2002 Silicon Graphics, Inc. All Rights Reserved.
+#
+# 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 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, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+
+TOPDIR = ../..
+include $(TOPDIR)/include/builddefs
+
+MAN_SECTION = 1
+
+MAN_PAGES = $(shell echo *.$(MAN_SECTION))
+MAN_DEST = $(PKG_MAN_DIR)/man$(MAN_SECTION)
+LSRCFILES = $(MAN_PAGES)
+
+default : $(MAN_PAGES)
+
+include $(BUILDRULES)
+
+install : default
+ $(INSTALL) -m 755 -d $(MAN_DEST)
+ $(INSTALL_MAN)
+install-dev install-lib:
diff --git a/man/man1/chacl.1 b/man/man1/chacl.1
new file mode 100644
index 0000000..74c7d98
--- /dev/null
+++ b/man/man1/chacl.1
@@ -0,0 +1,155 @@
+.\" Copyright (C) 2001, 2002, 2004 Silicon Graphics, Inc. All rights reserved.
+.\"
+.\" This is free documentation; 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 of
+.\" the License, or (at your option) any later version.
+.\"
+.\" The GNU General Public License's references to "object code"
+.\" and "executables" are to be interpreted as the output of any
+.\" document formatting or typesetting system, including
+.\" intermediate and printed output.
+.\"
+.\" This manual 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 manual. If not, see
+.\" <http://www.gnu.org/licenses/>.
+.\"
+.TH CHACL 1 "ACL File Utilities" "September 2001" "Access Control Lists"
+.SH NAME
+chacl \- change the access control list of a file or directory
+.SH SYNOPSIS
+.B chacl acl pathname...
+.br
+.B chacl \-b acl dacl pathname...
+.br
+.B chacl \-d dacl pathname...
+.br
+.B chacl \-R pathname...
+.br
+.B chacl \-D pathname...
+.br
+.B chacl \-B pathname...
+.br
+.B chacl \-l pathname...
+.br
+.B chacl \-r pathname...
+.br
+.SH DESCRIPTION
+.I chacl
+is an IRIX-compatibility command, and is maintained for those
+users who are familiar with its use from either XFS or IRIX.
+Refer to the
+.B "SEE ALSO"
+section below for a description of tools
+which conform more closely to the (withdrawn draft) POSIX 1003.1e
+standard which describes Access Control Lists (ACLs).
+.PP
+.I chacl
+changes the ACL(s) for a file or directory.
+The ACL(s) specified are applied to each file in the \f4pathname\f1 arguments.
+.P
+Each ACL is a string which is interpreted using the
+.IR acl_from_text (3)
+routine.
+These strings are made up of comma separated clauses each of which
+is of the form, tag:name:perm. Where \f4tag\fP can be:
+.TP
+"user" (or "u")
+indicating that the entry is a user ACL entry.
+.TP
+"group" (or "g")
+indicating that the entry is a group ACL entry.
+.TP
+"other" (or "o")
+indicating that the entry is an other ACL entry.
+.TP
+"mask" (or "m")
+indicating that the entry is a mask ACL entry.
+.P
+\f4name\fP is a string which is the user or group name for the ACL entry.
+A null \f4name\fP in a user or group ACL entry indicates the file's
+owner or file's group.
+\f4perm\fP is the string "rwx" where each of the entries may be replaced
+by a "\-" indicating no access of that type, e.g. "r\-x", "\-\-x", "\-\-\-".
+.SH OPTIONS
+.TP
+.B \-b
+Indicates that there are two ACLs to change, the first is the
+file access ACL and the second the directory default ACL.
+.TP
+.B \-d
+Used to set only the default ACL of a directory.
+.TP
+.B \-R
+Removes the file access ACL only.
+.TP
+.B \-D
+Removes directory default ACL only.
+.TP
+.B \-B
+Remove all ACLs.
+.TP
+.B \-l
+Lists the access ACL and possibly the default ACL associated
+with the specified files or directories. This option was added
+during the Linux port of XFS, and is not IRIX compatible.
+.TP
+.B \-r
+Set the access ACL recursively for each subtree rooted at \f4pathname\f1(s).
+This option was also added during the Linux port of XFS, and is not
+compatible with IRIX.
+.SH EXAMPLES
+A minimum ACL:
+.PP
+.nf
+ \f3chacl u::rwx,g::r-x,o::r-- file\fP
+.fi
+.PP
+The file ACL is set so that the file's owner has "rwx", the file's
+group has read and execute, and others have read only access to the file.
+.P
+An ACL that is not a minimum ACL, that is, one that specifies
+a user or group other than the file's owner or owner's group,
+must contain a mask entry:
+.PP
+.nf
+ \f4chacl u::rwx,g::r-x,o::r--,u:bob:r--,m::r-x file1 file2\fP
+.fi
+.PP
+To set the default and access ACLs on \f4newdir\f1 to be the
+same as on \f4olddir\f1, you could type:
+.PP
+.nf
+ \f4chacl \-b `chacl \-l olddir | \\
+ sed \-e 's/.*\\[//' \-e 's#/# #' \-e 's/]$//'` newdir
+\fP
+.fi
+.SH CAUTIONS
+.I chacl
+can replace the existing ACL. To add or delete entries, you
+must first do \f4chacl \-l\fP to get the existing ACL, and use the output
+to form the arguments to
+.IR chacl .
+.P
+Changing the permission bits of a file will change the file access
+ACL settings (see
+.IR chmod (1)).
+However, file creation mode masks (see
+.IR umask (1))
+will not affect the access ACL settings of files created using directory
+default ACLs.
+.P
+ACLs are filesystem extended attributes and hence are not typically
+archived or restored using the conventional archiving utilities.
+See
+.IR attr (5)
+for more information about extended attributes and see
+.IR xfsdump (8)
+for a method of backing them up under XFS.
+.SH SEE ALSO
+.BR getfacl "(1), " setfacl "(1), " chmod "(1), " umask "(1), " acl_from_text "(3), " acl "(5), " xfsdump (8)
diff --git a/man/man1/getfacl.1 b/man/man1/getfacl.1
new file mode 100644
index 0000000..967f72c
--- /dev/null
+++ b/man/man1/getfacl.1
@@ -0,0 +1,162 @@
+.\" Access Control Lists manual pages
+.\"
+.\" (C) 2000 Andreas Gruenbacher, <a.gruenbacher@bestbits.at>
+.\"
+.\" This is free documentation; 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 of
+.\" the License, or (at your option) any later version.
+.\"
+.\" The GNU General Public License's references to "object code"
+.\" and "executables" are to be interpreted as the output of any
+.\" document formatting or typesetting system, including
+.\" intermediate and printed output.
+.\"
+.\" This manual 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 manual. If not, see
+.\" <http://www.gnu.org/licenses/>.
+.\"
+.fam T
+.TH GETFACL 1 "ACL File Utilities" "May 2000" "Access Control Lists"
+.SH NAME
+getfacl \- get file access control lists
+.SH SYNOPSIS
+
+.B getfacl
+[\-aceEsRLPtpndvh] file ...
+
+.B getfacl
+[\-aceEsRLPtpndvh] \-
+
+.SH DESCRIPTION
+For each file, getfacl displays the file name, owner, the group,
+and the Access Control List (ACL). If a directory has a default ACL,
+getfacl also displays the default ACL. Non-directories cannot have default ACLs.
+
+If getfacl is used on a file system that does not support ACLs, getfacl
+displays the access permissions defined by the traditional file mode permission
+bits.
+
+The output format of getfacl is as follows:
+.fam C
+.RS
+.nf
+ 1: # file: somedir/
+ 2: # owner: lisa
+ 3: # group: staff
+ 4: user::rwx
+ 5: user:joe:rwx #effective:r\-x
+ 6: group::rwx #effective:r\-x
+ 7: group:cool:r\-x
+ 8: mask:r\-x
+ 9: other:r\-x
+10: default:user::rwx
+11: default:user:joe:rwx #effective:r\-x
+12: default:group::r\-x
+13: default:mask:r\-x
+14: default:other:\-\-\-
+
+.fi
+.RE
+.fam T
+
+Lines 4, 6 and 9 correspond to the user, group and other fields of
+the file mode permission bits. These three are called the base ACL
+entries. Lines 5 and 7 are named user and named group entries. Line 8 is
+the effective rights mask. This entry limits the effective rights granted
+to all groups and to named users. (The file owner and others permissions
+are not affected by the effective rights mask; all other entries are.)
+Lines 10\-\-14 display
+the default ACL associated with this directory. Directories may
+have a default ACL. Regular files never have a default ACL.
+
+The default behavior for getfacl is to display both the ACL and the
+default ACL, and to include an effective rights comment for lines
+where the rights of the entry differ from the effective rights.
+
+If output is to a terminal, the effective rights comment is aligned to
+column 40. Otherwise, a single tab character separates the ACL entry
+and the effective rights comment.
+
+The ACL listings of multiple files are separated by blank lines.
+The output of getfacl can also be used as input to setfacl.
+
+.SS PERMISSIONS
+Process with search access to a file (i.e., processes with read access
+to the containing directory of a file) are also granted read access
+to the file's ACLs. This is analogous to the permissions required for
+accessing the file mode.
+
+.SS OPTIONS
+.TP 4
+.I \-a, \-\-access
+Display the file access control list.
+.TP
+.I \-d, \-\-default
+Display the default access control list.
+.TP
+.I \-c, \-\-omit-header
+Do not display the comment header (the first three lines of each file's output).
+.TP
+.I \-e, \-\-all-effective
+Print all effective rights comments, even if identical to the rights defined by the ACL entry.
+.TP
+.I \-E, \-\-no-effective
+Do not print effective rights comments.
+.TP
+.I \-s, \-\-skip-base
+Skip files that only have the base ACL entries (owner, group, others).
+.TP
+.I \-R, \-\-recursive
+List the ACLs of all files and directories recursively.
+.TP
+.I \-L, \-\-logical
+Logical walk, follow symbolic links to directories. The default behavior is to follow
+symbolic link arguments, and skip symbolic links encountered in subdirectories.
+Only effective in combination with \-R.
+.TP
+.I \-P, \-\-physical
+Physical walk, do not follow symbolic links to directories. This also skips symbolic
+link arguments.
+Only effective in combination with \-R.
+.TP
+.I \-t, \-\-tabular
+Use an alternative tabular output format. The ACL and the default ACL are displayed side by side. Permissions that are ineffective due to the ACL mask entry are displayed capitalized. The entry tag names for the ACL_USER_OBJ and ACL_GROUP_OBJ entries are also displayed in capital letters, which helps in spotting those entries.
+.TP
+.I \-p, \-\-absolute-names
+Do not strip leading slash characters (`/'). The default behavior is to
+strip leading slash characters.
+.TP
+.I \-n, \-\-numeric
+List numeric user and group IDs
+.TP
+.I \-v, \-\-version
+Print the version of getfacl and exit.
+.TP
+.I \-h, \-\-help
+Print help explaining the command line options.
+.TP
+.I \-\-
+End of command line options. All remaining parameters are interpreted as file names, even if they start with a dash character.
+.TP
+.I \-
+If the file name parameter is a single dash character, getfacl reads a list of files from standard input.
+
+.SH CONFORMANCE TO POSIX 1003.1e DRAFT STANDARD 17
+If the environment variable POSIXLY_CORRECT is defined, the default behavior of getfacl changes in the following ways: Unless otherwise specified, only the ACL is printed. The default ACL is only printed if the
+.I \-d
+option is given. If no command line parameter is given,
+.I getfacl
+behaves as if it was invoked as ``getfacl \-''.
+.SH AUTHOR
+Andreas Gruenbacher,
+.RI < a.gruenbacher@bestbits.at >.
+
+Please send your bug reports and comments to the above address.
+.SH SEE ALSO
+.BR setfacl "(1), " acl (5)
diff --git a/man/man1/setfacl.1 b/man/man1/setfacl.1
new file mode 100644
index 0000000..000407f
--- /dev/null
+++ b/man/man1/setfacl.1
@@ -0,0 +1,295 @@
+.\" Access Control Lists manual pages
+.\"
+.\" (C) 2000 Andreas Gruenbacher, <a.gruenbacher@bestbits.at>
+.\"
+.\" This is free documentation; 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 of
+.\" the License, or (at your option) any later version.
+.\"
+.\" The GNU General Public License's references to "object code"
+.\" and "executables" are to be interpreted as the output of any
+.\" document formatting or typesetting system, including
+.\" intermediate and printed output.
+.\"
+.\" This manual 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 manual. If not, see
+.\" <http://www.gnu.org/licenses/>.
+.\"
+.TH SETFACL 1 "ACL File Utilities" "May 2000" "Access Control Lists"
+.SH NAME
+setfacl \- set file access control lists
+.SH SYNOPSIS
+
+.B setfacl
+[\-bkndRLPvh] [{\-m|\-x} acl_spec] [{\-M|\-X} acl_file] file ...
+
+.B setfacl
+\-\-restore=file
+
+.SH DESCRIPTION
+This utility sets Access Control Lists (ACLs) of files and directories.
+On the command line, a sequence of commands is followed by a sequence of
+files (which in turn can be followed by another sequence of commands, ...).
+
+The options
+.I \-m,
+and
+.I \-x
+expect an ACL on the command line. Multiple ACL entries are separated
+by comma characters (`,'). The options
+.I \-M,
+and
+.I \-X
+read an ACL from a file or from standard input. The ACL entry format is described in Section
+ACL ENTRIES.
+
+The
+.IR "\-\-set" " and " "\-\-set-file"
+options set the ACL of a file or a directory. The previous ACL is
+replaced.
+ACL entries for this operation must include permissions.
+
+The
+.IR "\-m (\-\-modify)" " and " "\-M (\-\-modify-file)"
+options modify the ACL of a file or directory.
+ACL entries for this operation must include permissions.
+
+The
+.IR "\-x (\-\-remove)" " and " "\-X (\-\-remove-file)"
+options remove ACL enries. Only
+ACL entries without the
+.I perms
+field are accepted as parameters, unless POSIXLY_CORRECT is defined.
+
+When reading from files using the
+.I \-M,
+and
+.IR \-X
+options, setfacl accepts the output getfacl produces.
+There is at most one ACL entry per line. After a Pound sign (`#'),
+everything up to the end of the line is treated as a comment.
+
+If setfacl is used on a file system which does not support ACLs, setfacl
+operates on the file mode permission bits. If the ACL does not fit completely
+in the permission bits, setfacl modifies the file mode permission bits to reflect the ACL as closely as possible, writes an error message to standard error, and returns with an exit status greater than 0.
+
+.SS PERMISSIONS
+The file owner and processes capable of CAP_FOWNER are granted the right
+to modify ACLs of a file. This is analogous to the permissions required
+for accessing the file mode. (On current Linux systems, root is the only
+user with the CAP_FOWNER capability.)
+
+.SS OPTIONS
+.TP 4
+.I \-b, \-\-remove-all
+Remove all extended ACL entries. The base ACL entries of the owner, group and others are retained.
+.TP 4
+.I \-k, \-\-remove-default
+Remove the Default ACL. If no Default ACL exists, no warnings are issued.
+.TP 4
+.I \-n, \-\-no-mask
+Do not recalculate the effective rights mask. The default behavior of
+setfacl is to recalculate the ACL mask entry, unless a mask entry was explicitly given.
+The mask entry is set to the union of all permissions of the owning group, and all named user and group entries. (These are exactly the entries affected by the mask entry).
+.TP 4
+.I \-\-mask
+Do recalculate the effective rights mask, even if an ACL mask entry was explicitly given. (See the
+.IR "\-n " option.)
+.TP 4
+.I \-d, \-\-default
+All operations apply to the Default ACL. Regular ACL entries in the
+input set are promoted to Default ACL entries. Default ACL entries in
+the input set are discarded. (A warning is issued if that happens).
+.TP 4
+.I \-\-restore=file
+Restore a permission backup created by `getfacl \-R' or similar. All permissions
+of a complete directory subtree are restored using this mechanism. If the input
+contains owner comments or group comments, and setfacl is run by root, the
+owner and owning group of all files are restored as well. This option cannot be mixed with other options except `\-\-test'.
+.TP 4
+.I \-\-test
+Test mode. Instead of changing the ACLs of any files, the resulting ACLs are listed.
+.TP 4
+.I \-R, \-\-recursive
+Apply operations to all files and directories recursively. This option cannot be mixed with `\-\-restore'.
+.TP 4
+.I \-L, \-\-logical
+Logical walk, follow symbolic links to directories. The default behavior is to follow
+symbolic link arguments, and skip symbolic links encountered in subdirectories.
+Only effective in combination with \-R.
+This option cannot be mixed with `\-\-restore'.
+.TP 4
+.I \-P, \-\-physical
+Physical walk, do not follow symbolic links to directories.
+This also skips symbolic link arguments.
+Only effective in combination with \-R.
+This option cannot be mixed with `\-\-restore'.
+.TP 4
+.I \-v, \-\-version
+Print the version of setfacl and exit.
+.TP 4
+.I \-h, \-\-help
+Print help explaining the command line options.
+.TP 4
+.I \-\-
+End of command line options. All remaining parameters are interpreted as file names, even if they start with a dash.
+.TP 4
+.I \-
+If the file name parameter is a single dash, setfacl reads a list of files from standard input.
+
+.SS ACL ENTRIES
+The setfacl utility recognizes the following ACL entry formats (blanks
+inserted for clarity):
+
+.fam C
+.TP
+.RI "[d[efault]:] [u[ser]:]" "uid " [: perms ]
+.fam T
+Permissions of a named user. Permissions of the file owner if
+.I uid
+is empty.
+.fam C
+.TP
+.RI "[d[efault]:] g[roup]:" "gid " [: perms ]
+.fam T
+Permissions of a named group. Permissions of the owning group if
+.I gid
+is empty.
+.fam C
+.TP
+.RI "[d[efault]:] m[ask][:] [:" perms ]
+.fam T
+Effective rights mask
+.fam C
+.TP
+.RI "[d[efault]:] o[ther][:] [:" perms ]
+.fam T
+Permissions of others.
+.PP
+Whitespace between delimiter characters and non-delimiter characters is ignored.
+.PP
+.PP
+Proper ACL entries including permissions are used in modify and set operations. (options
+.IR \-m ", " \-M ", " \-\-set " and " \-\-set-file ).
+Entries without the
+.I perms
+field are used for
+.I deletion
+of entries (options
+.IR \-x " and " \-X ).
+.PP
+For
+.I uid
+and
+.I gid
+you can specify either a name or a number.
+.PP
+The
+.I perms
+field is a combination of characters that indicate the permissions: read
+.IR (r) ,
+write
+.IR (w) ,
+execute
+.IR (x) ,
+execute only if the file is a directory or already has execute permission
+for some user
+.IR (X) .
+Alternatively, the
+.I perms
+field can be an octal digit (0\-7).
+.PP
+.SS AUTOMATICALLY CREATED ENTRIES
+Initially, files and directories contain only the three base ACL entries
+for the owner, the group, and others. There are some rules that
+need to be satisfied in order for an ACL to be valid:
+.IP * 4
+The three base entries cannot be removed. There must be exactly one
+entry of each of these base entry types.
+.IP * 4
+Whenever an ACL contains named user entries or named group objects,
+it must also contain an effective rights mask.
+.IP * 4
+Whenever an ACL contains any Default ACL entries, the three Default ACL
+base entries (default owner, default group, and default others) must also exist.
+.IP * 4
+Whenever a Default ACL contains named user entries or named group objects,
+it must also contain a default effective rights mask.
+.PP
+To help the user ensure these rules, setfacl creates entries from existing
+entries under the following conditions:
+.IP * 4
+If an ACL contains named user or named group entries, and
+no mask entry exists, a mask entry containing the same permissions as
+the group entry is created. Unless the
+.I \-n
+option is given, the permissions of the mask entry are further adjusted to include the union of all permissions affected by the mask entry. (See the
+.I \-n
+option description).
+.IP * 4
+If a Default ACL entry is created, and the Default ACL contains no
+owner, owning group, or others entry, a copy of the ACL owner, owning group, or others entry is added to the Default ACL.
+.IP * 4
+If a Default ACL contains named user entries or named group entries, and no mask entry exists, a mask entry containing the same permissions as the default Default ACL's group entry is added. Unless the
+.I \-n
+option is given, the permissions of the mask entry are further adjusted to inclu
+de the union of all permissions affected by the mask entry. (See the
+.I \-n
+option description).
+.PP
+.SH EXAMPLES
+.PP
+Granting an additional user read access
+.RS
+.fam C
+setfacl \-m u:lisa:r file
+.fam T
+.RE
+.PP
+Revoking write access from all groups and all named users (using the effective rights mask)
+.RS
+.fam C
+setfacl \-m m::rx file
+.fam T
+.RE
+.PP
+Removing a named group entry from a file's ACL
+.RS
+.fam C
+setfacl \-x g:staff file
+.fam T
+.RE
+.PP
+Copying the ACL of one file to another
+.RS
+.fam C
+getfacl file1 | setfacl \-\-set-file=\- file2
+.fam T
+.RE
+.PP
+Copying the access ACL into the Default ACL
+.RS
+.fam C
+getfacl \-\-access dir | setfacl \-d \-M\- dir
+.fam T
+.RE
+.SH CONFORMANCE TO POSIX 1003.1e DRAFT STANDARD 17
+If the environment variable POSIXLY_CORRECT is defined, the default behavior of setfacl changes as follows: All non-standard options are disabled.
+The ``default:'' prefix is disabled.
+The
+.IR \-x " and " \-X
+options also accept permission fields (and ignore them).
+.SH AUTHOR
+Andreas Gruenbacher,
+.RI < a.gruenbacher@bestbits.at >.
+
+Please send your bug reports, suggested features and comments to the
+above address.
+.SH SEE ALSO
+.BR getfacl "(1), " chmod "(1), " umask "(1), " acl (5)
diff --git a/man/man3/Makefile b/man/man3/Makefile
new file mode 100644
index 0000000..c00f02d
--- /dev/null
+++ b/man/man3/Makefile
@@ -0,0 +1,35 @@
+#
+# Copyright (c) 2000-2002 Silicon Graphics, Inc. All Rights Reserved.
+#
+# 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 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, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+
+TOPDIR = ../..
+include $(TOPDIR)/include/builddefs
+
+MAN_SECTION = 3
+
+MAN_PAGES = $(shell echo *.$(MAN_SECTION))
+MAN_DEST = $(PKG_MAN_DIR)/man$(MAN_SECTION)
+LSRCFILES = $(MAN_PAGES)
+
+default : $(MAN_PAGES)
+
+include $(BUILDRULES)
+
+install-dev : default
+ $(INSTALL) -m 755 -d $(MAN_DEST)
+ $(INSTALL_MAN)
+install install-lib:
diff --git a/man/man3/acl_add_perm.3 b/man/man3/acl_add_perm.3
new file mode 100644
index 0000000..2119832
--- /dev/null
+++ b/man/man3/acl_add_perm.3
@@ -0,0 +1,85 @@
+.\" Access Control Lists manual pages
+.\"
+.\" (C) 2002 Andreas Gruenbacher, <a.gruenbacher@bestbits.at>
+.\"
+.\" This is free documentation; 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 of
+.\" the License, or (at your option) any later version.
+.\"
+.\" The GNU General Public License's references to "object code"
+.\" and "executables" are to be interpreted as the output of any
+.\" document formatting or typesetting system, including
+.\" intermediate and printed output.
+.\"
+.\" This manual 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 manual. If not, see
+.\" <http://www.gnu.org/licenses/>.
+.\"
+.Dd March 23, 2002
+.Dt ACL_ADD_PERM 3
+.Os "Linux ACL"
+.Sh NAME
+.Nm acl_add_perm
+.Nd add a permission to an ACL permission set
+.Sh LIBRARY
+Linux Access Control Lists library (libacl, \-lacl).
+.Sh SYNOPSIS
+.In sys/types.h
+.In sys/acl.h
+.Ft int
+.Fn acl_add_perm "acl_permset_t permset_d" "acl_perm_t perm"
+.Sh DESCRIPTION
+The
+.Fn acl_add_perm
+function adds the permission contained in the argument
+.Va perm
+to the permission set referred to by the argument
+.Va permset_d .
+An attempt to add a permission that is already contained in the permission
+set is not considered an error.
+.Pp
+Any existing descriptors that refer to
+.Va permset_d
+continue to refer to that permission set.
+.Sh RETURN VALUE
+.Rv -std acl_add_perm
+.Sh ERRORS
+If any of the following conditions occur, the
+.Fn acl_add_perm
+function returns
+.Li -1
+and sets
+.Va errno
+to the corresponding value:
+.Bl -tag -width Er
+.It Bq Er EINVAL
+The argument
+.Va permset_d
+is not a valid descriptor for a permission set within an ACL entry.
+.Pp
+The argument
+.Va perm
+does not contain a valid
+.Va acl_perm_t
+value.
+.El
+.Sh STANDARDS
+IEEE Std 1003.1e draft 17 (\(lqPOSIX.1e\(rq, abandoned)
+.Sh SEE ALSO
+.Xr acl_clear_perms 3 ,
+.Xr acl_delete_perm 3 ,
+.Xr acl_get_perm 3 ,
+.Xr acl_get_permset 3 ,
+.Xr acl_set_permset 3 ,
+.Xr acl 5
+.Sh AUTHOR
+Derived from the FreeBSD manual pages written by
+.An "Robert N M Watson" Aq rwatson@FreeBSD.org ,
+and adapted for Linux by
+.An "Andreas Gruenbacher" Aq a.gruenbacher@bestbits.at .
diff --git a/man/man3/acl_calc_mask.3 b/man/man3/acl_calc_mask.3
new file mode 100644
index 0000000..fa69f96
--- /dev/null
+++ b/man/man3/acl_calc_mask.3
@@ -0,0 +1,101 @@
+.\" Access Control Lists manual pages
+.\"
+.\" (C) 2002 Andreas Gruenbacher, <a.gruenbacher@bestbits.at>
+.\"
+.\" This is free documentation; 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 of
+.\" the License, or (at your option) any later version.
+.\"
+.\" The GNU General Public License's references to "object code"
+.\" and "executables" are to be interpreted as the output of any
+.\" document formatting or typesetting system, including
+.\" intermediate and printed output.
+.\"
+.\" This manual 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 manual. If not, see
+.\" <http://www.gnu.org/licenses/>.
+.\"
+.Dd March 23, 2002
+.Dt ACL_CALC_MASK 3
+.Os "Linux ACL"
+.Sh NAME
+.Nm acl_calc_mask
+.Nd calculate the file group class mask
+.Sh LIBRARY
+Linux Access Control Lists library (libacl, \-lacl).
+.Sh SYNOPSIS
+.In sys/types.h
+.In sys/acl.h
+.Ft int
+.Fn acl_calc_mask "acl_t *acl_p"
+.Sh DESCRIPTION
+The
+.Fn acl_calc_mask
+function calculates and sets the permissions associated with the ACL_MASK
+ACL entry of the ACL referred to by
+.Va acl_p .
+The value of the new permissions is the union of the permissions
+granted by all entries of tag type ACL_GROUP, ACL_GROUP_OBJ, or ACL_USER.
+If the ACL referred to by
+.Va acl_p
+already contains an ACL_MASK entry, its permissions are overwritten;
+if it does not contain an ACL_MASK entry, one is added.
+.Pp
+If the ACL referred to by
+.Va acl_p
+does not contain enough space for the new ACL entry, then additional working
+storage may be allocated. If the working storage cannot be increased in the
+current location, then it may be relocated and the previous working storage
+is released and a pointer to the new working storage is returned via
+.Va acl_p .
+.Pp
+The order of existing entries in the ACL is undefined after this function.
+.Pp
+Any existing ACL entry descriptors that refer to entries in the ACL continue to
+refer to those entries. Any existing ACL pointers that refer to the ACL
+referred to by
+.Va acl_p
+continue to refer to the ACL.
+.\" <AG>
+.\" Conflict between requirements:
+.\" (a) ACL may be relocated,
+.\" (b) all pointers remain valid.
+.\" </AG>
+.Sh RETURN VALUE
+.Rv -std acl_calc_mask
+.Sh ERRORS
+If any of the following conditions occur, the
+.Fn acl_calc_mask
+function returns
+.Li -1
+and sets
+.Va errno
+to the corresponding value:
+.Bl -tag -width Er
+.It Bq Er EINVAL
+The argument
+.Va acl
+is not a valid pointer to an ACL.
+.It Bq Er ENOMEM
+The
+.Fn acl_calc_mask
+function is unable to allocate the memory required for an ACL_MASK ACL entry.
+.El
+.Sh STANDARDS
+IEEE Std 1003.1e draft 17 (\(lqPOSIX.1e\(rq, abandoned)
+.Sh SEE ALSO
+.Xr acl_check 3 ,
+.Xr acl_get_entry 3 ,
+.Xr acl_valid 3 ,
+.Xr acl 5
+.Sh AUTHOR
+Derived from the FreeBSD manual pages written by
+.An "Robert N M Watson" Aq rwatson@FreeBSD.org ,
+and adapted for Linux by
+.An "Andreas Gruenbacher" Aq a.gruenbacher@bestbits.at .
diff --git a/man/man3/acl_check.3 b/man/man3/acl_check.3
new file mode 100644
index 0000000..b583b1a
--- /dev/null
+++ b/man/man3/acl_check.3
@@ -0,0 +1,122 @@
+.\" Access Control Lists manual pages
+.\"
+.\" (C) 2002 Andreas Gruenbacher, <a.gruenbacher@bestbits.at>
+.\"
+.\" This is free documentation; 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 of
+.\" the License, or (at your option) any later version.
+.\"
+.\" The GNU General Public License's references to "object code"
+.\" and "executables" are to be interpreted as the output of any
+.\" document formatting or typesetting system, including
+.\" intermediate and printed output.
+.\"
+.\" This manual 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 manual. If not, see
+.\" <http://www.gnu.org/licenses/>.
+.\"
+.Dd March 23, 2002
+.Dt ACL_CHECK 3
+.Os "Linux ACL"
+.Sh NAME
+.Nm acl_check
+.Nd check an ACL for validity
+.Sh LIBRARY
+Linux Access Control Lists library (libacl, \-lacl).
+.Sh SYNOPSIS
+.In sys/types.h
+.In acl/libacl.h
+.Ft int
+.Fn acl_check "acl_t acl" "int *last"
+.Sh DESCRIPTION
+The
+.Fn acl_check
+function checks the ACL referred to by the argument
+.Va acl
+for validity.
+.Pp
+The three required entries ACL_USER_OBJ, ACL_GROUP_OBJ, and ACL_OTHER
+must exist exactly once in the ACL. If the ACL contains any ACL_USER or
+ACL_GROUP entries, then an ACL_MASK entry is also required. The ACL
+may contain at most one ACL_MASK entry.
+.Pp
+The user identifiers must be unique among all entries of type ACL_USER.
+The group identifiers must be unique among all entries of type ACL_GROUP.
+.Pp
+If the ACL referred to by
+.Va acl
+is invalid,
+.Fn acl_check
+returns a positive error code that indicates which type of error was detected.
+The following symbolic error codes are defined:
+.Bl -tag -width ACL_DUPLICATE_ERROR.
+.It ACL_MULTI_ERROR
+The ACL contains multiple entries that have a tag type
+that may occur at most once.
+.It ACL_DUPLICATE_ERROR
+The ACL contains multiple ACL_USER entries with the same user ID, or
+multiple ACL_GROUP entries with the same group ID.
+.It ACL_MISS_ERROR
+A required entry is missing.
+.It ACL_ENTRY_ERROR
+The ACL contains an invalid entry tag type.
+.El
+.Pp
+The
+.Fn acl_error
+function can be used to translate error codes to text messages.
+.Pp
+In addition, if the pointer
+.Va last
+is not
+.Li NULL ,
+.Fn acl_check
+assigns the number of the ACL entry at which the error was detected to
+the value pointed to by
+.Va last .
+Entries are numbered starting with zero, in the order in which they would be
+returned by the
+.Fn acl_get_entry
+function.
+.Sh RETURN VALUE
+If successful, the
+.Fn acl_check
+function returns
+.Li 0
+if the ACL referred to by
+.Va acl
+is valid, and a positive error code if the ACL is invalid. Otherwise, a
+value of
+.Li -1
+is returned and the global variable
+.Va errno
+is set to indicate the error.
+.Sh ERRORS
+If any of the following conditions occur, the
+.Fn acl_check
+function returns
+.Li -1
+and sets
+.Va errno
+to the corresponding value:
+.Bl -tag -width Er
+.It Bq Er EINVAL
+The argument
+.Va acl
+is not a valid pointer to an ACL.
+.El
+.Sh STANDARDS
+This is a non-portable, Linux specific extension to the ACL manipulation
+functions defined in IEEE Std 1003.1e draft 17 (\(lqPOSIX.1e\(rq, abandoned).
+.Sh SEE ALSO
+.Xr acl_valid 3 ,
+.Xr acl 5
+.Sh AUTHOR
+Written by
+.An "Andreas Gruenbacher" Aq a.gruenbacher@bestbits.at .
diff --git a/man/man3/acl_clear_perms.3 b/man/man3/acl_clear_perms.3
new file mode 100644
index 0000000..c7bff94
--- /dev/null
+++ b/man/man3/acl_clear_perms.3
@@ -0,0 +1,75 @@
+.\" Access Control Lists manual pages
+.\"
+.\" (C) 2002 Andreas Gruenbacher, <a.gruenbacher@bestbits.at>
+.\"
+.\" This is free documentation; 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 of
+.\" the License, or (at your option) any later version.
+.\"
+.\" The GNU General Public License's references to "object code"
+.\" and "executables" are to be interpreted as the output of any
+.\" document formatting or typesetting system, including
+.\" intermediate and printed output.
+.\"
+.\" This manual 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 manual. If not, see
+.\" <http://www.gnu.org/licenses/>.
+.\"
+.Dd March 23, 2002
+.Dt ACL_CLEAR_PERMS 3
+.Os "Linux ACL"
+.Sh NAME
+.Nm acl_clear_perms
+.Nd clear all permissions from an ACL permission set
+.Sh LIBRARY
+Linux Access Control Lists library (libacl, \-lacl).
+.Sh SYNOPSIS
+.In sys/types.h
+.In sys/acl.h
+.Ft int
+.Fn acl_clear_perms "acl_permset_t permset_d"
+.Sh DESCRIPTION
+The
+.Fn acl_clear_perms
+function clears all permissions from the permission set referred to by the argument
+.Va permset_d .
+.Pp
+Any existing descriptors that refer to
+.Va permset_d
+shall continue to refer to that permission set.
+.Sh RETURN VALUE
+.Rv -std acl_clear_perms
+.Sh ERRORS
+If any of the following conditions occur, the
+.Fn acl_clear_perms
+function returns
+.Li -1
+and sets
+.Va errno
+to the corresponding value:
+.Bl -tag -width Er
+.It Bq Er EINVAL
+The argument
+.Va permset_d
+is not a valid descriptor for a permission set within an ACL entry.
+.El
+.Sh STANDARDS
+IEEE Std 1003.1e draft 17 (\(lqPOSIX.1e\(rq, abandoned)
+.Sh SEE ALSO
+.Xr acl_add_perm 3 ,
+.Xr acl_delete_perm 3 ,
+.Xr acl_get_perm 3 ,
+.Xr acl_get_permset 3 ,
+.Xr acl_set_permset 3 ,
+.Xr acl 5
+.Sh AUTHOR
+Derived from the FreeBSD manual pages written by
+.An "Robert N M Watson" Aq rwatson@FreeBSD.org ,
+and adapted for Linux by
+.An "Andreas Gruenbacher" Aq a.gruenbacher@bestbits.at .
diff --git a/man/man3/acl_cmp.3 b/man/man3/acl_cmp.3
new file mode 100644
index 0000000..1b565a5
--- /dev/null
+++ b/man/man3/acl_cmp.3
@@ -0,0 +1,90 @@
+.\" Access Control Lists manual pages
+.\"
+.\" (C) 2002 Andreas Gruenbacher, <a.gruenbacher@bestbits.at>
+.\"
+.\" This is free documentation; 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 of
+.\" the License, or (at your option) any later version.
+.\"
+.\" The GNU General Public License's references to "object code"
+.\" and "executables" are to be interpreted as the output of any
+.\" document formatting or typesetting system, including
+.\" intermediate and printed output.
+.\"
+.\" This manual 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 manual. If not, see
+.\" <http://www.gnu.org/licenses/>.
+.\"
+.Dd March 23, 2002
+.Dt ACL_CMP 3
+.Os "Linux ACL"
+.Sh NAME
+.Nm acl_cmp
+.Nd compare two ACLs
+.Sh LIBRARY
+Linux Access Control Lists library (libacl, \-lacl).
+.Sh SYNOPSIS
+.In sys/types.h
+.In acl/libacl.h
+.Ft int
+.Fn acl_cmp "acl_t acl1" "acl_t acl2"
+.Sh DESCRIPTION
+The
+.Fn acl_cmp
+function compares the ACLs pointed to by the arguments
+.Va acl1
+and
+.Va acl2
+for equality. The two ACLs are considered equal if for each entry in
+.Va acl1
+there is an entry in
+.Va acl2
+with matching tag type, qualifier, and permissions, and vice versa.
+.Sh RETURN VALUE
+If successful, the
+.Fn acl_cmp
+function returns
+.Li 0
+if the two ACLs
+.Va acl1
+and
+.Va acl2
+are equal, and
+.Li 1
+if they differ. Otherwise, the value
+.Li -1
+is returned and the global variable
+.Va errno
+is set to indicate the error.
+.Sh ERRORS
+If any of the following conditions occur, the
+.Fn acl_cmp
+function returns
+.Li -1
+and sets
+.Va errno
+to the corresponding value:
+.Bl -tag -width Er
+.It Bq Er EINVAL
+The argument
+.Va acl1
+is not a valid pointer to an ACL.
+.Pp
+The argument
+.Va acl2
+is not a valid pointer to an ACL.
+.El
+.Sh STANDARDS
+This is a non-portable, Linux specific extension to the ACL manipulation
+functions defined in IEEE Std 1003.1e draft 17 (\(lqPOSIX.1e\(rq, abandoned).
+.Sh SEE ALSO
+.Xr acl 5
+.Sh AUTHOR
+Written by
+.An "Andreas Gruenbacher" Aq a.gruenbacher@bestbits.at .
diff --git a/man/man3/acl_copy_entry.3 b/man/man3/acl_copy_entry.3
new file mode 100644
index 0000000..90c9106
--- /dev/null
+++ b/man/man3/acl_copy_entry.3
@@ -0,0 +1,82 @@
+.\" Access Control Lists manual pages
+.\"
+.\" (C) 2002 Andreas Gruenbacher, <a.gruenbacher@bestbits.at>
+.\"
+.\" This is free documentation; 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 of
+.\" the License, or (at your option) any later version.
+.\"
+.\" The GNU General Public License's references to "object code"
+.\" and "executables" are to be interpreted as the output of any
+.\" document formatting or typesetting system, including
+.\" intermediate and printed output.
+.\"
+.\" This manual 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 manual. If not, see
+.\" <http://www.gnu.org/licenses/>.
+.\"
+.Dd March 23, 2002
+.Dt ACL_COPY_ENTRY 3
+.Os "Linux ACL"
+.Sh NAME
+.Nm acl_copy_entry
+.Nd copy an ACL entry
+.Sh LIBRARY
+Linux Access Control Lists library (libacl, \-lacl).
+.Sh SYNOPSIS
+.In sys/types.h
+.In sys/acl.h
+.Ft int
+.Fn acl_copy_entry "acl_entry_t dest_d" "acl_entry_t src_d"
+.Sh DESCRIPTION
+The
+.Fn acl_copy_entry
+function copies the contents of the ACL entry indicated by the
+.Va src_d
+descriptor to the existing ACL entry indicated by the
+.Va dest_d
+descriptor. The
+.Va src_d
+and
+.Va dest_d
+descriptors may refer to entries in different ACLs.
+.Sh RETURN VALUE
+.Rv -std acl_copy_entry
+.Sh ERRORS
+If any of the following conditions occur, the
+.Fn acl_copy_entry
+function returns
+.Li -1
+and sets
+.Va errno
+to the corresponding value:
+.Bl -tag -width Er
+.It Bq Er EINVAL
+The argument
+.Va src_d
+or
+.Va dest_d
+is not a valid descriptor for an ACL entry.
+.Pp
+The arguments
+.Va src_d
+and
+.Va dest_d
+reference the same ACL entry.
+.El
+.Sh STANDARDS
+IEEE Std 1003.1e draft 17 (\(lqPOSIX.1e\(rq, abandoned)
+.Sh SEE ALSO
+.Xr acl_get_entry 3 ,
+.Xr acl 5
+.Sh AUTHOR
+Derived from the FreeBSD manual pages written by
+.An "Robert N M Watson" Aq rwatson@FreeBSD.org ,
+and adapted for Linux by
+.An "Andreas Gruenbacher" Aq a.gruenbacher@bestbits.at .
diff --git a/man/man3/acl_copy_ext.3 b/man/man3/acl_copy_ext.3
new file mode 100644
index 0000000..a509ec8
--- /dev/null
+++ b/man/man3/acl_copy_ext.3
@@ -0,0 +1,108 @@
+.\" Access Control Lists manual pages
+.\"
+.\" (C) 2002 Andreas Gruenbacher, <a.gruenbacher@bestbits.at>
+.\"
+.\" This is free documentation; 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 of
+.\" the License, or (at your option) any later version.
+.\"
+.\" The GNU General Public License's references to "object code"
+.\" and "executables" are to be interpreted as the output of any
+.\" document formatting or typesetting system, including
+.\" intermediate and printed output.
+.\"
+.\" This manual 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 manual. If not, see
+.\" <http://www.gnu.org/licenses/>.
+.\"
+.Dd March 23, 2002
+.Dt ACL_COPY_EXT 3
+.Os "Linux ACL"
+.Sh NAME
+.Nm acl_copy_ext
+.Nd copy an ACL from internal to external representation
+.Sh LIBRARY
+Linux Access Control Lists library (libacl, \-lacl).
+.Sh SYNOPSIS
+.In sys/types.h
+.In sys/acl.h
+.Ft ssize_t
+.Fn acl_copy_ext "void *buf_p" "acl_t acl" "ssize_t size"
+.Sh DESCRIPTION
+The
+.Fn acl_copy_ext
+function copies the ACL pointed to by
+.Va acl
+from system-managed space to the user managed space pointed to by
+.Va buf_p .
+The
+.Va size
+parameter represents the size in bytes of the buffer pointed to by
+.Va buf_p .
+The format of the ACL placed in the buffer pointed to by
+.Va buf_p
+is a contiguous, persistent data item, the format of which is unspecified.
+It is the responsibility of the invoker to allocate an area large enough
+to hold the copied ACL. The size of the exportable, contiguous, persistent
+form of the ACL may be obtained by invoking the
+.Fn acl_size
+function.
+.Pp
+Any ACL entry descriptors that refer to an entry in the ACL referenced by
+.Va acl
+continue to refer to those entries. Any existing ACL pointers that refer
+to the ACL referenced by
+.Va acl
+continue to refer to the ACL.
+.Sh RETURN VALUE
+Upon success, this function returns the number of bytes placed in the buffer pointed to by
+.Va buf_p .
+On error, a value of
+.Li (ssize_t)-1
+is returned and
+.Va errno
+is set appropriately.
+.Sh ERRORS
+If any of the following conditions occur, the
+.Fn acl_copy_ext
+function returns a value of
+.Li (ssize_t)-1
+and sets
+.Va errno
+to the corresponding value:
+.Bl -tag -width Er
+.It Bq Er EINVAL
+The
+.Va size
+parameter is zero or negative.
+.Pp
+The argument
+.Va acl
+is not a valid pointer to an ACL.
+.Pp
+The ACL referenced by
+.Va acl
+contains one or more improperly formed ACL entries, or for some other
+reason cannot be translated into the external form of an ACL.
+.It Bq Er ERANGE
+The
+.Va size
+parameter is greater than zero but smaller than the length of the contiguous, persistent form of the ACL.
+.El
+.Sh STANDARDS
+IEEE Std 1003.1e draft 17 (\(lqPOSIX.1e\(rq, abandoned)
+.Sh SEE ALSO
+.Xr acl_copy_int 3 ,
+.Xr acl_size 3 ,
+.Xr acl 5
+.Sh AUTHOR
+Derived from the FreeBSD manual pages written by
+.An "Robert N M Watson" Aq rwatson@FreeBSD.org ,
+and adapted for Linux by
+.An "Andreas Gruenbacher" Aq a.gruenbacher@bestbits.at .
diff --git a/man/man3/acl_copy_int.3 b/man/man3/acl_copy_int.3
new file mode 100644
index 0000000..b34e7c7
--- /dev/null
+++ b/man/man3/acl_copy_int.3
@@ -0,0 +1,89 @@
+.\" Access Control Lists manual pages
+.\"
+.\" (C) 2002 Andreas Gruenbacher, <a.gruenbacher@bestbits.at>
+.\"
+.\" This is free documentation; 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 of
+.\" the License, or (at your option) any later version.
+.\"
+.\" The GNU General Public License's references to "object code"
+.\" and "executables" are to be interpreted as the output of any
+.\" document formatting or typesetting system, including
+.\" intermediate and printed output.
+.\"
+.\" This manual 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 manual. If not, see
+.\" <http://www.gnu.org/licenses/>.
+.\"
+.Dd March 23, 2002
+.Dt ACL_COPY_INT 3
+.Os "Linux ACL"
+.Sh NAME
+.Nm acl_copy_int
+.Nd copy an ACL from external to internal representation
+.Sh LIBRARY
+Linux Access Control Lists library (libacl, \-lacl).
+.Sh SYNOPSIS
+.In sys/types.h
+.In sys/acl.h
+.Ft acl_t
+.Fn acl_copy_int "const void *buf_p"
+.Sh DESCRIPTION
+The
+.Fn acl_copy_int
+function copies an exportable, contiguous, persistent form of an ACL, pointed to by
+.Va buf_p ,
+to the internal representation.
+.Pp
+This function may cause memory to be allocated. The caller should free any
+releasable memory, when the new ACL is no longer required, by calling
+.Xr acl_free 3
+with the
+.Va (void*)acl_t
+returned by
+.Fn acl_copy_int
+as an argument.
+.Sh RETURN VALUE
+Upon success,
+the
+.Fn acl_copy_int
+function returns a pointer that references the ACL in working storage.
+On error, a value of
+.Li (acl_t)NULL
+is returned, and
+.Va errno
+is set appropriately.
+.Sh ERRORS
+If any of the following conditions occur, the
+.Fn acl_copy_int
+function returns a value of
+.Li (acl_t)NULL
+and sets
+.Va errno
+to the corresponding value:
+.Bl -tag -width Er
+.It Bq Er EINVAL
+The buffer pointed to by the argument
+.Va buf_p
+does not contain a valid external form ACL.
+.It Bq Er ENOMEM
+The ACL working storage requires more memory than is allowed by the hardware or system-imposed memory management constraints.
+.El
+.Sh STANDARDS
+IEEE Std 1003.1e draft 17 (\(lqPOSIX.1e\(rq, abandoned)
+.Sh SEE ALSO
+.Xr acl_copy_ext 3 ,
+.Xr acl_get_entry 3 ,
+.Xr acl_free 3 ,
+.Xr acl 5
+.Sh AUTHOR
+Derived from the FreeBSD manual pages written by
+.An "Robert N M Watson" Aq rwatson@FreeBSD.org ,
+and adapted for Linux by
+.An "Andreas Gruenbacher" Aq a.gruenbacher@bestbits.at .
diff --git a/man/man3/acl_create_entry.3 b/man/man3/acl_create_entry.3
new file mode 100644
index 0000000..e3515f7
--- /dev/null
+++ b/man/man3/acl_create_entry.3
@@ -0,0 +1,104 @@
+.\" Access Control Lists manual pages
+.\"
+.\" (C) 2002 Andreas Gruenbacher, <a.gruenbacher@bestbits.at>
+.\"
+.\" This is free documentation; 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 of
+.\" the License, or (at your option) any later version.
+.\"
+.\" The GNU General Public License's references to "object code"
+.\" and "executables" are to be interpreted as the output of any
+.\" document formatting or typesetting system, including
+.\" intermediate and printed output.
+.\"
+.\" This manual 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 manual. If not, see
+.\" <http://www.gnu.org/licenses/>.
+.\"
+.Dd March 23, 2002
+.Dt ACL_CREATE_ENTRY 3
+.Os "Linux ACL"
+.Sh NAME
+.Nm acl_create_entry
+.Nd create a new ACL entry
+.Sh LIBRARY
+Linux Access Control Lists library (libacl, \-lacl).
+.Sh SYNOPSIS
+.In sys/types.h
+.In sys/acl.h
+.Ft int
+.Fn acl_create_entry "acl_t *acl_p" "acl_entry_t *entry_p"
+.Sh DESCRIPTION
+The
+.Fn acl_create_entry
+function creates a new ACL entry in the ACL pointed to by the contents of the pointer argument
+.Va acl_p .
+On success, the function returns a descriptor for the new
+ACL entry via
+.Va entry_p .
+.Pp
+This function may cause memory to be allocated. The caller should free any
+releasable memory, when the new ACL is no longer required, by calling
+.Xr acl_free 3
+with
+.\" <AG>
+.\" 1003.1e says:
+.\" .Va (void*)acl_t
+.\" this makes no sense, so:
+.Va (void*)*acl_p
+.\" </AG>
+as an argument.
+If the ACL working storage cannot be increased in the current location,
+then the working storage for the ACL pointed to by
+.Va acl_p
+may be relocated and the previous working storage is released. A pointer to
+the new working storage is returned via
+.Va acl_p .
+.Pp
+The components of the new ACL entry are initialized in the following ways: the
+ACL tag type component contains ACL_UNDEFINED_TAG, the qualifier component
+contains ACL_UNDEFINED_ID, and the set of permissions has no permissions
+enabled. Any existing ACL entry descriptors that refer to entries in the ACL
+continue to refer to those entries.
+.\" <AG>
+.\" Conflict between requirements:
+.\" (a) ACL may be relocated,
+.\" (b) all pointers remain valid.
+.\" </AG>
+.Sh RETURN VALUE
+.Rv -std acl_create_entry
+.Sh ERRORS
+If any of the following conditions occur, the
+.Fn acl_create_entry
+function returns
+.Li -1
+and sets
+.Va errno
+to the corresponding value:
+.Bl -tag -width Er
+.It Bq Er EINVAL
+The argument
+.Va acl_p
+is not a valid pointer to an ACL.
+.It Bq Er ENOMEM
+The ACL working storage requires more memory than is allowed by the hardware or system-imposed memory management constraints.
+.El
+.Sh STANDARDS
+IEEE Std 1003.1e draft 17 (\(lqPOSIX.1e\(rq, abandoned)
+.Sh SEE ALSO
+.Xr acl_init 3 ,
+.Xr acl_delete_entry 3 ,
+.Xr acl_free 3 ,
+.Xr acl_create_entry 3 ,
+.Xr acl 5
+.Sh AUTHOR
+Derived from the FreeBSD manual pages written by
+.An "Robert N M Watson" Aq rwatson@FreeBSD.org ,
+and adapted for Linux by
+.An "Andreas Gruenbacher" Aq a.gruenbacher@bestbits.at .
diff --git a/man/man3/acl_delete_def_file.3 b/man/man3/acl_delete_def_file.3
new file mode 100644
index 0000000..d8616ba
--- /dev/null
+++ b/man/man3/acl_delete_def_file.3
@@ -0,0 +1,86 @@
+.\" Access Control Lists manual pages
+.\"
+.\" (C) 2002 Andreas Gruenbacher, <a.gruenbacher@bestbits.at>
+.\"
+.\" This is free documentation; 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 of
+.\" the License, or (at your option) any later version.
+.\"
+.\" The GNU General Public License's references to "object code"
+.\" and "executables" are to be interpreted as the output of any
+.\" document formatting or typesetting system, including
+.\" intermediate and printed output.
+.\"
+.\" This manual 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 manual. If not, see
+.\" <http://www.gnu.org/licenses/>.
+.\"
+.Dd March 23, 2002
+.Dt ACL_DELETE_DEF_FILE 3
+.Os "Linux ACL"
+.Sh NAME
+.Nm acl_delete_def_file
+.Nd delete a default ACL by filename
+.Sh LIBRARY
+Linux Access Control Lists library (libacl, \-lacl).
+.Sh SYNOPSIS
+.In sys/types.h
+.In sys/acl.h
+.Ft int
+.Fn acl_delete_def_file "const char *path_p"
+.Sh DESCRIPTION
+The
+.Fn acl_delete_def_file
+function deletes a default ACL from the directory whose pathname is pointed to by the argument
+.Va path_p .
+.Pp
+The effective user ID of the process must match the owner of the file or
+directory or the process must have the CAP_FOWNER capability for the
+request to succeed.
+.Pp
+If the argument
+.Va path_p
+is not a directory, then the function fails. It is no error if the directory whose pathname is pointed to by the argument
+.Va path_p
+does not have a default ACL.
+.Sh RETURN VALUE
+.Rv -std acl_delete_def_file
+.Sh ERRORS
+If any of the following conditions occur, the
+.Fn acl_delete_def_file
+function returns the value
+.Li -1
+and and sets
+.Va errno
+to the corresponding value:
+.Bl -tag -width Er
+.It Bq Er EINVAL
+The file referred to by
+.Va path_p
+is not a directory.
+.It Bq Er ENOTSUP
+The file system on which the file identified by
+.Va path_p
+is located does not support ACLs, or ACLs are disabled.
+.It Bq Er EPERM
+The process does not have appropriate privilege to perform the operation to delete the default ACL.
+.It Bq Er EROFS
+This function requires modification of a file system which is currently read-only.
+.El
+.Sh STANDARDS
+IEEE Std 1003.1e draft 17 (\(lqPOSIX.1e\(rq, abandoned)
+.Sh SEE ALSO
+.Xr acl_get_file 3 ,
+.Xr acl_set_file 3 ,
+.Xr acl 5
+.Sh AUTHOR
+Derived from the FreeBSD manual pages written by
+.An "Robert N M Watson" Aq rwatson@FreeBSD.org ,
+and adapted for Linux by
+.An "Andreas Gruenbacher" Aq a.gruenbacher@bestbits.at .
diff --git a/man/man3/acl_delete_entry.3 b/man/man3/acl_delete_entry.3
new file mode 100644
index 0000000..b4a1186
--- /dev/null
+++ b/man/man3/acl_delete_entry.3
@@ -0,0 +1,86 @@
+.\" Access Control Lists manual pages
+.\"
+.\" (C) 2002 Andreas Gruenbacher, <a.gruenbacher@bestbits.at>
+.\"
+.\" This is free documentation; 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 of
+.\" the License, or (at your option) any later version.
+.\"
+.\" The GNU General Public License's references to "object code"
+.\" and "executables" are to be interpreted as the output of any
+.\" document formatting or typesetting system, including
+.\" intermediate and printed output.
+.\"
+.\" This manual 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 manual. If not, see
+.\" <http://www.gnu.org/licenses/>.
+.\"
+.Dd March 23, 2002
+.Dt ACL_DELETE_ENTRY 3
+.Os "Linux ACL"
+.Sh NAME
+.Nm acl_delete_entry
+.Nd delete an ACL entry
+.Sh LIBRARY
+Linux Access Control Lists library (libacl, \-lacl).
+.Sh SYNOPSIS
+.In sys/types.h
+.In sys/acl.h
+.Ft int
+.Fn acl_delete_entry "acl_t acl" "acl_entry_t entry_d"
+.Sh DESCRIPTION
+The
+.Fn acl_delete_entry
+function removes the ACL entry indicated by the
+.Va entry_d
+descriptor from the ACL pointed to by
+.Va acl .
+Any existing ACL entry descriptors that refer to entries in
+.Va acl
+other than that referred to by
+.Va entry_d
+continue to refer to the same entries. The argument
+.Va entry_d
+and any other ACL entry descriptors that refer to the same ACL entry are
+undefined after this function completes. Any existing ACL pointers that
+refer to the ACL referred to by
+.Va acl
+continue to refer to the ACL.
+.Sh RETURN VALUE
+.Rv -std acl_delete_entry
+.Sh ERRORS
+If any of the following conditions occur, the
+.Fn acl_delete_entry
+function returns
+.Li -1
+and sets
+.Va errno
+to the corresponding value:
+.Bl -tag -width Er
+.It Bq Er EINVAL
+The argument
+.Va acl_p
+is not a valid pointer to an ACL.
+.Pp
+The argument
+.Va entry_d
+is not a valid pointer to an ACL entry.
+.El
+.Sh STANDARDS
+IEEE Std 1003.1e draft 17 (\(lqPOSIX.1e\(rq, abandoned)
+.Sh SEE ALSO
+.Xr acl_copy_entry 3 ,
+.Xr acl_create_entry 3 ,
+.Xr acl_get_entry 3 ,
+.Xr acl 5
+.Sh AUTHOR
+Derived from the FreeBSD manual pages written by
+.An "Robert N M Watson" Aq rwatson@FreeBSD.org ,
+and adapted for Linux by
+.An "Andreas Gruenbacher" Aq a.gruenbacher@bestbits.at .
diff --git a/man/man3/acl_delete_perm.3 b/man/man3/acl_delete_perm.3
new file mode 100644
index 0000000..f87a95e
--- /dev/null
+++ b/man/man3/acl_delete_perm.3
@@ -0,0 +1,85 @@
+.\" Access Control Lists manual pages
+.\"
+.\" (C) 2002 Andreas Gruenbacher, <a.gruenbacher@bestbits.at>
+.\"
+.\" This is free documentation; 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 of
+.\" the License, or (at your option) any later version.
+.\"
+.\" The GNU General Public License's references to "object code"
+.\" and "executables" are to be interpreted as the output of any
+.\" document formatting or typesetting system, including
+.\" intermediate and printed output.
+.\"
+.\" This manual 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 manual. If not, see
+.\" <http://www.gnu.org/licenses/>.
+.\"
+.Dd March 23, 2002
+.Dt ACL_DELETE_PERM 3
+.Os "Linux ACL"
+.Sh NAME
+.Nm acl_delete_perm
+.Nd delete a permission from an ACL permission set
+.Sh LIBRARY
+Linux Access Control Lists library (libacl, \-lacl).
+.Sh SYNOPSIS
+.In sys/types.h
+.In sys/acl.h
+.Ft int
+.Fn acl_delete_perm "acl_permset_t permset_d" "acl_perm_t perm"
+.Sh DESCRIPTION
+The
+.Fn acl_delete_perm
+function deletes the permission contained in the argument
+.Va perm
+from the permission set referred to by the argument
+.Va permset_d .
+An attempt to delete a permission that is not contained in the permission
+set is not considered an error.
+.Pp
+Any existing descriptors that refer to
+.Va permset_d
+continue to refer to that permission set.
+.Sh RETURN VALUE
+.Rv -std acl_delete_perm
+.Sh ERRORS
+If any of the following conditions occur, the
+.Fn acl_delete_perm
+function returns
+.Li -1
+and sets
+.Va errno
+to the corresponding value:
+.Bl -tag -width Er
+.It Bq Er EINVAL
+The argument
+.Va permset_d
+is not a valid descriptor for a permission set within an ACL entry.
+.Pp
+The argument
+.Va perm
+does not contain a valid
+.Va acl_perm_t
+value.
+.El
+.Sh STANDARDS
+IEEE Std 1003.1e draft 17 (\(lqPOSIX.1e\(rq, abandoned)
+.Sh SEE ALSO
+.Xr acl_add_perm 3 ,
+.Xr acl_clear_perms 3 ,
+.Xr acl_get_perm 3 ,
+.Xr acl_get_permset 3 ,
+.Xr acl_set_permset 3 ,
+.Xr acl 5
+.Sh AUTHOR
+Derived from the FreeBSD manual pages written by
+.An "Robert N M Watson" Aq rwatson@FreeBSD.org ,
+and adapted for Linux by
+.An "Andreas Gruenbacher" Aq a.gruenbacher@bestbits.at .
diff --git a/man/man3/acl_dup.3 b/man/man3/acl_dup.3
new file mode 100644
index 0000000..6b61baa
--- /dev/null
+++ b/man/man3/acl_dup.3
@@ -0,0 +1,87 @@
+.\" Access Control Lists manual pages
+.\"
+.\" (C) 2002 Andreas Gruenbacher, <a.gruenbacher@bestbits.at>
+.\"
+.\" This is free documentation; 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 of
+.\" the License, or (at your option) any later version.
+.\"
+.\" The GNU General Public License's references to "object code"
+.\" and "executables" are to be interpreted as the output of any
+.\" document formatting or typesetting system, including
+.\" intermediate and printed output.
+.\"
+.\" This manual 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 manual. If not, see
+.\" <http://www.gnu.org/licenses/>.
+.\"
+.Dd March 23, 2002
+.Dt ACL_DUP 3
+.Os "Linux ACL"
+.Sh NAME
+.Nm acl_dup
+.Nd duplicate an ACL
+.Sh LIBRARY
+Linux Access Control Lists library (libacl, \-lacl).
+.Sh SYNOPSIS
+.In sys/types.h
+.In sys/acl.h
+.Ft acl_t
+.Fn acl_dup "acl_t acl"
+.Sh DESCRIPTION
+The
+.Fn acl_dup
+function returns a pointer to a copy of the ACL pointed to by
+.Va acl .
+.Pp
+This function may cause memory to be allocated. The caller should free any
+releasable memory, when the new ACL is no longer required, by calling
+.Xr acl_free 3
+with the
+.Va (void*)acl_t
+returned by
+.Fn acl_dup
+as an argument.
+.Sh RETURN VALUE
+On success, this function returns a pointer to the
+working storage. On error, a value of
+.Li (acl_t)NULL
+is returned, and
+.Va errno
+is set appropriately.
+.Sh ERRORS
+If any of the following conditions occur, the
+.Fn acl_dup
+function returns a value of
+.Li (acl_t)NULL
+and sets
+.Va errno
+to the corresponding value:
+.Bl -tag -width Er
+.It Bq Er EINVAL
+The argument
+.Va acl
+is not a valid pointer to an ACL.
+.It Bq Er ENOMEM
+The
+.Va acl_t
+to be returned requires more memory than is allowed by the hardware or
+system-imposed memory management constraints.
+.El
+.Sh STANDARDS
+IEEE Std 1003.1e draft 17 (\(lqPOSIX.1e\(rq, abandoned)
+.Sh SEE ALSO
+.Xr acl_free 3 ,
+.Xr acl_get_entry 3 ,
+.Xr acl 5
+.Sh AUTHOR
+Derived from the FreeBSD manual pages written by
+.An "Robert N M Watson" Aq rwatson@FreeBSD.org ,
+and adapted for Linux by
+.An "Andreas Gruenbacher" Aq a.gruenbacher@bestbits.at .
diff --git a/man/man3/acl_entries.3 b/man/man3/acl_entries.3
new file mode 100644
index 0000000..3bfabe4
--- /dev/null
+++ b/man/man3/acl_entries.3
@@ -0,0 +1,73 @@
+.\" Access Control Lists manual pages
+.\"
+.\" (C) 2002 Andreas Gruenbacher, <a.gruenbacher@bestbits.at>
+.\"
+.\" This is free documentation; 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 of
+.\" the License, or (at your option) any later version.
+.\"
+.\" The GNU General Public License's references to "object code"
+.\" and "executables" are to be interpreted as the output of any
+.\" document formatting or typesetting system, including
+.\" intermediate and printed output.
+.\"
+.\" This manual 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 manual. If not, see
+.\" <http://www.gnu.org/licenses/>.
+.\"
+.Dd March 23, 2002
+.Dt ACL_ENTRIES 3
+.Os "Linux ACL"
+.Sh NAME
+.Nm acl_entries
+.Nd return the number of entries in an ACL
+.Sh LIBRARY
+Linux Access Control Lists library (libacl, \-lacl).
+.Sh SYNOPSIS
+.In sys/types.h
+.In acl/libacl.h
+.Ft int
+.Fn acl_entries "acl_t acl"
+.Sh DESCRIPTION
+The
+.Fn acl_entries
+function returns the number of ACL entries that are contained in the ACL referred to by the argument
+.Va acl .
+.Sh RETURN VALUE
+The
+.Fn acl_entries
+function returns the number of entries in
+.Va acl
+if successful; otherwise the value
+.Li -1
+is returned and the global variable
+.Va errno
+is set to indicate the error.
+.Sh ERRORS
+If any of the following conditions occur, the
+.Fn acl_entries
+function returns
+.Li -1
+and sets
+.Va errno
+to the corresponding value:
+.Bl -tag -width Er
+.It Bq Er EINVAL
+The argument
+.Va acl
+is not a valid pointer to an ACL.
+.El
+.Sh STANDARDS
+This is a non-portable, Linux specific extension to the ACL manipulation
+functions defined in IEEE Std 1003.1e draft 17 (\(lqPOSIX.1e\(rq, abandoned).
+.Sh SEE ALSO
+.Xr acl 5
+.Sh AUTHOR
+Written by
+.An "Andreas Gruenbacher" Aq a.gruenbacher@bestbits.at .
diff --git a/man/man3/acl_equiv_mode.3 b/man/man3/acl_equiv_mode.3
new file mode 100644
index 0000000..1a693ec
--- /dev/null
+++ b/man/man3/acl_equiv_mode.3
@@ -0,0 +1,96 @@
+.\" Access Control Lists manual pages
+.\"
+.\" (C) 2002 Andreas Gruenbacher, <a.gruenbacher@bestbits.at>
+.\"
+.\" This is free documentation; 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 of
+.\" the License, or (at your option) any later version.
+.\"
+.\" The GNU General Public License's references to "object code"
+.\" and "executables" are to be interpreted as the output of any
+.\" document formatting or typesetting system, including
+.\" intermediate and printed output.
+.\"
+.\" This manual 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 manual. If not, see
+.\" <http://www.gnu.org/licenses/>.
+.\"
+.Dd March 23, 2002
+.Dt ACL_EQUIV_MODE 3
+.Os "Linux ACL"
+.Sh NAME
+.Nm acl_equiv_mode
+.Nd check for an equivalent ACL
+.Sh LIBRARY
+Linux Access Control Lists library (libacl, \-lacl).
+.Sh SYNOPSIS
+.In sys/types.h
+.In acl/libacl.h
+.Ft int
+.Fn acl_equiv_mode "acl_t acl" "mode_t *mode_p"
+.Sh DESCRIPTION
+The
+.Fn acl_equiv_mode
+function checks if the ACL pointed to by the argument
+.Va acl
+contains only the required ACL entries of tag types
+ACL_USER_OBJ, ACL_GROUP_OBJ, and ACL_OTHER, and contains no
+permissions other that ACL_READ, ACL_WRITE or ACL_EXECUTE.
+If the ACL has this form, it can can be fully represented with
+the traditional file permission bits, and is considered
+equivalent with the traditional file permission bits.
+.Pp
+If
+.Va acl
+is an equivalent ACL and the pointer
+.Va mode_p
+is not
+.Li NULL ,
+the value pointed to by
+.Va mode_p
+is set to the value that defines the same owner, group and other
+permissions as contained in
+the ACL.
+.Sh RETURN VALUE
+On success, this function returns the value
+.Li 0
+if
+.Va acl
+is an equivalent ACL, and the value
+.Li 1
+if
+.Va acl
+is not an equivalent ACL. On error, the value
+.Li -1
+is returned, and
+.Va errno
+is set appropriately.
+.Sh ERRORS
+If any of the following conditions occur, the
+.Fn acl_equiv_mode
+function returns the value
+.Li -1
+and sets
+.Va errno
+to the corresponding value:
+.Bl -tag -width Er
+.It Bq Er EINVAL
+The argument
+.Va acl
+is not a valid pointer to an ACL.
+.El
+.Sh STANDARDS
+This is a non-portable, Linux specific extension to the ACL manipulation
+functions defined in IEEE Std 1003.1e draft 17 (\(lqPOSIX.1e\(rq, abandoned).
+.Sh SEE ALSO
+.Xr acl_from_mode 3 ,
+.Xr acl 5
+.Sh AUTHOR
+Written by
+.An "Andreas Gruenbacher" Aq a.gruenbacher@bestbits.at .
diff --git a/man/man3/acl_error.3 b/man/man3/acl_error.3
new file mode 100644
index 0000000..f491820
--- /dev/null
+++ b/man/man3/acl_error.3
@@ -0,0 +1,71 @@
+.\" Access Control Lists manual pages
+.\"
+.\" (C) 2002 Andreas Gruenbacher, <a.gruenbacher@bestbits.at>
+.\"
+.\" This is free documentation; 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 of
+.\" the License, or (at your option) any later version.
+.\"
+.\" The GNU General Public License's references to "object code"
+.\" and "executables" are to be interpreted as the output of any
+.\" document formatting or typesetting system, including
+.\" intermediate and printed output.
+.\"
+.\" This manual 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 manual. If not, see
+.\" <http://www.gnu.org/licenses/>.
+.\"
+.Dd March 23, 2002
+.Dt ACL_CHECK 3
+.Os "Linux ACL"
+.Sh NAME
+.Nm acl_error
+.Nd convert an ACL error code to a text message
+.Sh LIBRARY
+Linux Access Control Lists library (libacl, \-lacl).
+.Sh SYNOPSIS
+.In sys/types.h
+.In acl/libacl.h
+.Ft const char *
+.Fn acl_error "int code"
+.Sh DESCRIPTION
+The
+.Fn acl_error
+function converts an ACL error code such as returned by the
+.Fn acl_check
+function to a text message describing the error condition. In the
+\(lqPOSIX\(rq locale,
+.Fn acl_check
+returns the following descriptions for the error codes.
+.Bl -tag -width ACL_DUPLICATE_ERROR.
+.It ACL_MULTI_ERROR
+\(lqMultiple entries\(rq
+.It ACL_DUPLICATE_ERROR
+\(lqDuplicate entries\(rq
+.It ACL_MISS_ERROR
+\(lqMissing or wrong entry\(rq
+.It ACL_ENTRY_ERROR
+\(lqInvalid entry type\(rq
+.El
+.Sh RETURN VALUE
+The
+.Fn acl_error
+function returns a text message if the error code is recognized, and a value of
+.Li (const char *)NULL
+otherwise.
+.Sh STANDARDS
+This is a non-portable, Linux specific extension to the ACL manipulation
+functions defined in IEEE Std 1003.1e draft 17 (\(lqPOSIX.1e\(rq, abandoned).
+.Sh SEE ALSO
+.Xr acl_check 3 ,
+.Xr acl_valid 3 ,
+.Xr acl 5
+.Sh AUTHOR
+Written by
+.An "Andreas Gruenbacher" Aq a.gruenbacher@bestbits.at .
diff --git a/man/man3/acl_extended_fd.3 b/man/man3/acl_extended_fd.3
new file mode 100644
index 0000000..b4ca1b4
--- /dev/null
+++ b/man/man3/acl_extended_fd.3
@@ -0,0 +1,105 @@
+.\" Access Control Lists manual pages
+.\"
+.\" (C) 2002 Andreas Gruenbacher, <a.gruenbacher@bestbits.at>
+.\"
+.\" This is free documentation; 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 of
+.\" the License, or (at your option) any later version.
+.\"
+.\" The GNU General Public License's references to "object code"
+.\" and "executables" are to be interpreted as the output of any
+.\" document formatting or typesetting system, including
+.\" intermediate and printed output.
+.\"
+.\" This manual 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 manual. If not, see
+.\" <http://www.gnu.org/licenses/>.
+.\"
+.Dd March 23, 2002
+.Dt ACL_EXTENDED_FD 3
+.Os "Linux ACL"
+.Sh NAME
+.Nm acl_extended_fd
+.Nd test for information in the ACL by file descriptor
+.Sh LIBRARY
+Linux Access Control Lists library (libacl, \-lacl).
+.Sh SYNOPSIS
+.In sys/types.h
+.In acl/libacl.h
+.Ft int
+.Fn acl_extended_fd "int fd"
+.Sh DESCRIPTION
+The
+.Fn acl_extended_fd
+function returns
+.Li 1
+if the file identified by the argument
+.Va fd
+is associated with an extended access ACL. The function returns
+.Li 0
+if the file does not have an extended access ACL.
+.Pp
+An extended ACL is an ACL that contains entries other than the three
+required entries of tag types ACL_USER_OBJ, ACL_GROUP_OBJ and ACL_OTHER.
+If the result of the
+.Fn acl_extended_fd
+function for a file object is
+.Li 0 ,
+then the ACL defines no discretionary access rights other than those
+already defined by the traditional file permission bits.
+.Pp
+Access to the file object may be further restricted by other
+mechanisms, such as Mandatory Access Control schemes. The
+.Xr access 2
+system call can be used to check whether a given type of access to a file
+object would be granted.
+.Sh RETURN VALUE
+If successful, the
+.Fn acl_extended_fd
+function returns
+.Li 1
+if the file object identified by
+.Va fd
+has an extended access ACL, and
+.Li 0
+if the file object identified by
+.Va fd
+does not have an extended access ACL. Otherwise, the value
+.Li -1
+is returned and the global variable
+.Va errno
+is set to indicate the error.
+.Sh ERRORS
+If any of the following conditions occur, the
+.Fn acl_extended_fd
+function returns
+.Li -1
+and sets
+.Va errno
+to the corresponding value:
+.Bl -tag -width Er
+.It Bq Er EBADF
+The
+.Va fd
+argument is not a valid file descriptor.
+.It Bq Er ENOTSUP
+The file system on which the file identified by
+.Va fd
+is located does not support ACLs, or ACLs are disabled.
+.El
+.Sh STANDARDS
+This is a non-portable, Linux specific extension to the ACL manipulation
+functions defined in IEEE Std 1003.1e draft 17 (\(lqPOSIX.1e\(rq, abandoned).
+.Sh SEE ALSO
+.Xr access 2 ,
+.Xr acl_get_fd 3 ,
+.Xr acl 5
+.Sh AUTHOR
+Written by
+.An "Andreas Gruenbacher" Aq a.gruenbacher@bestbits.at .
diff --git a/man/man3/acl_extended_file.3 b/man/man3/acl_extended_file.3
new file mode 100644
index 0000000..0ca7e0f
--- /dev/null
+++ b/man/man3/acl_extended_file.3
@@ -0,0 +1,115 @@
+.\" Access Control Lists manual pages
+.\"
+.\" (C) 2002 Andreas Gruenbacher, <a.gruenbacher@bestbits.at>
+.\"
+.\" This is free documentation; 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 of
+.\" the License, or (at your option) any later version.
+.\"
+.\" The GNU General Public License's references to "object code"
+.\" and "executables" are to be interpreted as the output of any
+.\" document formatting or typesetting system, including
+.\" intermediate and printed output.
+.\"
+.\" This manual 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 manual. If not, see
+.\" <http://www.gnu.org/licenses/>.
+.\"
+.Dd March 23, 2002
+.Dt ACL_EXTENDED_FILE 3
+.Os "Linux ACL"
+.Sh NAME
+.Nm acl_extended_file
+.Nd test for information in ACLs by file name
+.Sh LIBRARY
+Linux Access Control Lists library (libacl, \-lacl).
+.Sh SYNOPSIS
+.In sys/types.h
+.In acl/libacl.h
+.Ft int
+.Fn acl_extended_file "const char *path_p"
+.Sh DESCRIPTION
+The
+.Fn acl_extended_file
+function returns
+.Li 1
+if the file or directory referred to by the argument
+.Va path_p
+is associated with an extended access ACL, or if the directory referred to by
+.Va path_p
+is associated with a default ACL. The function returns
+.Li 0
+if the file has neither an extended access ACL nor a default ACL.
+.Pp
+An extended ACL is an ACL that contains entries other than the three
+required entries of tag types ACL_USER_OBJ, ACL_GROUP_OBJ and ACL_OTHER.
+If the result of the
+.Fn acl_extended_file
+function for a file object is
+.Li 0 ,
+then ACLs define no discretionary access rights other than those
+already defined by the traditional file permission bits.
+.Pp
+Access to the file object may be further restricted by other
+mechanisms, such as Mandatory Access Control schemes. The
+.Xr access 2
+system call can be used to check whether a given type of access to a file
+object would be granted.
+.Sh RETURN VALUE
+If successful, the
+.Fn acl_extended_file
+function returns
+.Li 1
+if the file object referred to by
+.Va path_p
+has an extended access ACL or a default ACL, and
+.Li 0
+if the file object referred to by
+.Va path_p
+has neither an extended access ACL nor a default ACL. Otherwise, the value
+.Li -1
+is returned and the global variable
+.Va errno
+is set to indicate the error.
+.Sh ERRORS
+If any of the following conditions occur, the
+.Fn acl_extended_file
+function returns
+.Li -1
+and sets
+.Va errno
+to the corresponding value:
+.Bl -tag -width Er
+.It Bq Er EACCES
+Search permission is denied for a component of the path prefix.
+.It Bq Er ENAMETOOLONG
+The length of the argument
+.Va path_p
+is too long.
+.It Bq Er ENOENT
+The named object does not exist or the argument
+.Va path_p
+points to an empty string.
+.It Bq Er ENOTDIR
+A component of the path prefix is not a directory.
+.It Bq Er ENOTSUP
+The file system on which the file identified by
+.Va path_p
+is located does not support ACLs, or ACLs are disabled.
+.El
+.Sh STANDARDS
+This is a non-portable, Linux specific extension to the ACL manipulation
+functions defined in IEEE Std 1003.1e draft 17 (\(lqPOSIX.1e\(rq, abandoned).
+.Sh SEE ALSO
+.Xr access 2 ,
+.Xr acl_get_file 3 ,
+.Xr acl 5
+.Sh AUTHOR
+Written by
+.An "Andreas Gruenbacher" Aq a.gruenbacher@bestbits.at .
diff --git a/man/man3/acl_free.3 b/man/man3/acl_free.3
new file mode 100644
index 0000000..11b0bd3
--- /dev/null
+++ b/man/man3/acl_free.3
@@ -0,0 +1,82 @@
+.\" Access Control Lists manual pages
+.\"
+.\" (C) 2002 Andreas Gruenbacher, <a.gruenbacher@bestbits.at>
+.\"
+.\" This is free documentation; 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 of
+.\" the License, or (at your option) any later version.
+.\"
+.\" The GNU General Public License's references to "object code"
+.\" and "executables" are to be interpreted as the output of any
+.\" document formatting or typesetting system, including
+.\" intermediate and printed output.
+.\"
+.\" This manual 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 manual. If not, see
+.\" <http://www.gnu.org/licenses/>.
+.\"
+.Dd March 23, 2002
+.Dt ACL_FREE 3
+.Os "Linux ACL"
+.Sh NAME
+.Nm acl_free
+.Nd release memory allocated to an ACL data object
+.Sh LIBRARY
+Linux Access Control Lists library (libacl, \-lacl).
+.Sh SYNOPSIS
+.In sys/types.h
+.In sys/acl.h
+.Ft int
+.Fn acl_free "void *obj_p"
+.Sh DESCRIPTION
+The
+.Fn acl_free
+function frees any releasable memory currently allocated by to the ACL data object identified by
+.Va obj_p .
+The argument
+.Va obj_p
+may identify an ACL, an ACL entry qualifier, or a pointer to a string
+allocated by the
+.Fn acl_to_text
+function.
+.\" .Sh IMPLEMENTATION NOTES
+.\" True64 prints a compile time warning for acl_free(text) if text was
+.\" produced by acl_to_text(). Bad!
+.Sh RETURN VALUE
+.Rv -std acl_free
+.Sh ERRORS
+If any of the following conditions occur, the
+.Fn acl_free
+function returns the value
+.Li -1
+and and sets
+.Va errno
+to the corresponding value:
+.Bl -tag -width Er
+.It Bq Er EINVAL
+The value of the argument
+.Va obj_p
+is invalid.
+.El
+.Sh STANDARDS
+IEEE Std 1003.1e draft 17 (\(lqPOSIX.1e\(rq, abandoned)
+.Sh SEE ALSO
+.Xr acl_copy_int 3 ,
+.Xr acl_create_entry 3 ,
+.Xr acl_dup 3 ,
+.Xr acl_from_text 3 ,
+.Xr acl_get_fd ,
+.Xr acl_get_file 3 ,
+.Xr acl_init 3 ,
+.Xr acl 5
+.Sh AUTHOR
+Derived from the FreeBSD manual pages written by
+.An "Robert N M Watson" Aq rwatson@FreeBSD.org ,
+and adapted for Linux by
+.An "Andreas Gruenbacher" Aq a.gruenbacher@bestbits.at .
diff --git a/man/man3/acl_from_mode.3 b/man/man3/acl_from_mode.3
new file mode 100644
index 0000000..2681bca
--- /dev/null
+++ b/man/man3/acl_from_mode.3
@@ -0,0 +1,74 @@
+.\" Access Control Lists manual pages
+.\"
+.\" (C) 2002 Andreas Gruenbacher, <a.gruenbacher@bestbits.at>
+.\"
+.\" This is free documentation; 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 of
+.\" the License, or (at your option) any later version.
+.\"
+.\" The GNU General Public License's references to "object code"
+.\" and "executables" are to be interpreted as the output of any
+.\" document formatting or typesetting system, including
+.\" intermediate and printed output.
+.\"
+.\" This manual 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 manual. If not, see
+.\" <http://www.gnu.org/licenses/>.
+.\"
+.Dd March 23, 2002
+.Dt ACL_FROM_MODE 3
+.Os "Linux ACL"
+.Sh NAME
+.Nm acl_from_mode
+.Nd create an ACL from file permission bits
+.Sh LIBRARY
+Linux Access Control Lists library (libacl, \-lacl).
+.Sh SYNOPSIS
+.In sys/types.h
+.In acl/libacl.h
+.Ft acl_t
+.Fn acl_from_mode "mode_t mode"
+.Sh DESCRIPTION
+The
+.Fn acl_from_mode
+function creates a minimal ACL that contains the three entries with tag
+types ACL_USER_OBJ, ACL_GROUP_OBJ, and ACL_OTHER, with permissions
+corresponding to the owner, group, and other permission bits of its
+argument
+.Va mode .
+.Sh RETURN VALUE
+On success, this function returns a pointer to the
+working storage. On error, a value of
+.Li (acl_t)NULL
+is returned, and
+.Va errno
+is set appropriately.
+.Sh ERRORS
+If any of the following conditions occur, the
+.Fn acl_from_mode
+function returns a value of
+.Li (acl_t)NULL
+and sets
+.Va errno
+to the corresponding value:
+.Bl -tag -width Er
+.It Bq Er ENOMEM
+The ACL working storage requires more memory than is allowed by the
+hardware or system-imposed memory management constraints.
+.El
+.Sh STANDARDS
+This is a non-portable, Linux specific extension to the ACL manipulation
+functions defined in IEEE Std 1003.1e draft 17 (\(lqPOSIX.1e\(rq, abandoned).
+.Sh SEE ALSO
+.Xr acl_equiv_mode 3 ,
+.Xr acl_get_file 3 ,
+.Xr acl 5
+.Sh AUTHOR
+Written by
+.An "Andreas Gruenbacher" Aq a.gruenbacher@bestbits.at .
diff --git a/man/man3/acl_from_text.3 b/man/man3/acl_from_text.3
new file mode 100644
index 0000000..89b5a16
--- /dev/null
+++ b/man/man3/acl_from_text.3
@@ -0,0 +1,93 @@
+.\" Access Control Lists manual pages
+.\"
+.\" (C) 2002 Andreas Gruenbacher, <a.gruenbacher@bestbits.at>
+.\"
+.\" This is free documentation; 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 of
+.\" the License, or (at your option) any later version.
+.\"
+.\" The GNU General Public License's references to "object code"
+.\" and "executables" are to be interpreted as the output of any
+.\" document formatting or typesetting system, including
+.\" intermediate and printed output.
+.\"
+.\" This manual 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 manual. If not, see
+.\" <http://www.gnu.org/licenses/>.
+.\"
+.Dd March 23, 2002
+.Dt ACL_FROM_TEXT 3
+.Os "Linux ACL"
+.Sh NAME
+.Nm acl_from_text
+.Nd create an ACL from text
+.Sh LIBRARY
+Linux Access Control Lists library (libacl, \-lacl).
+.Sh SYNOPSIS
+.In sys/types.h
+.In sys/acl.h
+.Ft acl_t
+.Fn acl_from_text "const char *buf_p"
+.Sh DESCRIPTION
+The
+.Fn acl_from_text
+function converts the text form of the ACL referred to by
+.Va buf_p
+into the internal form of an ACL and returns a pointer to the working storage
+that contains the ACL. The
+.Fn acl_from_text
+function accepts as input the long text form and short text form of an ACL as described in
+.Xr acl 5 .
+.Pp
+This function may cause memory to be allocated. The caller should free any
+releasable memory, when the new ACL is no longer required, by calling
+.Xr acl_free 3
+with the
+.Va (void*)acl_t
+returned by
+.Fn acl_from_text
+as an argument.
+.Sh RETURN VALUE
+On success, this function returns a pointer to the
+working storage. On error, a value of
+.Li (acl_t)NULL
+is returned, and
+.Va errno
+is set appropriately.
+.Sh ERRORS
+If any of the following conditions occur, the
+.Fn acl_from_text
+function returns a value of
+.Li (acl_t)NULL
+and sets
+.Va errno
+to the corresponding value:
+.Bl -tag -width Er
+.It Bq Er EINVAL
+The argument
+.Va buf_p
+cannot be translated into an ACL.
+.It Bq Er ENOMEM
+The
+.Va acl_t
+to be returned requires more memory than is allowed by the hardware or
+system-imposed memory management constraints.
+.El
+.Sh STANDARDS
+IEEE Std 1003.1e draft 17 (\(lqPOSIX.1e\(rq, abandoned)
+.Sh SEE ALSO
+.Xr acl_free 3 ,
+.Xr acl_get_entry 3 ,
+.Xw acl_to_text 3 ,
+.Xr acl 5
+.Sh AUTHOR
+Derived from the FreeBSD manual pages written by
+.An "Robert N M Watson" Aq rwatson@FreeBSD.org ,
+and adapted for Linux by
+.An "Andreas Gruenbacher" Aq a.gruenbacher@bestbits.at .
diff --git a/man/man3/acl_get_entry.3 b/man/man3/acl_get_entry.3
new file mode 100644
index 0000000..f5d9894
--- /dev/null
+++ b/man/man3/acl_get_entry.3
@@ -0,0 +1,142 @@
+.\" Access Control Lists manual pages
+.\"
+.\" (C) 2002 Andreas Gruenbacher, <a.gruenbacher@bestbits.at>
+.\"
+.\" This is free documentation; 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 of
+.\" the License, or (at your option) any later version.
+.\"
+.\" The GNU General Public License's references to "object code"
+.\" and "executables" are to be interpreted as the output of any
+.\" document formatting or typesetting system, including
+.\" intermediate and printed output.
+.\"
+.\" This manual 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 manual. If not, see
+.\" <http://www.gnu.org/licenses/>.
+.\"
+.Dd March 23, 2002
+.Dt ACL_GET_ENTRY 3
+.Os "Linux ACL"
+.Sh NAME
+.Nm acl_get_entry
+.Nd get an ACL entry
+.Sh LIBRARY
+Linux Access Control Lists library (libacl, \-lacl).
+.Sh SYNOPSIS
+.In sys/types.h
+.In sys/acl.h
+.Ft int
+.Fn acl_get_entry "acl_t acl" "int entry_id" "acl_entry_t *entry_p"
+.Sh DESCRIPTION
+The
+.Fn acl_get_entry
+function obtains a descriptor for an ACL entry as specified by
+.Va entry_id
+within the ACL indicated by the argument
+.Va acl .
+If the value of
+.Va entry_id
+is ACL_FIRST_ENTRY, then the function returns in
+.Va entry_p
+a descriptor for the first ACL entry within
+.Va acl .
+If the value of
+.Va entry_id
+is ACL_NEXT_ENTRY, then the function returns in
+.Va entry_p
+a descriptor for the next ACL entry within
+.Va acl .
+.Pp
+If a call is made to
+.Fn acl_get_entry
+with
+.Va entry_id
+set to ACL_NEXT_ENTRY when there has not been either an initial
+successful call to
+.Fn acl_get_entry ,
+or a previous successful call to
+.Fn acl_get_entry
+following a call to
+.Fn acl_calc_mask ,
+.Fn acl_copy_int ,
+.Fn acl_create_entry ,
+.Fn acl_delete_entry ,
+.Fn acl_dup ,
+.Fn acl_from_text ,
+.Fn acl_get_fd ,
+.Fn acl_get_file ,
+.Fn acl_set_fd ,
+.Fn acl_set_file ,
+or
+.Fn acl_valid ,
+then the effect is unspecified.
+.Pp
+Calls to
+.Fn acl_get_entry
+do not modify any ACL entries. Subsequent operations using the returned
+ACL entry descriptor operate on the ACL entry within the ACL in working
+storage. The order of all existing entries in the ACL remains unchanged.
+Any existing ACL entry descriptors that refer to entries within the ACL
+continue to refer to those entries. Any existing ACL pointers that refer
+to the ACL referred to by
+.Va acl
+continue to refer to the ACL.
+.Sh RETURN VALUE
+If the function successfully obtains an ACL entry, the function returns a
+value of
+.Li 1 .
+If the ACL has no ACL entries, the function returns the value
+.Li 0 .
+If the value of
+.Va entry_id
+is ACL_NEXT_ENTRY and the last ACL entry in the ACL has already been
+returned by a previous call to
+.Fn acl_get_entry ,
+the function returns the value
+.Li 0
+until a successful call with an
+.Va entry_id
+of ACL_FIRST_ENTRY is made. Otherwise, the value
+.Li -1
+is returned and
+.Va errno
+is set to indicate the error.
+.Sh ERRORS
+If any of the following conditions occur, the
+.Fn acl_get_entry
+function returns
+.Li -1
+and sets
+.Va errno
+to the corresponding value:
+.Bl -tag -width Er
+.It Bq Er EINVAL
+The argument
+.Va acl_p
+is not a valid pointer to an ACL.
+.Pp
+The argument
+.Va entry_id
+is neither ACL_NEXT_ENTRY nor ACL_FIRST_ENTRY.
+.El
+.Sh STANDARDS
+IEEE Std 1003.1e draft 17 (\(lqPOSIX.1e\(rq, abandoned)
+.Sh SEE ALSO
+.Xr acl_calc_mask 3 ,
+.Xr acl_create_entry 3 ,
+.Xr acl_copy_entry 3 ,
+.Xr acl_delete_entry 3 ,
+.Xr acl_get_file 3 ,
+.Xr acl 5
+.Sh AUTHOR
+Derived from the FreeBSD manual pages written by
+.An "Robert N M Watson" Aq rwatson@FreeBSD.org ,
+and adapted for Linux by
+.An "Andreas Gruenbacher" Aq a.gruenbacher@bestbits.at .
diff --git a/man/man3/acl_get_fd.3 b/man/man3/acl_get_fd.3
new file mode 100644
index 0000000..a9513f4
--- /dev/null
+++ b/man/man3/acl_get_fd.3
@@ -0,0 +1,96 @@
+.\" Access Control Lists manual pages
+.\"
+.\" (C) 2002 Andreas Gruenbacher, <a.gruenbacher@bestbits.at>
+.\"
+.\" This is free documentation; 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 of
+.\" the License, or (at your option) any later version.
+.\"
+.\" The GNU General Public License's references to "object code"
+.\" and "executables" are to be interpreted as the output of any
+.\" document formatting or typesetting system, including
+.\" intermediate and printed output.
+.\"
+.\" This manual 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 manual. If not, see
+.\" <http://www.gnu.org/licenses/>.
+.\"
+.Dd March 23, 2002
+.Dt ACL_GET_FD 3
+.Os "Linux ACL"
+.Sh NAME
+.Nm acl_get_fd
+.Nd get an ACL by file descriptor
+.Sh LIBRARY
+Linux Access Control Lists library (libacl, \-lacl).
+.Sh SYNOPSIS
+.In sys/types.h
+.In sys/acl.h
+.Ft acl_t
+.Fn acl_get_fd "int fd"
+.Sh DESCRIPTION
+The
+.Fn acl_get_fd
+function retrieves the access ACL associated with the file referred to by
+.Va fd .
+The ACL is placed into working storage and
+.Fn acl_get_fd
+returns a pointer to that storage.
+.Pp
+In order to read an ACL from an object, a process must have read access to
+the object's attributes.
+.Pp
+This function may cause memory to be allocated. The caller should free any
+releasable memory, when the new ACL is no longer required, by calling
+.Xr acl_free 3
+with the
+.Va (void*)acl_t
+returned by
+.Fn acl_get_fd
+as an argument.
+.Sh RETURN VALUE
+On success, this function shall return a pointer to the
+working storage. On error, a value of
+.Li (acl_t)NULL
+shall be returned, and
+.Va errno
+is set appropriately.
+.Sh ERRORS
+If any of the following conditions occur, the
+.Fn acl_get_fd
+function returns a value of
+.Li (acl_t)NULL
+and sets
+.Va errno
+to the corresponding value:
+.Bl -tag -width Er
+.It Bq Er EBADF
+The
+.Va fd
+argument is not a valid file descriptor.
+.It Bq Er ENOMEM
+The ACL working storage requires more memory than is allowed by the hardware or system-imposed memory management constraints.
+.It Bq Er ENOTSUP
+The file system on which the file identified by
+.Va fd
+is located does not support ACLs, or ACLs are disabled.
+.El
+.Sh STANDARDS
+IEEE Std 1003.1e draft 17 (\(lqPOSIX.1e\(rq, abandoned)
+.Sh SEE ALSO
+.Xr acl_free 3 ,
+.Xr acl_get_entry 3 ,
+.Xr acl_get_file 3 ,
+.Xr acl_set_fd 3 ,
+.Xr acl 5
+.Sh AUTHOR
+Derived from the FreeBSD manual pages written by
+.An "Robert N M Watson" Aq rwatson@FreeBSD.org ,
+and adapted for Linux by
+.An "Andreas Gruenbacher" Aq a.gruenbacher@bestbits.at .
diff --git a/man/man3/acl_get_file.3 b/man/man3/acl_get_file.3
new file mode 100644
index 0000000..192a9ca
--- /dev/null
+++ b/man/man3/acl_get_file.3
@@ -0,0 +1,136 @@
+.\" Access Control Lists manual pages
+.\"
+.\" (C) 2002 Andreas Gruenbacher, <a.gruenbacher@bestbits.at>
+.\"
+.\" This is free documentation; 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 of
+.\" the License, or (at your option) any later version.
+.\"
+.\" The GNU General Public License's references to "object code"
+.\" and "executables" are to be interpreted as the output of any
+.\" document formatting or typesetting system, including
+.\" intermediate and printed output.
+.\"
+.\" This manual 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 manual. If not, see
+.\" <http://www.gnu.org/licenses/>.
+.\"
+.Dd March 23, 2002
+.Dt ACL_GET_FILE 3
+.Os "Linux ACL"
+.Sh NAME
+.Nm acl_get_file
+.Nd get an ACL by filename
+.Sh LIBRARY
+Linux Access Control Lists library (libacl, \-lacl).
+.Sh SYNOPSIS
+.In sys/types.h
+.In sys/acl.h
+.Ft acl_t
+.Fn acl_get_file "const char *path_p" "acl_type_t type"
+.Sh DESCRIPTION
+The
+.Fn acl_get_file
+function retrieves the access ACL associated with a file or directory, or the default ACL associated with a directory. The pathname for the file or directory is pointed to by the argument
+.Va path_p .
+The ACL is placed into working storage and
+.Fn acl_get_file
+returns a pointer to that storage.
+.Pp
+In order to read an ACL from an object, a process must have read access to
+the object's attributes.
+.Pp
+The value of the argument
+.Va type
+is used to indicate whether the access ACL or the default ACL associated with
+.Va path_p
+is returned. If
+.Va type
+is ACL_TYPE_ACCESS, the access ACL of
+.Va path_p
+is returned. If
+.Va type
+is ACL_TYPE_DEFAULT, the default ACL of
+.Va path_p
+is returned. If
+.Va type
+is ACL_TYPE_DEFAULT and no default ACL is associated with the directory
+.Va path_p ,
+then an ACL containing zero ACL entries is returned. If
+.Va type
+specifies a type of ACL that cannot be associated with
+.Va path_p ,
+then the function fails.
+.Pp
+This function may cause memory to be allocated. The caller should free any
+releasable memory, when the new ACL is no longer required, by calling
+.Xr acl_free 3
+with the
+.Va (void*)acl_t
+returned by
+.Fn acl_get_file
+as an argument.
+.Sh RETURN VALUE
+On success, this function returns a pointer to the
+working storage. On error, a value of
+.Li (acl_t)NULL
+is returned, and
+.Va errno
+is set appropriately.
+.Sh ERRORS
+If any of the following conditions occur, the
+.Fn acl_get_file
+function returns a value of
+.Li (acl_t)NULL
+and sets
+.Va errno
+to the corresponding value:
+.Bl -tag -width Er
+.It Bq Er EACCES
+Search permission is denied for a component of the path prefix or the
+object exists and the process does not have appropriate access rights.
+.Pp
+Argument
+.Va type
+specifies a type of ACL that cannot be associated with
+.Va path_p .
+.It Bq Er EINVAL
+The argument
+.Va type
+is not ACL_TYPE_ACCESS or ACL_TYPE_DEFAULT.
+.It Bq Er ENAMETOOLONG
+The length of the argument
+.Va path_p
+is too long.
+.It Bq Er ENOENT
+The named object does not exist or the argument
+.Va path_p
+points to an empty string.
+.It Bq Er ENOMEM
+The ACL working storage requires more memory than is allowed by the hardware or system-imposed memory management constraints.
+.It Bq Er ENOTDIR
+A component of the path prefix is not a directory.
+.It Bq Er ENOTSUP
+The file system on which the file identified by
+.Va path_p
+is located does not support ACLs, or ACLs are disabled.
+.El
+.Sh STANDARDS
+IEEE Std 1003.1e draft 17 (\(lqPOSIX.1e\(rq, abandoned)
+.Sh SEE ALSO
+.Xr acl_free 3 ,
+.Xr acl_get_entry 3 ,
+.Xr acl_get_fd 3 ,
+.Xr acl_set_file 3 ,
+.Xr acl 5
+.Sh AUTHOR
+Derived from the FreeBSD manual pages written by
+.An "Robert N M Watson" Aq rwatson@FreeBSD.org ,
+and adapted for Linux by
+.An "Andreas Gruenbacher" Aq a.gruenbacher@bestbits.at .
diff --git a/man/man3/acl_get_perm.3 b/man/man3/acl_get_perm.3
new file mode 100644
index 0000000..d7f6c37
--- /dev/null
+++ b/man/man3/acl_get_perm.3
@@ -0,0 +1,97 @@
+.\" Access Control Lists manual pages
+.\"
+.\" (C) 2002 Andreas Gruenbacher, <a.gruenbacher@bestbits.at>
+.\"
+.\" This is free documentation; 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 of
+.\" the License, or (at your option) any later version.
+.\"
+.\" The GNU General Public License's references to "object code"
+.\" and "executables" are to be interpreted as the output of any
+.\" document formatting or typesetting system, including
+.\" intermediate and printed output.
+.\"
+.\" This manual 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 manual. If not, see
+.\" <http://www.gnu.org/licenses/>.
+.\"
+.Dd March 23, 2002
+.Dt ACL_GET_PERM 3
+.Os "Linux ACL"
+.Sh NAME
+.Nm acl_get_perm
+.Nd test for a permission in an ACL permission set
+.Sh LIBRARY
+Linux Access Control Lists library (libacl, \-lacl).
+.Sh SYNOPSIS
+.In sys/types.h
+.In acl/libacl.h
+.Ft int
+.Fn acl_get_perm "acl_permset_t permset_d" "acl_perm_t perm"
+.Sh DESCRIPTION
+The
+.Fn acl_get_perm
+function tests if the permission specified by the argument
+.Va perm
+is contained in the ACL permission set pointed to by the argument
+.Va permset_d .
+.Pp
+Any existing descriptors that refer to
+.Va permset_d
+continue to refer to that permission set.
+.Sh RETURN VALUE
+If successful, the
+.Fn acl_get_perm
+function returns
+.Li 1
+if the permission specified by
+.Va perm
+is contained in the ACL permission set
+.Va permset_d ,
+and
+.Li 0
+if the permission is not contained in the permission set. Otherwise,
+the value
+.Li -1
+is returned and the global variable
+.Va errno
+is set to indicate the error.
+.Sh ERRORS
+If any of the following conditions occur, the
+.Fn acl_get_perm
+function returns
+.Li -1
+and sets
+.Va errno
+to the corresponding value:
+.Bl -tag -width Er
+.It Bq Er EINVAL
+The argument
+.Va permset_d
+is not a valid descriptor for a permission set within an ACL entry.
+.Pp
+The argument
+.Va perm
+is not a valid
+.Va acl_perm_t
+value.
+.El
+.Sh STANDARDS
+This is a non-portable, Linux specific extension to the ACL manipulation
+functions defined in IEEE Std 1003.1e draft 17 (\(lqPOSIX.1e\(rq, abandoned).
+.Sh SEE ALSO
+.Xr acl_add_perm 3 ,
+.Xr acl_clear_perms 3 ,
+.Xr acl_delete_perm 3 ,
+.Xr acl_get_permset 3 ,
+.Xr acl_set_permset 3 ,
+.Xr acl 5
+.Sh AUTHOR
+Written by
+.An "Andreas Gruenbacher" Aq a.gruenbacher@bestbits.at .
diff --git a/man/man3/acl_get_permset.3 b/man/man3/acl_get_permset.3
new file mode 100644
index 0000000..d98f6b4
--- /dev/null
+++ b/man/man3/acl_get_permset.3
@@ -0,0 +1,82 @@
+.\" Access Control Lists manual pages
+.\"
+.\" (C) 2002 Andreas Gruenbacher, <a.gruenbacher@bestbits.at>
+.\"
+.\" This is free documentation; 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 of
+.\" the License, or (at your option) any later version.
+.\"
+.\" The GNU General Public License's references to "object code"
+.\" and "executables" are to be interpreted as the output of any
+.\" document formatting or typesetting system, including
+.\" intermediate and printed output.
+.\"
+.\" This manual 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 manual. If not, see
+.\" <http://www.gnu.org/licenses/>.
+.\"
+.Dd March 23, 2002
+.Dt ACL_GET_PERMSET 3
+.Os "Linux ACL"
+.Sh NAME
+.Nm acl_get_permset
+.Nd retrieve the permission set from an ACL entry
+.Sh LIBRARY
+Linux Access Control Lists library (libacl, \-lacl).
+.Sh SYNOPSIS
+.In sys/types.h
+.In sys/acl.h
+.Ft int
+.Fn acl_get_permset "acl_entry_t entry_d" "acl_permset_t *permset_p"
+.Sh DESCRIPTION
+The
+.Fn acl_get_permset
+function returns in
+.Va permset_p
+a descriptor to the permission set in the ACL entry indicated by
+.Va entry_d .
+Subsequent operations using the returned permission set descriptor operate on the permission set within the ACL entry.
+.Pp
+Any ACL entry descriptors that refer to the entry referred to by
+.Va entry_d
+shall continue to refer to those entries.
+.Sh RETURN VALUE
+.Rv -std acl_get_permset
+.Sh ERRORS
+If any of the following conditions occur, the
+.Fn acl_get_permset
+function returns
+.Li -1
+and sets
+.Va errno
+to the corresponding value:
+.Bl -tag -width Er
+.It Bq Er EINVAL
+The argument
+.Va entry_d
+is not a valid descriptor for an ACL entry.
+.El
+.Sh STANDARDS
+IEEE Std 1003.1e draft 17 (\(lqPOSIX.1e\(rq, abandoned)
+.Sh SEE ALSO
+.Xr acl_add_perm 3 ,
+.Xr acl_clear_perms 3 ,
+.Xr acl_delete_perm 3 ,
+.Xr acl_get_perm 3 ,
+.Xr acl_get_qualifier 3 ,
+.Xr acl_get_tag_type 3 ,
+.Xr acl_set_permset 3 ,
+.Xr acl_set_qualifier 3 ,
+.Xr acl_set_tag_type 3 ,
+.Xr acl 5
+.Sh AUTHOR
+Derived from the FreeBSD manual pages written by
+.An "Robert N M Watson" Aq rwatson@FreeBSD.org ,
+and adapted for Linux by
+.An "Andreas Gruenbacher" Aq a.gruenbacher@bestbits.at .
diff --git a/man/man3/acl_get_qualifier.3 b/man/man3/acl_get_qualifier.3
new file mode 100644
index 0000000..52ac273
--- /dev/null
+++ b/man/man3/acl_get_qualifier.3
@@ -0,0 +1,125 @@
+.\" Access Control Lists manual pages
+.\"
+.\" (C) 2002 Andreas Gruenbacher, <a.gruenbacher@bestbits.at>
+.\"
+.\" This is free documentation; 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 of
+.\" the License, or (at your option) any later version.
+.\"
+.\" The GNU General Public License's references to "object code"
+.\" and "executables" are to be interpreted as the output of any
+.\" document formatting or typesetting system, including
+.\" intermediate and printed output.
+.\"
+.\" This manual 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 manual. If not, see
+.\" <http://www.gnu.org/licenses/>.
+.\"
+.Dd March 23, 2002
+.Dt ACL_GET_QUALIFIER 3
+.Os "Linux ACL"
+.Sh NAME
+.Nm acl_get_qualifier
+.Nd retrieve the qualifier from an ACL entry
+.Sh LIBRARY
+Linux Access Control Lists library (libacl, \-lacl).
+.Sh SYNOPSIS
+.In sys/types.h
+.In sys/acl.h
+.Ft void *
+.Fn acl_get_qualifier "acl_entry_t entry_d"
+.Sh DESCRIPTION
+The
+.Fn acl_get_qualifier
+function retrieves the qualifier from the ACL entry indicated by the argument
+.Va entry_d
+into working storage and returns a pointer to that storage.
+.Pp
+If the value of the tag type in the ACL entry referred to by
+.Va entry_d
+is ACL_USER, then the value returned by
+.Fn acl_get_qualifier
+is a pointer to type
+.Va uid_t .
+If the value of the tag type in the ACL entry referred to by
+.Va entry_d
+is ACL_GROUP, then the value returned by
+.Fn acl_get_qualifier
+is a pointer to type
+.Va gid_t .
+If the tag type in the ACL entry referred to by
+.Va entry_d
+is a tag type for which a qualifier is not supported,
+.Fn acl_get_qualifier
+returns a value of
+.Li (void *)NULL
+and the function fails. Subsequent operations using the returned pointer
+operate on an independent copy of the qualifier in working storage, and will not change the qualifier of the ACL entry.
+.Pp
+This function may cause memory to be allocated. The caller should free any
+releasable memory, when the new qualifier is no longer required, by calling
+.Fn acl_free
+with the
+.Va void *
+value returned by
+.Fn acl_get_qualifier
+as an argument.
+.Pp
+The argument
+.Va entry_d
+and any other ACL entry descriptors that refer to entries within the ACL
+containing the entry referred to by
+.Va entry_d
+continue to refer to those entries. The order of all existing
+entries in the ACL containing the entry referred to by
+.Va entry_d
+remains unchanged.
+.Sh RETURN VALUE
+On success, the function returns a pointer to the tag qualifier that was retrieved into ACL working storage. On error, a value of
+.Li (void *)NULL
+is returned and
+.Va errno
+is set appropriately.
+.Sh ERRORS
+If any of the following conditions occur, the
+.Fn acl_get_qualifier
+function returns
+.Li (void *)NULL
+and sets
+.Va errno
+to the corresponding value:
+.Bl -tag -width Er
+.It Bq Er EINVAL
+The argument
+.Va entry_d
+is not a valid descriptor for an ACL entry.
+.Pp
+The value of the tag type in the ACL entry referenced by the argument
+.Va entry_d
+is neither ACL_USER nor ACL_GROUP.
+.It Bq Er ENOMEM
+The value to be returned requires more memory than is allowed by the hardware or system-imposed memory management constraints.
+.El
+.Sh STANDARDS
+IEEE Std 1003.1e draft 17 (\(lqPOSIX.1e\(rq, abandoned)
+.Sh SEE ALSO
+.Xr acl_create_entry 3 ,
+.Xr acl_free 3 ,
+.Xr acl_get_entry 3 ,
+.Xr acl_get_permset 3 ,
+.Xr acl_get_tag_type 3 ,
+.Xr acl_set_permset 3 ,
+.Xr acl_set_qualifier 3 ,
+.Xr acl_set_tag_type 3 ,
+.Xr acl 5
+.Sh AUTHOR
+Derived from the FreeBSD manual pages written by
+.An "Robert N M Watson" Aq rwatson@FreeBSD.org ,
+and adapted for Linux by
+.An "Andreas Gruenbacher" Aq a.gruenbacher@bestbits.at .
diff --git a/man/man3/acl_get_tag_type.3 b/man/man3/acl_get_tag_type.3
new file mode 100644
index 0000000..4bdfe40
--- /dev/null
+++ b/man/man3/acl_get_tag_type.3
@@ -0,0 +1,81 @@
+.\" Access Control Lists manual pages
+.\"
+.\" (C) 2002 Andreas Gruenbacher, <a.gruenbacher@bestbits.at>
+.\"
+.\" This is free documentation; 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 of
+.\" the License, or (at your option) any later version.
+.\"
+.\" The GNU General Public License's references to "object code"
+.\" and "executables" are to be interpreted as the output of any
+.\" document formatting or typesetting system, including
+.\" intermediate and printed output.
+.\"
+.\" This manual 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 manual. If not, see
+.\" <http://www.gnu.org/licenses/>.
+.\"
+.Dd March 23, 2002
+.Dt ACL_GET_TAG_TYPE 3
+.Os "Linux ACL"
+.Sh NAME
+.Nm acl_get_tag_type
+.Nd get the tag type of an ACL entry
+.Sh LIBRARY
+Linux Access Control Lists library (libacl, \-lacl).
+.Sh SYNOPSIS
+.In sys/types.h
+.In sys/acl.h
+.Ft int
+.Fn acl_get_tag_type "acl_entry_t entry_d" "acl_tag_t *tag_type_p"
+.Sh DESCRIPTION
+The
+.Fn acl_get_tag_type
+function assigns to the value pointed to by
+.Va tag_type_p
+the tag type for the ACL entry indicated by the argument
+.Va entry_d .
+.Pp
+The argument
+.Va entry_d
+and any other ACL entry descriptors that refer to entries in the same
+ACL continue to refer to those entries. The order of all existing
+entries in the ACL remain unchanged.
+.Sh RETURN VALUE
+.Rv -std acl_get_tag_type
+.Sh ERRORS
+If any of the following conditions occur, the
+.Fn acl_get_tag_type
+function returns
+.Li -1
+and sets
+.Va errno
+to the corresponding value:
+.Bl -tag -width Er
+.It Bq Er EINVAL
+The argument
+.Va entry_d
+is not a valid descriptor for an ACL entry.
+.El
+.Sh STANDARDS
+IEEE Std 1003.1e draft 17 (\(lqPOSIX.1e\(rq, abandoned)
+.Sh SEE ALSO
+.Xr acl_create_entry 3 ,
+.Xr acl_get_entry 3 ,
+.Xr acl_get_permset 3 ,
+.Xr acl_get_qualifier 3 ,
+.Xr acl_set_permset 3 ,
+.Xr acl_set_qualifier 3 ,
+.Xr acl_set_tag_type 3 ,
+.Xr acl 5
+.Sh AUTHOR
+Derived from the FreeBSD manual pages written by
+.An "Robert N M Watson" Aq rwatson@FreeBSD.org ,
+and adapted for Linux by
+.An "Andreas Gruenbacher" Aq a.gruenbacher@bestbits.at .
diff --git a/man/man3/acl_init.3 b/man/man3/acl_init.3
new file mode 100644
index 0000000..b12f636
--- /dev/null
+++ b/man/man3/acl_init.3
@@ -0,0 +1,87 @@
+.\" Access Control Lists manual pages
+.\"
+.\" (C) 2002 Andreas Gruenbacher, <a.gruenbacher@bestbits.at>
+.\"
+.\" This is free documentation; 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 of
+.\" the License, or (at your option) any later version.
+.\"
+.\" The GNU General Public License's references to "object code"
+.\" and "executables" are to be interpreted as the output of any
+.\" document formatting or typesetting system, including
+.\" intermediate and printed output.
+.\"
+.\" This manual 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 manual. If not, see
+.\" <http://www.gnu.org/licenses/>.
+.\"
+.Dd March 23, 2002
+.Dt ACL_INIT 3
+.Os "Linux ACL"
+.Sh NAME
+.Nm acl_init
+.Nd initialize ACL working storage
+.Sh LIBRARY
+Linux Access Control Lists library (libacl, \-lacl).
+.Sh SYNOPSIS
+.In sys/types.h
+.In sys/acl.h
+.Ft acl_t
+.Fn acl_init "int count"
+.Sh DESCRIPTION
+The
+.Fn acl_init
+function allocates and initializes the working storage for an ACL of at least
+.Va count
+ACL entries. The ACL created initially contains no ACL entries.
+A pointer to the working storage is returned.
+.Pp
+This function may cause memory to be allocated. The caller should free any
+releasable memory, when the new ACL is no longer required, by calling
+.Xr acl_free 3
+with the
+.Va (void*)acl_t
+returned by
+.Fn acl_init
+as an argument.
+.Sh RETURN VALUE
+On success, this function returns a pointer to the
+working storage. On error, a value of
+.Li (acl_t)NULL
+is returned, and
+.Va errno
+is set appropriately.
+.Sh ERRORS
+If any of the following conditions occur, the
+.Fn acl_init
+function returns a value of
+.Li (acl_t)NULL
+and sets
+.Va errno
+to the corresponding value:
+.Bl -tag -width Er
+.It Bq Er EINVAL
+The value of count is less than zero.
+.It Bq Er ENOMEM
+The
+.Va acl_t
+to be returned requires more memory than is allowed by the hardware or
+system-imposed memory management constraints.
+.El
+.Sh STANDARDS
+IEEE Std 1003.1e draft 17 (\(lqPOSIX.1e\(rq, abandoned)
+.Sh SEE ALSO
+.Xr acl_get_file 3 ,
+.Xr acl_free 3 ,
+.Xr acl 5
+.Sh AUTHOR
+Derived from the FreeBSD manual pages written by
+.An "Robert N M Watson" Aq rwatson@FreeBSD.org ,
+and adapted for Linux by
+.An "Andreas Gruenbacher" Aq a.gruenbacher@bestbits.at .
diff --git a/man/man3/acl_set_fd.3 b/man/man3/acl_set_fd.3
new file mode 100644
index 0000000..7f623ed
--- /dev/null
+++ b/man/man3/acl_set_fd.3
@@ -0,0 +1,91 @@
+.\" Access Control Lists manual pages
+.\"
+.\" (C) 2002 Andreas Gruenbacher, <a.gruenbacher@bestbits.at>
+.\"
+.\" This is free documentation; 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 of
+.\" the License, or (at your option) any later version.
+.\"
+.\" The GNU General Public License's references to "object code"
+.\" and "executables" are to be interpreted as the output of any
+.\" document formatting or typesetting system, including
+.\" intermediate and printed output.
+.\"
+.\" This manual 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 manual. If not, see
+.\" <http://www.gnu.org/licenses/>.
+.\"
+.Dd March 23, 2002
+.Dt ACL_SET_FD 3
+.Os "Linux ACL"
+.Sh NAME
+.Nm acl_set_fd
+.Nd set an ACL by file descriptor
+.Sh LIBRARY
+Linux Access Control Lists library (libacl, \-lacl).
+.Sh SYNOPSIS
+.In sys/types.h
+.In sys/acl.h
+.Ft int
+.Fn acl_set_fd "int fd" "acl_t acl"
+.Sh DESCRIPTION
+The
+.Fn acl_set_fd
+function associates an access ACL with the file referred to by
+.Va fd .
+.Pp
+The effective user ID of the process must match the owner of the file or the process must have the CAP_FOWNER capability for the request to succeed.
+.Sh RETURN VALUE
+.Rv -std acl_set_fd
+.Sh ERRORS
+If any of the following conditions occur, the
+.Fn acl_set_fd
+function returns the value
+.Li -1
+and and sets
+.Va errno
+to the corresponding value:
+.Bl -tag -width Er
+.It Bq Er EBADF
+The
+.Va fd
+argument is not a valid file descriptor.
+.It Bq Er EINVAL
+The argument
+.Va acl
+does not point to a valid ACL.
+.Pp
+The ACL has more entries than the file referred to by
+.Va fd
+can obtain.
+.It Bq Er ENOSPC
+The directory or file system that would contain the new ACL cannot be extended or the file system is out of file allocation resources.
+.It Bq Er ENOTSUP
+The file identified by
+.Va fd
+cannot be associated with the ACL because the file system on which the file
+is located does not support this.
+.It Bq Er EPERM
+The process does not have appropriate privilege to perform the operation to set the ACL.
+.It Bq Er EROFS
+This function requires modification of a file system which is currently read-only.
+.El
+.Sh STANDARDS
+IEEE Std 1003.1e draft 17 (\(lqPOSIX.1e\(rq, abandoned)
+.Sh SEE ALSO
+.Xr acl_delete_def_file 3 ,
+.Xr acl_get_file 3 ,
+.Xr acl_set_file 3 ,
+.Xr acl_valid 3 ,
+.Xr acl 5
+.Sh AUTHOR
+Derived from the FreeBSD manual pages written by
+.An "Robert N M Watson" Aq rwatson@FreeBSD.org ,
+and adapted for Linux by
+.An "Andreas Gruenbacher" Aq a.gruenbacher@bestbits.at .
diff --git a/man/man3/acl_set_file.3 b/man/man3/acl_set_file.3
new file mode 100644
index 0000000..9cdd524
--- /dev/null
+++ b/man/man3/acl_set_file.3
@@ -0,0 +1,168 @@
+.\" Access Control Lists manual pages
+.\"
+.\" (C) 2002 Andreas Gruenbacher, <a.gruenbacher@bestbits.at>
+.\"
+.\" This is free documentation; 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 of
+.\" the License, or (at your option) any later version.
+.\"
+.\" The GNU General Public License's references to "object code"
+.\" and "executables" are to be interpreted as the output of any
+.\" document formatting or typesetting system, including
+.\" intermediate and printed output.
+.\"
+.\" This manual 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 manual. If not, see
+.\" <http://www.gnu.org/licenses/>.
+.\"
+.Dd March 23, 2002
+.Dt ACL_SET_FILE 3
+.Os "Linux ACL"
+.Sh NAME
+.Nm acl_set_file
+.Nd set an ACL by filename
+.Sh LIBRARY
+Linux Access Control Lists library (libacl, \-lacl).
+.Sh SYNOPSIS
+.In sys/types.h
+.In sys/acl.h
+.Ft int
+.Fn acl_set_file "const char *path_p" "acl_type_t type" "acl_t acl"
+.Sh DESCRIPTION
+The
+.Fn acl_set_file
+function associates an access ACL with a file or directory, or
+associates a default ACL with a directory. The pathname for the file or
+directory is pointed to by the argument
+.Va path_p .
+.Pp
+The effective user ID of the process must match the owner of the file or
+directory or the process must have the CAP_FOWNER capability for the
+request to succeed.
+.Pp
+The value of the argument
+.Va type
+is used to indicate whether the access ACL or the default ACL associated
+with
+.Va path_p
+is being set. If the
+.Va type
+parameter is ACL_TYPE_ACCESS, the access ACL of
+.Va path_p
+shall be set. If the
+.Va type
+parameter is ACL_TYPE_DEFAULT, the default ACL of
+.Va path_p
+shall be set. If the argument
+.Va type
+specifies a type of ACL that cannot be associated with
+.Va path_p ,
+then the function fails.
+.Pp
+The
+.Va acl
+parameter must reference a valid ACL according to the rules described on the
+.Xr acl_valid 3
+manual page if the
+.Va type
+parameter is ACL_TYPE_ACCESS, and must either reference a valid ACL or an ACL with zero ACL entries if the
+.Va type
+parameter is ACL_TYPE_DEFAULT. If the
+.Va acl
+parameter references an empty ACL, then the
+.Fn acl_set_file
+function removes any default ACL associated with the directory referred to
+by the
+.Va path_p
+parameter.
+.Sh RETURN VALUE
+.Rv -std acl_set_file
+.Sh ERRORS
+If any of the following conditions occur, the
+.Fn acl_set_file
+function returns
+.Li -1
+and sets
+.Va errno
+to the corresponding value:
+.Bl -tag -width Er
+.It Bq Er EACCES
+Search permission is denied for a component of the path prefix or the
+object exists and the process does not have appropriate access rights.
+.Pp
+Argument
+.Va type
+specifies a type of ACL that cannot be associated with
+.Va path_p .
+.It Bq Er EINVAL
+The argument
+.Va acl
+does not point to a valid ACL.
+.Pp
+The ACL has more entries than the file referred to by
+.Va path_p
+can obtain.
+.Pp
+The
+.Va type
+parameter is not ACL_TYPE_ACCESS or ACL_TYPE_DEFAULT.
+.Pp
+The
+.Va type
+parameter is ACL_TYPE_DEFAULT, but the file referred to by
+.Va path_p
+is not a directory.
+.It Bq Er ENAMETOOLONG
+The length of the argument
+.Va path_p
+is too long.
+.It Bq Er ENOENT
+The named object does not exist or the argument
+.Va path_p
+points to an empty string.
+.It Bq Er ENOSPC
+The directory or file system that would contain the new ACL cannot be extended or the file system is out of file allocation resources.
+.It Bq Er ENOTDIR
+A component of the path prefix is not a directory.
+.It Bq Er ENOTSUP
+The file identified by
+.Va path_p
+cannot be associated with the ACL because the file system on which the file
+is located does not support this.
+.It Bq Er EPERM
+The process does not have appropriate privilege to perform the operation to set the ACL.
+.It Bq Er EROFS
+This function requires modification of a file system which is currently read-only.
+.El
+.Sh STANDARDS
+IEEE Std 1003.1e draft 17 (\(lqPOSIX.1e\(rq, abandoned)
+.Pp
+The behavior of
+.Fn acl_set_file
+when the
+.Va acl
+parameter refers to an empty ACL and the
+.Va type
+parameter is ACL_TYPE_DEFAULT is an extension in the Linux implementation, in order that all values returned by
+.Fn acl_get_file
+can be passed to
+.Fn acl_set_file .
+The POSIX.1e function for removing a default ACL is
+.Fn acl_delete_def_file .
+.Sh SEE ALSO
+.Xr acl_delete_def_file 3 ,
+.Xr acl_get_file 3 ,
+.Xr acl_set_fd 3 ,
+.Xr acl_valid 3 ,
+.Xr acl 5
+.Sh AUTHOR
+Derived from the FreeBSD manual pages written by
+.An "Robert N M Watson" Aq rwatson@FreeBSD.org ,
+and adapted for Linux by
+.An "Andreas Gruenbacher" Aq a.gruenbacher@bestbits.at .
diff --git a/man/man3/acl_set_permset.3 b/man/man3/acl_set_permset.3
new file mode 100644
index 0000000..e48580c
--- /dev/null
+++ b/man/man3/acl_set_permset.3
@@ -0,0 +1,98 @@
+.\" Access Control Lists manual pages
+.\"
+.\" (C) 2002 Andreas Gruenbacher, <a.gruenbacher@bestbits.at>
+.\"
+.\" This is free documentation; 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 of
+.\" the License, or (at your option) any later version.
+.\"
+.\" The GNU General Public License's references to "object code"
+.\" and "executables" are to be interpreted as the output of any
+.\" document formatting or typesetting system, including
+.\" intermediate and printed output.
+.\"
+.\" This manual 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 manual. If not, see
+.\" <http://www.gnu.org/licenses/>.
+.\"
+.Dd March 23, 2002
+.Dt ACL_SET_PERMSET 3
+.Os "Linux ACL"
+.Sh NAME
+.Nm acl_set_permset
+.Nd set the permission set in an ACL entry
+.Sh LIBRARY
+Linux Access Control Lists library (libacl, \-lacl).
+.Sh SYNOPSIS
+.In sys/types.h
+.In sys/acl.h
+.Ft int
+.Fn acl_set_permset "acl_entry_t entry_d" "acl_permset_t permset_d"
+.Sh DESCRIPTION
+The
+.Fn acl_set_permset
+function sets the permission set of the ACL entry indicated by the argument
+.Va entry_d
+to the permissions contained in the argument
+.Va permset_d .
+.Pp
+Any ACL entry descriptors that refer to the entry containing the permission
+set referred to by
+.Va permset_d
+shall continue to refer to those entries. Any ACL entry descriptors that
+refer to the entry referred to by
+.Va entry_d
+shall continue to refer to that entry.
+.Sh RETURN VALUE
+.Rv -std acl_set_permset
+.Sh ERRORS
+If any of the following conditions occur, the
+.Fn acl_set_permset
+function returns
+.Li -1
+and sets
+.Va errno
+to the corresponding value:
+.Bl -tag -width Er
+.It Bq Er EINVAL
+The argument
+.Va entry_d
+is not a valid descriptor for an ACL entry.
+.Pp
+The argument
+.Va permset_d
+is not a valid descriptor for a permission set within an ACL entry.
+.Pp
+.\" <AG>
+.\" The following condition seems strange.
+.\" </AG>
+The argument
+.Va permset_d
+contains values which are not valid
+.Va acl_permset_t
+values.
+.El
+.Sh STANDARDS
+IEEE Std 1003.1e draft 17 (\(lqPOSIX.1e\(rq, abandoned)
+.Sh SEE ALSO
+.Xr acl_add_perm 3 ,
+.Xr acl_clear_perms 3 ,
+.Xr acl_delete_perm 3 ,
+.Xr acl_get_perm 3 ,
+.Xr acl_get_permset 3 ,
+.Xr acl_get_qualifier 3 ,
+.Xr acl_get_tag_type 3 ,
+.Xr acl_set_qualifier 3 ,
+.Xr acl_set_tag_type 3 ,
+.Xr acl 5
+.Sh AUTHOR
+Derived from the FreeBSD manual pages written by
+.An "Robert N M Watson" Aq rwatson@FreeBSD.org ,
+and adapted for Linux by
+.An "Andreas Gruenbacher" Aq a.gruenbacher@bestbits.at .
diff --git a/man/man3/acl_set_qualifier.3 b/man/man3/acl_set_qualifier.3
new file mode 100644
index 0000000..eb49747
--- /dev/null
+++ b/man/man3/acl_set_qualifier.3
@@ -0,0 +1,113 @@
+.\" Access Control Lists manual pages
+.\"
+.\" (C) 2002 Andreas Gruenbacher, <a.gruenbacher@bestbits.at>
+.\"
+.\" This is free documentation; 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 of
+.\" the License, or (at your option) any later version.
+.\"
+.\" The GNU General Public License's references to "object code"
+.\" and "executables" are to be interpreted as the output of any
+.\" document formatting or typesetting system, including
+.\" intermediate and printed output.
+.\"
+.\" This manual 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 manual. If not, see
+.\" <http://www.gnu.org/licenses/>.
+.\"
+.Dd March 23, 2002
+.Dt ACL_SET_QUALIFIER 3
+.Os "Linux ACL"
+.Sh NAME
+.Nm acl_set_qualifier
+.Nd set the qualifier of an ACL entry
+.Sh LIBRARY
+Linux Access Control Lists library (libacl, \-lacl).
+.Sh SYNOPSIS
+.In sys/types.h
+.In sys/acl.h
+.Ft int
+.Fn acl_set_qualifier "acl_entry_t entry_d" "const void *qualifier_p"
+.Sh DESCRIPTION
+The
+.Fn acl_set_qualifier
+function sets the qualifier of the ACL entry indicated by the argument
+.Va entry_d
+to the value referred to by the argument
+.Va qualifier_p .
+If the value of the tag type in the ACL entry referred to by
+.Va entry_d
+is ACL_USER, then the value referred to by
+.Va qualifier_p
+shall be of type
+.Va uid_t .
+If the value of the tag type in the ACL entry referred to by
+.Va entry_d
+is ACL_GROUP, then the value referred to by
+.Va qualifier_p
+shall be of type
+.Va gid_t .
+If the value of the tag type in the ACL entry referred to by
+.Va entry_d
+is a tag type for which a qualifier is not supported,
+.Fn acl_set_qualifier
+returns an error.
+.Pp
+Any ACL entry descriptors that refer to the entry referred to by
+.Va entry_d
+continue to refer to that entry. This function may cause memory to be
+allocated. The caller should free any releasable memory, when the ACL
+is no longer required, by calling
+.Fn acl_free
+with a pointer to the ACL as argument.
+.Sh RETURN VALUE
+.Rv -std acl_set_qualifier
+.Sh ERRORS
+If any of the following conditions occur, the
+.Fn acl_set_qualifier
+function returns
+.Li -1
+and sets
+.Va errno
+to the corresponding value:
+.Bl -tag -width Er
+.It Bq Er EINVAL
+The argument
+.Va entry_d
+is not a valid descriptor for an ACL entry.
+.Pp
+The value of the tag type in the ACL entry referenced by the argument
+.Va entry_d
+is neither ACL_USER nor ACL_GROUP.
+.Pp
+The value pointed to by the argument
+.Va qualifier_p
+is not valid.
+.It Bq Er ENOMEM
+The
+.Fn acl_set_qualifier
+function is unable to allocate the memory required for the ACL qualifier.
+.El
+.Sh STANDARDS
+IEEE Std 1003.1e draft 17 (\(lqPOSIX.1e\(rq, abandoned)
+.Sh SEE ALSO
+.Xr acl_create_entry 3 ,
+.Xr acl_free 3 ,
+.Xr acl_get_permset 3 ,
+.Xr acl_get_qualifier 3 ,
+.Xr acl_get_tag_type 3 ,
+.Xr acl_set_entry 3 ,
+.Xr acl_set_permset 3 ,
+.Xr acl_set_tag_type 3 ,
+.Xr acl 5
+.Sh AUTHOR
+Derived from the FreeBSD manual pages written by
+.An "Robert N M Watson" Aq rwatson@FreeBSD.org ,
+and adapted for Linux by
+.An "Andreas Gruenbacher" Aq a.gruenbacher@bestbits.at .
diff --git a/man/man3/acl_set_tag_type.3 b/man/man3/acl_set_tag_type.3
new file mode 100644
index 0000000..05b771d
--- /dev/null
+++ b/man/man3/acl_set_tag_type.3
@@ -0,0 +1,83 @@
+.\" Access Control Lists manual pages
+.\"
+.\" (C) 2002 Andreas Gruenbacher, <a.gruenbacher@bestbits.at>
+.\"
+.\" This is free documentation; 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 of
+.\" the License, or (at your option) any later version.
+.\"
+.\" The GNU General Public License's references to "object code"
+.\" and "executables" are to be interpreted as the output of any
+.\" document formatting or typesetting system, including
+.\" intermediate and printed output.
+.\"
+.\" This manual 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 manual. If not, see
+.\" <http://www.gnu.org/licenses/>.
+.\"
+.Dd March 23, 2002
+.Dt ACL_SET_TAG_TYPE 3
+.Os "Linux ACL"
+.Sh NAME
+.Nm acl_set_tag_type
+.Nd set the tag type of an ACL entry
+.Sh LIBRARY
+Linux Access Control Lists library (libacl, \-lacl).
+.Sh SYNOPSIS
+.In sys/types.h
+.In sys/acl.h
+.Ft int
+.Fn acl_set_tag_type "acl_entry_t entry_d" "acl_tag_t tag_type"
+.Sh DESCRIPTION
+The
+.Fn acl_set_tag_type
+function sets the tag type of the ACL entry indicated by the argument
+.Va entry_d
+to the value of the argument
+.Va tag_type .
+.Pp
+Any ACL entry descriptors that refer to the entry referred to by
+.Va entry_d
+continue to refer to that entry.
+.Sh RETURN VALUE
+.Rv -std acl_set_tag_type
+.Sh ERRORS
+If any of the following conditions occur, the
+.Fn acl_set_tag_type
+function returns
+.Li -1
+and sets
+.Va errno
+to the corresponding value:
+.Bl -tag -width Er
+.It Bq Er EINVAL
+The argument
+.Va entry_d
+is not a valid descriptor for an ACL entry.
+.Pp
+The argument
+.Va tag_type
+is not a valid tag type.
+.El
+.Sh STANDARDS
+IEEE Std 1003.1e draft 17 (\(lqPOSIX.1e\(rq, abandoned)
+.Sh SEE ALSO
+.Xr acl_create_entry 3 ,
+.Xr acl_get_permset 3 ,
+.Xr acl_get_qualifier 3 ,
+.Xr acl_get_tag_type 3 ,
+.Xr acl_set_entry 3 ,
+.Xr acl_set_permset 3 ,
+.Xr acl_set_qualifier 3 ,
+.Xr acl 5
+.Sh AUTHOR
+Derived from the FreeBSD manual pages written by
+.An "Robert N M Watson" Aq rwatson@FreeBSD.org ,
+and adapted for Linux by
+.An "Andreas Gruenbacher" Aq a.gruenbacher@bestbits.at .
diff --git a/man/man3/acl_size.3 b/man/man3/acl_size.3
new file mode 100644
index 0000000..e574750
--- /dev/null
+++ b/man/man3/acl_size.3
@@ -0,0 +1,85 @@
+.\" Access Control Lists manual pages
+.\"
+.\" (C) 2002 Andreas Gruenbacher, <a.gruenbacher@bestbits.at>
+.\"
+.\" This is free documentation; 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 of
+.\" the License, or (at your option) any later version.
+.\"
+.\" The GNU General Public License's references to "object code"
+.\" and "executables" are to be interpreted as the output of any
+.\" document formatting or typesetting system, including
+.\" intermediate and printed output.
+.\"
+.\" This manual 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 manual. If not, see
+.\" <http://www.gnu.org/licenses/>.
+.\"
+.Dd March 23, 2002
+.Dt ACL_SIZE 3
+.Os "Linux ACL"
+.Sh NAME
+.Nm acl_size
+.Nd get the size of the external representation of an ACL
+.Sh LIBRARY
+Linux Access Control Lists library (libacl, \-lacl).
+.Sh SYNOPSIS
+.In sys/types.h
+.In sys/acl.h
+.Ft ssize_t
+.Fn acl_size "acl_t acl"
+.Sh DESCRIPTION
+The
+.Fn acl_size
+function return the size, in bytes, of the buffer required to hold the exportable, contiguous, persistent form of the ACL pointed to by the argument
+.Va acl ,
+when converted by
+.Fn acl_copy_ext .
+.Pp
+Any existing ACL entry descriptors that refer to entries in
+.Va acl
+continue to refer to the same entries. Any existing ACL pointers that refer
+to the ACL referred to by
+.Va acl
+continue to refer to the ACL. The order of ACL entries within
+.Va acl
+remains unchanged.
+.Sh RETURN VALUE
+On success, the
+.Fn acl_size
+function returns the size in bytes of the contiguous, persistent form of
+the ACL. On error, a value of
+.Li (ssize_t)-1
+is returned and
+.Va errno
+is set appropriately.
+.Sh ERRORS
+If any of the following conditions occur, the
+.Fn acl_size
+function returns a value of
+.Li (ssize_t)-1
+and sets
+.Va errno
+to the corresponding value:
+.Bl -tag -width Er
+.It Bq Er EINVAL
+The argument
+.Va acl
+is not a valid pointer to an ACL.
+.El
+.Sh STANDARDS
+IEEE Std 1003.1e draft 17 (\(lqPOSIX.1e\(rq, abandoned)
+.Sh SEE ALSO
+.Xr acl_copy_ext 3 ,
+.Xr acl 5
+.Sh AUTHOR
+Derived from the FreeBSD manual pages written by
+.An "Robert N M Watson" Aq rwatson@FreeBSD.org ,
+and adapted for Linux by
+.An "Andreas Gruenbacher" Aq a.gruenbacher@bestbits.at .
diff --git a/man/man3/acl_to_any_text.3 b/man/man3/acl_to_any_text.3
new file mode 100644
index 0000000..fd3cf74
--- /dev/null
+++ b/man/man3/acl_to_any_text.3
@@ -0,0 +1,169 @@
+.\" Access Control Lists manual pages
+.\"
+.\" (C) 2002 Andreas Gruenbacher, <a.gruenbacher@bestbits.at>
+.\"
+.\" This is free documentation; 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 of
+.\" the License, or (at your option) any later version.
+.\"
+.\" The GNU General Public License's references to "object code"
+.\" and "executables" are to be interpreted as the output of any
+.\" document formatting or typesetting system, including
+.\" intermediate and printed output.
+.\"
+.\" This manual 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 manual. If not, see
+.\" <http://www.gnu.org/licenses/>.
+.\"
+.Dd March 25, 2002
+.Dt ACL_TO_ANY_TEXT 3
+.Os "Linux ACL"
+.Sh NAME
+.Nm acl_to_any_text
+.Nd convert an ACL to text
+.Sh LIBRARY
+Linux Access Control Lists library (libacl, \-lacl).
+.Sh SYNOPSIS
+.In sys/types.h
+.In acl/libacl.h
+.Ft char *
+.Fo acl_to_any_text
+.Fa "acl_t acl"
+.Fa "const char *prefix"
+.Fa "char separator"
+.Fa "int options"
+.Fc
+.Sh DESCRIPTION
+The
+.Fn acl_to_any_text
+function translates the ACL pointed to by the argument
+.Va acl
+into a
+.Li NULL
+terminated character string. This character string
+is composed of the ACL entries contained in
+.Va acl ,
+in the entry text format described on
+.Xr acl 5 .
+Entries are separated from each other by the
+.Va separator
+character. If the argument
+.Va prefix
+is not
+.Li (const char *)NULL ,
+each entry is prefixed by this character string.
+.Pp
+If the argument
+.Va options
+is
+.Li 0 ,
+ACL entries are converted using the entry tag type keywords
+.Li user , group , mask ,
+and
+.Li other .
+User IDs and group IDs of ACL entries that contain such
+qualifiers are converted to their corresponding names; if an identifier
+has no corresponding name, a decimal number string is produced. The
+ACL text representation contains no additional comments.
+A bitwise combinations of the following
+.Va options
+can be used to modify the result:
+.Bl -tag
+.It TEXT_ABBREVIATE
+Instead of the full tag type keywords, single letter abbreviations are used.
+The abbreviation for
+.Li user
+is
+.Li u ,
+the abbreviation for
+.Li group
+is
+.Li g ,
+the abbreviation for
+.Li mask
+is
+.Li m ,
+and the abbreviation for
+.Li other
+is
+.Li o .
+.It TEXT_NUMERIC_IDS
+User IDs and group IDs are included as decimal numbers instead of names.
+.It TEXT_SOME_EFFECTIVE
+A comment containing the effective permissions of the ACL entry is
+included after ACL entries that contain permissions which are ineffective
+because they are masked by an ACL_MASK entry. The ACL entry and the comment
+are separated by a tab character.
+.It TEXT_ALL_EFFECTIVE
+A comment containing the effective permissions of the ACL entry is
+included after all ACL entries that are affected by an ACL_MASK entry.
+The comment is included even if the permissions contained in the ACL
+entry equal the effective permissions. The ACL entry and the comment are
+separated by a tab character.
+.It TEXT_SMART_INDENT
+This option is used in combination with the TEXT_SOME_EFFECTIVE or
+TEXT_ALL_EFFECTIVE option. The number of tab characters inserted between
+the ACL entry and the comment is increased so that the comment is
+aligned to the fourth tab stop position.
+A tab width of 8 characters is assumed.
+.El
+.Pp
+The ACL referred to by
+.Va acl
+is not changed.
+.Pp
+This function allocates any memory necessary to contain the string and
+returns a pointer to the string. The caller should free any releasable
+memory, when the new string is no longer required, by calling
+.Fn acl_free
+with the
+.Va (void*)char
+returned by
+.Fn acl_to_any_text
+as an argument.
+.Sh RETURN VALUE
+On success, this function returns a pointer to the text
+representation of the ACL. On error, a value of
+.Li (char *)NULL
+is returned, and
+.Va errno
+is set appropriately.
+.Sh ERRORS
+If any of the following conditions occur, the
+.Fn acl_to_any_text
+function returns a value of
+.Li (char *)NULL
+and sets
+.Va errno
+to the corresponding value:
+.Bl -tag -width Er
+.It Bq Er EINVAL
+The argument
+.Va acl
+is not a valid pointer to an ACL.
+.Pp
+The ACL referenced by
+.Va acl
+contains one or more improperly formed ACL entries, or for some other
+reason cannot be translated into the text form of an ACL.
+.It Bq Er ENOMEM
+The character string to be returned requires more memory than is allowed
+by the hardware or system-imposed memory management constraints.
+.El
+.Sh STANDARDS
+This is a non-portable, Linux specific extension to the ACL manipulation
+functions defined in IEEE Std 1003.1e draft 17 (\(lqPOSIX.1e\(rq, abandoned).
+.Sh SEE ALSO
+.Xr acl_from_text 3 ,
+.Xr acl_to_text 3 ,
+.Xr acl_free 3 ,
+.Xr acl 5
+.Sh AUTHOR
+Written by
+.An "Andreas Gruenbacher" Aq a.gruenbacher@bestbits.at .
diff --git a/man/man3/acl_to_text.3 b/man/man3/acl_to_text.3
new file mode 100644
index 0000000..1b64e62
--- /dev/null
+++ b/man/man3/acl_to_text.3
@@ -0,0 +1,111 @@
+.\" Access Control Lists manual pages
+.\"
+.\" (C) 2002 Andreas Gruenbacher, <a.gruenbacher@bestbits.at>
+.\"
+.\" This is free documentation; 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 of
+.\" the License, or (at your option) any later version.
+.\"
+.\" The GNU General Public License's references to "object code"
+.\" and "executables" are to be interpreted as the output of any
+.\" document formatting or typesetting system, including
+.\" intermediate and printed output.
+.\"
+.\" This manual 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 manual. If not, see
+.\" <http://www.gnu.org/licenses/>.
+.\"
+.Dd March 23, 2002
+.Dt ACL_FROM_TEXT 3
+.Os "Linux ACL"
+.Sh NAME
+.Nm acl_to_text
+.Nd convert an ACL to text
+.Sh LIBRARY
+Linux Access Control Lists library (libacl, \-lacl).
+.Sh SYNOPSIS
+.In sys/types.h
+.In sys/acl.h
+.Ft char *
+.Fn acl_to_text "acl_t acl" "ssize_t *len_p"
+.Sh DESCRIPTION
+The
+.Fn acl_to_text
+function translates the ACL pointed to by the argument
+.Va acl
+into a
+.Li NULL
+terminated character string. If the pointer
+.Va len_p
+is not
+.Li NULL ,
+then the function returns the length of the string (not
+including the
+.Li NULL
+terminator) in the location pointed to by
+.Va len_p .
+The format of the text string returned by
+.Fn acl_to_text
+is the long text form defined in
+.Xr acl 5 .
+The ACL referred to by
+.Va acl
+is not changed.
+.Pp
+This function allocates any memory necessary to contain the string and
+returns a pointer to the string. The caller should free any releasable
+memory, when the new string is no longer required, by calling
+.Xr acl_free 3
+with the
+.Va (void*)char
+returned by
+.Fn acl_to_text
+as an argument.
+.Sh RETURN VALUE
+On success, this function returns a pointer to the
+long text form of the ACL.
+On error, a value of
+.Li (char *)NULL
+is returned, and
+.Va errno
+is set appropriately.
+.Sh ERRORS
+If any of the following conditions occur, the
+.Fn acl_to_text
+function returns a value of
+.Li (char *)NULL
+and sets
+.Va errno
+to the corresponding value:
+.Bl -tag -width Er
+.It Bq Er EINVAL
+The argument
+.Va acl
+is not a valid pointer to an ACL.
+.Pp
+The ACL referenced by
+.Va acl
+contains one or more improperly formed ACL entries, or for some other
+reason cannot be translated into a text form of an ACL.
+.It Bq Er ENOMEM
+The character string to be returned requires more memory than is allowed
+by the hardware or system-imposed memory management constraints.
+.El
+.Sh STANDARDS
+IEEE Std 1003.1e draft 17 (\(lqPOSIX.1e\(rq, abandoned)
+.Sh SEE ALSO
+.Xr acl_free 3 ,
+.Xw acl_from_text 3 ,
+.Xr acl_to_any_text 3 ,
+.Xr acl 5
+.Sh AUTHOR
+Derived from the FreeBSD manual pages written by
+.An "Robert N M Watson" Aq rwatson@FreeBSD.org ,
+and adapted for Linux by
+.An "Andreas Gruenbacher" Aq a.gruenbacher@bestbits.at .
diff --git a/man/man3/acl_valid.3 b/man/man3/acl_valid.3
new file mode 100644
index 0000000..89ec4d9
--- /dev/null
+++ b/man/man3/acl_valid.3
@@ -0,0 +1,86 @@
+.\" Access Control Lists manual pages
+.\"
+.\" (C) 2002 Andreas Gruenbacher, <a.gruenbacher@bestbits.at>
+.\"
+.\" This is free documentation; 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 of
+.\" the License, or (at your option) any later version.
+.\"
+.\" The GNU General Public License's references to "object code"
+.\" and "executables" are to be interpreted as the output of any
+.\" document formatting or typesetting system, including
+.\" intermediate and printed output.
+.\"
+.\" This manual 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 manual. If not, see
+.\" <http://www.gnu.org/licenses/>.
+.\"
+.Dd March 23, 2002
+.Dt ACL_VALID 3
+.Os "Linux ACL"
+.Sh NAME
+.Nm acl_valid
+.Nd validate an ACL
+.Sh LIBRARY
+Linux Access Control Lists library (libacl, \-lacl).
+.Sh SYNOPSIS
+.In sys/types.h
+.In sys/acl.h
+.Ft int
+.Fn acl_valid "acl_t acl"
+.Sh DESCRIPTION
+The
+.Fn acl_valid
+function checks the ACL referred to by the argument
+.Va acl
+for validity.
+.Pp
+The three required entries ACL_USER_OBJ, ACL_GROUP_OBJ, and ACL_OTHER
+must exist exactly once in the ACL. If the ACL contains any ACL_USER or
+ACL_GROUP entries, then an ACL_MASK entry is also required. The ACL
+may contain at most one ACL_MASK entry.
+.Pp
+The user identifiers must be unique among all entries of type ACL_USER.
+The group identifiers must be unique among all entries of type ACL_GROUP.
+.Sh RETURN VALUE
+.Rv -std acl_valid
+.Sh ERRORS
+If any of the following conditions occur, the
+.Fn acl_valid
+function returns
+.Li -1
+and sets
+.Va errno
+to the corresponding value:
+.Bl -tag -width Er
+.It Bq Er EINVAL
+The argument
+.Va acl
+is not a valid pointer to an ACL.
+.Pp
+The argument
+.Va acl
+does not point to a valid ACL.
+.Pp
+One or more of the required ACL entries is not present in
+.Va acl .
+.Pp
+The ACL contains entries that are not unique.
+.El
+.Sh STANDARDS
+IEEE Std 1003.1e draft 17 (\(lqPOSIX.1e\(rq, abandoned)
+.Sh SEE ALSO
+.Xr acl_check 3 ,
+.Xr acl_set_file 3 ,
+.Xr acl 5
+.Sh AUTHOR
+Derived from the FreeBSD manual pages written by
+.An "Robert N M Watson" Aq rwatson@FreeBSD.org ,
+and adapted for Linux by
+.An "Andreas Gruenbacher" Aq a.gruenbacher@bestbits.at .
diff --git a/man/man5/Makefile b/man/man5/Makefile
new file mode 100644
index 0000000..51de8d9
--- /dev/null
+++ b/man/man5/Makefile
@@ -0,0 +1,35 @@
+#
+# Copyright (c) 2000-2002 Silicon Graphics, Inc. All Rights Reserved.
+#
+# 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 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, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+
+TOPDIR = ../..
+include $(TOPDIR)/include/builddefs
+
+MAN_SECTION = 5
+
+MAN_PAGES = $(shell echo *.$(MAN_SECTION))
+MAN_DEST = $(PKG_MAN_DIR)/man$(MAN_SECTION)
+LSRCFILES = $(MAN_PAGES)
+
+default : $(MAN_PAGES)
+
+include $(BUILDRULES)
+
+install : default
+ $(INSTALL) -m 755 -d $(MAN_DEST)
+ $(INSTALL_MAN)
+install-dev install-lib:
diff --git a/man/man5/acl.5 b/man/man5/acl.5
new file mode 100644
index 0000000..6b0f468
--- /dev/null
+++ b/man/man5/acl.5
@@ -0,0 +1,504 @@
+.\" Access Control Lists manual pages
+.\"
+.\" (C) 2002 Andreas Gruenbacher, <a.gruenbacher@bestbits.at>
+.\"
+.\" This is free documentation; 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 of
+.\" the License, or (at your option) any later version.
+.\"
+.\" The GNU General Public License's references to "object code"
+.\" and "executables" are to be interpreted as the output of any
+.\" document formatting or typesetting system, including
+.\" intermediate and printed output.
+.\"
+.\" This manual 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 manual. If not, see
+.\" <http://www.gnu.org/licenses/>.
+.\"
+.Dd March 23, 2002
+.Dt ACL 5
+.Os "Linux ACL"
+.Sh NAME
+.Nm acl
+.Nd Access Control Lists
+.Sh DESCRIPTION
+This manual page describes POSIX Access Control Lists, which are used to
+define more fine-grained discretionary access rights for files and
+directories.
+.Sh ACL TYPES
+Every object can be thought of as having associated with it an ACL that
+governs the discretionary access to that object; this ACL is referred to
+as an access ACL. In addition, a directory may have an associated ACL
+that governs the initial access ACL for objects created within that
+directory; this ACL is referred to as a default ACL.
+.Sh ACL ENTRIES
+An ACL consists of a set of ACL entries. An ACL entry specifies the
+access permissions on the associated object for an individual user or a
+group of users as a combination of read, write and search/execute
+permissions.
+.Pp
+An ACL entry contains an entry tag type, an optional entry tag
+qualifier, and a set of permissions.
+We use the term qualifier to denote the entry tag qualifier of an ACL entry.
+.Pp
+The qualifier denotes the identifier of a user or a group, for entries
+with tag types of ACL_USER or ACL_GROUP, respectively. Entries with tag
+types other than ACL_USER or ACL_GROUP have no defined qualifiers.
+.Pp
+The following entry tag types are defined:
+.Bl -tag -offset indent -width ACL_GROUP_OBJ.
+.It ACL_USER_OBJ
+The ACL_USER_OBJ entry denotes access rights for the file owner.
+.It ACL_USER
+ACL_USER entries denote access rights for users identified by
+the entry's qualifier.
+.It ACL_GROUP_OBJ
+The ACL_GROUP_OBJ entry denotes access rights for the file group.
+.It ACL_GROUP
+ACL_GROUP entries denote access rights for groups identified by
+the entry's qualifier.
+.It ACL_MASK
+The ACL_MASK entry denotes the maximum access rights that can be granted
+by entries of type ACL_USER, ACL_GROUP_OBJ, or ACL_GROUP.
+.It ACL_OTHER
+The ACL_OTHER entry denotes access rights for processes
+that do not match any other entry in the ACL.
+.El
+.Pp
+When an access check is performed, the ACL_USER_OBJ and ACL_USER entries
+are tested against the effective user ID. The effective group ID, as
+well as all supplementary group IDs are tested against the ACL_GROUP_OBJ
+and ACL_GROUP entries.
+.Sh VALID ACLs
+A valid ACL contains exactly one entry with each of the ACL_USER_OBJ,
+ACL_GROUP_OBJ, and ACL_OTHER tag types. Entries with ACL_USER and
+ACL_GROUP tag types may appear zero or more times in an ACL. An ACL that
+contains entries of ACL_USER or ACL_GROUP tag types must contain
+exactly one entry of the ACL_MASK tag type. If an ACL contains no
+entries of ACL_USER or ACL_GROUP tag types, the ACL_MASK entry is
+optional.
+.Pp
+All user ID qualifiers must be unique among all entries of
+ACL_USER tag type, and all group IDs must be unique among all entries of
+ACL_GROUP tag type.
+.\"minimal vs. extended ACLs
+.Pp
+ The
+.Fn acl_get_file
+function returns an ACL with zero ACL entries as the default ACL of a
+directory, if the directory is not associated with a default ACL. The
+.Fn acl_set_file
+function also accepts an ACL with zero ACL entries as a valid default ACL for
+directories, denoting that the directory shall not be associated with a
+default ACL. This is equivalent to using the
+.Fn acl_delete_def_file
+function.
+.Sh CORRESPONDENCE BETWEEN ACL ENTRIES AND FILE PERMISSION BITS
+The permissions defined by ACLs are a superset of the permissions
+specified by the file permission bits.
+.Pp
+There is a correspondence between the file owner, group, and other
+permissions and specific ACL entries: the owner permissions correspond
+to the permissions of the ACL_USER_OBJ entry. If the ACL has an ACL_MASK
+entry, the group permissions correspond to the permissions of the
+ACL_MASK entry. Otherwise, if the ACL has no ACL_MASK entry, the group
+permissions correspond to the permissions of the ACL_GROUP_OBJ entry.
+The other permissions correspond to the permissions of the ACL_OTHER_OBJ
+entry.
+.Pp
+The file owner, group, and other permissions always match the
+permissions of the corresponding ACL entry. Modification of the file
+permission bits results in the modification of the associated ACL
+entries, and modification of these ACL entries results in the
+modification of the file permission bits.
+.Sh OBJECT CREATION AND DEFAULT ACLs
+The access ACL of a file object is initialized when the object is
+created with any of the
+.Fn creat ,
+.Fn mkdir ,
+.Fn mknod ,
+.Fn mkfifo ,
+or
+.Fn open
+functions. If a default ACL is associated with a directory, the
+.Va mode
+parameter to the functions creating file objects and the default ACL of
+the directory are used to determine the ACL of the new object:
+.Bl -enum
+.It
+The new object inherits the default ACL of the containing directory
+as its access ACL.
+.It
+The access ACL entries corresponding to the file permission bits are
+modified so that they contain no permissions that are not
+contained in the permissions specified by the
+.Va mode
+parameter.
+.El
+.Pp
+If no default ACL is associated with a directory, the
+.Va mode
+parameter to the functions creating file objects and the file creation
+mask (see
+.Xr umask 2 )
+are used to determine the ACL of the new object:
+.Bl -enum
+.It
+The new object is assigned an access ACL containing entries of tag types
+ACL_USER_OBJ, ACL_GROUP_OBJ, and ACL_OTHER. The permissions of these
+entries are set to the permissions specified by the file creation mask.
+.It
+The access ACL entries corresponding to the file permission bits are
+modified so that they contain no permissions that are not
+contained in the permissions specified by the
+.Va mode
+parameter.
+.El
+.Sh ACCESS CHECK ALGORITHM
+A process may request read, write, or execute/search access to a file object
+protected by an ACL. The access check algorithm determines whether access to
+the object will be granted.
+.Bl -enum
+.It
+.Sy If
+the effective user ID of the process matches the user ID of the file object owner,
+.Sy then
+.Pp
+.in +4
+.Bd -filled
+.Sy if
+the ACL_USER_OBJ entry contains the requested permissions, access is granted,
+.Pp
+.Sy else
+access is denied.
+.in -4
+.Ed
+.It
+.Sy "else if"
+the effective user ID of the process matches the qualifier of any entry
+of type ACL_USER,
+.Sy then
+.Pp
+.in +4
+.Bd -filled
+.Sy if
+the matching ACL_USER entry and the ACL_MASK entry contain the requested
+permissions, access is granted,
+.Pp
+.Sy else
+access is denied.
+.in -4
+.Ed
+.It
+.Sy else if
+the effective group ID or any of the supplementary group IDs of the process
+match the file group or the qualifier of any entry of type ACL_GROUP,
+.Sy then
+.Pp
+.in +4
+.Bd -filled
+.Sy if
+the ACL contains an ACL_MASK entry,
+.Sy then
+.in +4
+.Bd -filled
+.Sy if
+the ACL_MASK entry and any of the matching ACL_GROUP_OBJ or ACL_GROUP entries
+contain
+the requested permissions, access is granted,
+.Pp
+.Sy else
+access is denied.
+.Pp
+.in -4
+.Ed
+.Sy else
+(note that there can be no ACL_GROUP entries without an ACL_MASK entry)
+.in +4
+.Bd -filled
+.Sy if
+the ACL_GROUP_OBJ entry contains the requested permissions,
+access is granted,
+.Ed
+.Pp
+.Sy else
+access is denied.
+.Pp
+.in -4
+.Ed
+.It
+.Sy else if
+the ACL_OTHER entry contains the requested permissions, access is granted.
+.It
+.Sy else
+access is denied.
+.El
+.\".It
+.\"Checking whether the requested access modes are granted by the matched entry.
+.\".El
+.Sh ACL TEXT FORMS
+A long and a short text form for representing ACLs is defined. In both forms, ACL entries are represented as three colon separated fields: an ACL entry tag type, an ACL entry qualifier, and the discretionary access permissions. The first field contains one of the following entry tag type keywords:
+.Bl -tag -offset indent -width group.
+.It Li user
+A
+.Li user
+ACL entry specifies the access granted to either the file owner (entry tag
+type ACL_USER_OBJ) or a specified user (entry tag type ACL_USER).
+.It Li group
+A
+.Li group
+ACL entry specifies the access granted to either the file group (entry tag
+type ACL_GROUP_OBJ) or a specified group (entry tag type ACL_GROUP).
+.It Li mask
+A
+.Li mask
+ACL entry specifies the maximum access which can be granted by any ACL
+entry except the
+.Li user
+entry for the file owner and the
+.Li other
+entry (entry tag type ACL_MASK).
+.It Li other
+An other ACL entry specifies the access granted to any process that does
+not match any
+.Li user
+or
+.Li group
+ACL entries (entry tag type ACL_OTHER).
+.El
+.Pp
+The second field contains the user or group identifier of the user or
+group associated with the ACL entry for entries of entry tag type ACL_USER
+or ACL_GROUP, and is empty for all other entries. A user identifier can
+be a user name or a user ID number in decimal form. A group identifier can
+be a group name or a group ID number in decimal form.
+.Pp
+The third field contains the discretionary access permissions. The read,
+write and search/execute permissions are represented by the
+.Li r ,
+.Li w ,
+and
+.Li x
+characters, in this order. Each of these characters is replaced by the
+.Li \-
+character to denote that a permission is absent in the ACL entry.
+When converting from the text form to the internal representation,
+permissions that are absent need not be specified.
+.Pp
+White space is permitted at the beginning and end of each ACL entry, and
+immediately before and after a field separator (the colon character).
+.Ss LONG TEXT FORM
+The long text form contains one ACL entry per line. In addition, a
+number sign
+.No ( Li # )
+may start a comment that extends until the end of the line. If an
+ACL_USER, ACL_GROUP_OBJ or ACL_GROUP ACL entry contains permissions that
+are not also contained in the ACL_MASK entry, the entry is followed by a
+number sign, the string \(lqeffective:\(rq, and the effective access
+permissions defined by that entry. This is an example of the long text
+form:
+.Bd -literal -offset indent
+user::rw-
+user:lisa:rw- #effective:r--
+group::r--
+group:toolies:rw- #effective:r--
+mask::r--
+other::r--
+.Ed
+.Ss SHORT TEXT FORM
+The short text form is a sequence of ACL entries separated by commas,
+and is used for input. Comments are not supported. Entry tag type
+keywords may either appear in their full unabbreviated form, or in their
+single letter abbreviated form. The abbreviation for
+.Li user
+is
+.Li u ,
+the abbreviation for
+.Li group
+is
+.Li g ,
+the abbreviation for
+.Li mask
+is
+.Li m ,
+and the abbreviation for
+.Li other
+is
+.Li o .
+The permissions may contain at most one each of the following characters
+in any order:
+.Li r ,
+.Li w ,
+.Li x .
+These are examples of the short text form:
+.Bd -literal -offset indent
+u::rw-,u:lisa:rw-,g::r--,g:toolies:rw-,m::r--,o::r--
+g:toolies:rw,u:lisa:rw,u::wr,g::r,o::r,m::r
+.Ed
+.Sh RATIONALE
+IEEE 1003.1e draft 17 defines Access Control Lists that include entries
+of tag type ACL_MASK, and defines a mapping between file permission bits
+that is not constant. The standard working group defined this relatively
+complex interface in order to ensure that applications that are compliant
+with IEEE 1003.1 (\(lqPOSIX.1\(rq) will still function as expected on
+systems with ACLs. The IEEE 1003.1e draft 17 contains the rationale for
+choosing this interface in section B.23.
+.Sh CHANGES TO THE FILE UTILITIES
+On a system that supports ACLs, the file utilities
+.Xr ls 1 ,
+.Xr cp 1 ,
+and
+.Xr mv 1
+change their behavior in the following way:
+.Bl -bullet
+.It
+For files that have a default ACL or an access ACL that contains more than
+the three required ACL entries, the
+.Xr ls 1
+utility in the long form produced by
+.Ic "ls \-l"
+displays a plus sign
+.No ( Li + )
+after the permission string.
+.It
+If the
+.Fl p
+flag is specified, the
+.Xr cp 1
+utility also preserves ACLs.
+If this is not possible, a warning is produced.
+.It
+ The
+.Xr mv 1
+utility always preserves ACLs. If this is not possible, a warning is produced.
+.El
+.Pp
+The effect of the
+.Xr chmod 1
+utility, and of the
+.Xr chmod 2
+system call, on the access ACL is described in
+.Sx "CORRESPONDENCE BETWEEN ACL ENTRIES AND FILE PERMISSION BITS" .
+.Sh STANDARDS
+The IEEE 1003.1e draft 17 (\(lqPOSIX.1e\(rq) document describes several
+security extensions to the IEEE 1003.1 standard. While the work on
+1003.1e has been abandoned, many UNIX style systems implement parts of
+POSIX.1e draft 17, or of earlier drafts.
+.Pp
+Linux Access Control Lists implement the full set of functions and
+utilities defined for Access Control Lists in POSIX.1e, and several
+extensions. The implementation is fully compliant with POSIX.1e draft
+17; extensions are marked as such.
+The Access Control List manipulation functions are defined in
+the ACL library (libacl, \-lacl). The POSIX compliant interfaces are
+declared in the
+.Li <sys/acl.h>
+header. Linux-specific extensions to these functions are declared in the
+.Li <acl/libacl.h>
+header.
+.Sh SEE ALSO
+.Xr chmod 1 ,
+.Xr creat 2 ,
+.Xr getfacl 1 ,
+.Xr ls 1 ,
+.Xr mkdir 2 ,
+.Xr mkfifo 2 ,
+.Xr mknod 2 ,
+.Xr open 2 ,
+.Xr setfacl 1 ,
+.Xr stat 2 ,
+.Xr umask 1
+.Ss POSIX 1003.1e DRAFT 17
+.Xr "http://www.guug.de/~winni/posix.1e/download.html"
+.Ss POSIX 1003.1e FUNCTIONS BY CATEGORY
+.Bl -tag -width "MMM"
+.It Sy ACL storage management
+.Xr acl_dup 3 ,
+.Xr acl_free 3 ,
+.Xr acl_init 3
+.It Sy ACL entry manipulation
+.Xr acl_copy_entry 3 ,
+.Xr acl_create_entry 3 ,
+.Xr acl_delete_entry 3 ,
+.Xr acl_get_entry 3 ,
+.Xr acl_valid 3
+.Pp
+.Xr acl_add_perm 3 ,
+.Xr acl_calc_mask 3 ,
+.Xr acl_clear_perms 3 ,
+.Xr acl_delete_perm 3 ,
+.Xr acl_get_permset 3 ,
+.Xr acl_set_permset 3
+.Pp
+.Xr acl_get_qualifier 3 ,
+.Xr acl_get_tag_type 3 ,
+.Xr acl_set_qualifier 3 ,
+.Xr acl_set_tag_type 3
+.It Sy ACL manipulation on an object
+.Xr acl_delete_def_file 3 ,
+.Xr acl_get_fd 3 ,
+.Xr acl_get_file 3 ,
+.Xr acl_set_fd 3 ,
+.Xr acl_set_file 3
+.It Sy ACL format translation
+.Xr acl_copy_entry 3 ,
+.Xr acl_copy_ext 3 ,
+.Xr acl_from_text 3 ,
+.Xr acl_to_text 3 ,
+.Xr acl_size 3
+.El
+.Ss POSIX 1003.1e FUNCTIONS BY AVAILABILITY
+The first group of functions is supported on most systems with POSIX-like
+access control lists, while the second group is supported on fewer systems.
+For applications that will be ported the second group is best avoided.
+.Pp
+.Xr acl_delete_def_file 3 ,
+.Xr acl_dup 3 ,
+.Xr acl_free 3 ,
+.Xr acl_from_text 3 ,
+.Xr acl_get_fd 3 ,
+.Xr acl_get_file 3 ,
+.Xr acl_init 3 ,
+.Xr acl_set_fd 3 ,
+.Xr acl_set_file 3 ,
+.Xr acl_to_text 3 ,
+.Xr acl_valid 3
+.Pp
+.Xr acl_add_perm 3 ,
+.Xr acl_calc_mask 3 ,
+.Xr acl_clear_perms 3 ,
+.Xr acl_copy_entry 3 ,
+.Xr acl_copy_ext 3 ,
+.Xr acl_copy_int 3 ,
+.Xr acl_create_entry 3 ,
+.Xr acl_delete_entry 3 ,
+.Xr acl_delete_perm 3 ,
+.Xr acl_get_entry 3 ,
+.Xr acl_get_permset 3 ,
+.Xr acl_get_qualifier 3 ,
+.Xr acl_get_tag_type 3 ,
+.Xr acl_set_permset 3 ,
+.Xr acl_set_qualifier 3 ,
+.Xr acl_set_tag_type 3 ,
+.Xr acl_size 3
+.Ss LINUX EXTENSIONS
+These non-portable extensions are available on Linux systems.
+.Pp
+.Xr acl_check 3 ,
+.Xr acl_cmp 3 ,
+.Xr acl_entries 3 ,
+.Xr acl_equiv_mode 3 ,
+.Xr acl_error 3 ,
+.Xr acl_extended_fd 3 ,
+.Xr acl_extended_file 3 ,
+.Xr acl_from_mode 3 ,
+.Xr acl_get_perm 3 ,
+.Xr acl_to_any_text 3
+.Sh AUTHOR
+Andreas Gruenbacher, <a.gruenbacher@bestbits.at>
diff --git a/po/Makefile b/po/Makefile
new file mode 100644
index 0000000..7cd5b61
--- /dev/null
+++ b/po/Makefile
@@ -0,0 +1,42 @@
+#
+# Copyright (c) 2001-2002 Silicon Graphics, Inc. All Rights Reserved.
+#
+# 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 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, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+
+TOPDIR = ..
+include $(TOPDIR)/include/builddefs
+
+POTHEAD = $(PKG_NAME).pot
+LINGUAS ?= de es fr gl pl sv
+LSRCFILES = $(LINGUAS:%=%.po) $(POTHEAD)
+LDIRT = $(POTHEAD)
+
+XGETTEXTFILES = $(TOPDIR)/chacl/chacl.c \
+ $(TOPDIR)/setfacl/do_set.c \
+ $(TOPDIR)/setfacl/setfacl.c \
+ $(TOPDIR)/getfacl/getfacl.c \
+ $(TOPDIR)/libacl/acl_error.c \
+ $(TOPDIR)/libacl/perm_copy_fd.c \
+ $(TOPDIR)/libacl/perm_copy_file.c
+
+default: $(POTHEAD) $(LINGUAS:%=%.mo)
+
+include $(BUILDRULES)
+
+install: default
+ $(INSTALL_LINGUAS)
+
+install-dev install-lib:
diff --git a/po/de.po b/po/de.po
new file mode 100644
index 0000000..42bf33a
--- /dev/null
+++ b/po/de.po
@@ -0,0 +1,334 @@
+# German translation for ACL utilities
+# Copyright (C) 2000 Free Software Foundation, Inc.
+# Andreas Grünbacher <a.gruenbacher@computer.org>, 2000.
+#
+# 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 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 <http://www.gnu.org/licenses/>.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: acl-2.1.2\n"
+"POT-Creation-Date: 2002-11-22 18:28+0100\n"
+"PO-Revision-Date: 2003-01-23 00:08GMT\n"
+"Last-Translator: Andreas Grünbacher <a.gruenbacher@computer.org>\n"
+"Language-Team: <de@li.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+#: ../chacl/chacl.c:59
+msgid "Usage:\n"
+msgstr "Verwendung:\n"
+
+#: ../chacl/chacl.c:60
+#, c-format
+msgid "\t%s acl pathname...\n"
+msgstr "\t%s acl pfadname...\n"
+
+#: ../chacl/chacl.c:61
+#, c-format
+msgid "\t%s -b acl dacl pathname...\n"
+msgstr "\t%s -b acl dacl pfadname...\n"
+
+#: ../chacl/chacl.c:62
+#, c-format
+msgid "\t%s -d dacl pathname...\n"
+msgstr "\t%s -d dacl pfadname...\n"
+
+#: ../chacl/chacl.c:63
+#, c-format
+msgid "\t%s -R pathname...\n"
+msgstr "\t%s -R pfadname...\n"
+
+#: ../chacl/chacl.c:64
+#, c-format
+msgid "\t%s -D pathname...\n"
+msgstr "\t%s -D pfadname...\n"
+
+#: ../chacl/chacl.c:65
+#, c-format
+msgid "\t%s -B pathname...\n"
+msgstr "\t%s -B pfadname...\n"
+
+#: ../chacl/chacl.c:66
+#, c-format
+msgid "\t%s -l pathname...\t[not IRIX compatible]\n"
+msgstr "\t%s -l pfadname...\t[nicht IRIX-kompatibel]\n"
+
+#: ../chacl/chacl.c:68
+#, c-format
+msgid "\t%s -r pathname...\t[not IRIX compatible]\n"
+msgstr "\t%s -r pfadname...\t[nicht IRIX-kompatibel]\n"
+
+#: ../chacl/chacl.c:154
+#, c-format
+msgid "%s: error removing access acl on \"%s\": %s\n"
+msgstr "%s: Fehler beim Entfernen der Zugriffs-ACL von \"%s\": %s\n"
+
+#: ../chacl/chacl.c:161
+#, c-format
+msgid "%s: error removing default acl on \"%s\": %s\n"
+msgstr "%s: Fehler beim Entfernen der Vorgabe-ACL von \"%s\": %s\n"
+
+#: ../chacl/chacl.c:180 ../chacl/chacl.c:199
+#, c-format
+msgid "%s: access ACL '%s': %s at entry %d\n"
+msgstr "%s: Zugriffs-ACL '%s': %s bei Eintrag %d\n"
+
+#: ../chacl/chacl.c:267
+#, c-format
+msgid "%s: cannot get access ACL on '%s': %s\n"
+msgstr "%s: Kann Zugriffs-ACL von '%s' nicht ermitteln: %s\n"
+
+#: ../chacl/chacl.c:273
+#, c-format
+msgid "%s: cannot get default ACL on '%s': %s\n"
+msgstr "%s: Kann Vorgabe-ACL von '%s' nicht ermitteln: %s\n"
+
+#: ../chacl/chacl.c:279
+#, c-format
+msgid "%s: cannot get access ACL text on '%s': %s\n"
+msgstr "%s: Kann den Text zur Zugriffs-ACL von '%s' nicht ermitteln: %s\n"
+
+#: ../chacl/chacl.c:286
+#, c-format
+msgid "%s: cannot get default ACL text on '%s': %s\n"
+msgstr "%s: Kann den Text zur Vorgabe-ACL von '%s' nicht ermitteln: %s\n"
+
+#: ../chacl/chacl.c:312
+#, c-format
+msgid "%s: cannot set access acl on \"%s\": %s\n"
+msgstr "%s: Kann die Zugriffs-ACL von \"%s\" nicht setzen: %s\n"
+
+#: ../chacl/chacl.c:318
+#, c-format
+msgid "%s: cannot set default acl on \"%s\": %s\n"
+msgstr "%s: Kann die Vorgabe-ACL von \"%s\" nicht setzen: %s\n"
+
+#: ../chacl/chacl.c:336
+#, c-format
+msgid "%s: opendir failed: %s\n"
+msgstr "%s: opendir ist fehlgeschlagen: %s\n"
+
+#: ../chacl/chacl.c:350
+#, c-format
+msgid "%s: malloc failed: %s\n"
+msgstr "%s: malloc ist fehlgeschlagen: %s\n"
+
+#: ../setfacl/do_set.c:404
+#, c-format
+msgid "%s: %s: Malformed access ACL `%s': %s at entry %d\n"
+msgstr "%s: %s: Ungültige Zugriffs-ACL `%s': %s bei Eintrag %d\n"
+
+#: ../setfacl/do_set.c:431
+#, c-format
+msgid "%s: %s: Malformed default ACL `%s': %s at entry %d\n"
+msgstr "%s: %s: Ungültige Vorgabe-ACL `%s': %s bei Eintrag %d\n"
+
+#: ../setfacl/do_set.c:494
+#, c-format
+msgid "%s: %s: Only directories can have default ACLs\n"
+msgstr "%s: %s: Nur Verzeichnisse können Vorgabe-ACLs haben\n"
+
+#: ../setfacl/setfacl.c:140
+#, c-format
+msgid "%s: %s: No filename found in line %d, aborting\n"
+msgstr "%s: %s: Kein Dateiname in Zeile %d gefunden; Abbruch\n"
+
+#: ../setfacl/setfacl.c:144
+#, c-format
+msgid "%s: No filename found in line %d of standard input, aborting\n"
+msgstr "%s: Kein Dateiname in Zeile %d der Standardeingabe gefunden; Abbruch\n"
+
+#: ../setfacl/setfacl.c:165
+#, c-format
+msgid "%s: %s: %s in line %d\n"
+msgstr "%s: %s: %s in Zeile %d\n"
+
+#: ../setfacl/setfacl.c:188
+#, c-format
+msgid "%s: %s: Cannot change owner/group: %s\n"
+msgstr "%s: %s: Kann Besitzer/Gruppe nicht ändern: %s\n"
+
+#: ../setfacl/setfacl.c:226
+#, c-format
+msgid "%s %s -- set file access control lists\n"
+msgstr "%s %s -- Datei-Zugriffskontrollisten (ACLs) ändern\n"
+
+#: ../setfacl/setfacl.c:228 ../setfacl/setfacl.c:674
+#, c-format
+msgid "Usage: %s %s\n"
+msgstr "Verwendung: %s %s\n"
+
+#: ../setfacl/setfacl.c:231
+msgid ""
+" -m, --modify=acl modify the current ACL(s) of file(s)\n"
+" -M, --modify-file=file read ACL entries to modify from file\n"
+" -x, --remove=acl remove entries from the ACL(s) of file(s)\n"
+" -X, --remove-file=file read ACL entries to remove from file\n"
+" -b, --remove-all remove all extended ACL entries\n"
+" -k, --remove-default remove the default ACL\n"
+msgstr ""
+" -m, --modify=acl Verändere die ACL(s) von Datei(en)\n"
+" -M, --modify-file=datei Lies die ACL-Einträge aus datei\n"
+" -x, --remove=acl Entferne Einträge aus ACLs von Datei(en)\n"
+" -X, --remove-file=datei Lies die ACL-Einträge aus datei\n"
+" -b, --remove-all Alle erweiterten ACL-Einträge entfernen\n"
+" -k, --remove-default Vorgabe-ACL entfernen\n"
+
+#: ../setfacl/setfacl.c:240
+msgid ""
+" --set=acl set the ACL of file(s), replacing the current ACL\n"
+" --set-file=file read ACL entries to set from file\n"
+" --mask do recalculate the effective rights mask\n"
+msgstr ""
+" --set=acl Ersetze die ACL von Datei(en)\n"
+" --set-file=datei Lies die ACL-Einträge aus datei\n"
+" --mask Effektive Rechte nicht neu berechnen\n"
+
+#: ../setfacl/setfacl.c:246
+msgid ""
+" -n, --no-mask don't recalculate the effective rights mask\n"
+" -d, --default operations apply to the default ACL\n"
+msgstr ""
+" -n, --no-mask Effektive Rechte nicht neu berechnen\n"
+" -d, --default Bearbeite die Vorgabe-ACL\n"
+
+#: ../setfacl/setfacl.c:251
+msgid ""
+" -R, --recursive recurse into subdirectories\n"
+" -L, --logical logical walk, follow symbolic links\n"
+" -P, --physical physical walk, do not follow symbolic links\n"
+" --restore=file restore ACLs (inverse of `getfacl -R')\n"
+" --test test mode (ACLs are not modified)\n"
+msgstr ""
+" -R, --recursive In Unterverzeichnisse wechseln\n"
+" -L, --logical Symbolischen Links folgen\n"
+" -P, --physical Symbolischen Links nicht folgen\n"
+" --restore=datei ACLs wiederherstellen (Umkehr von `getfacl -R')\n"
+" --test Testmodus (ACLs werden nicht verändert)\n"
+
+#: ../setfacl/setfacl.c:259 ../getfacl/getfacl.c:543
+msgid ""
+" --version print version and exit\n"
+" --help this help text\n"
+msgstr ""
+" --version Die Version ausgeben\n"
+" --help Diese Hilfe\n"
+
+#: ../setfacl/setfacl.c:468
+#, c-format
+msgid "%s: Option -%c incomplete\n"
+msgstr "%s: Option -%c unvollständig\n"
+
+#: ../setfacl/setfacl.c:473
+#, c-format
+msgid "%s: Option -%c: %s near character %d\n"
+msgstr "%s: Option -%c: %s bei Zeichen %d\n"
+
+#: ../setfacl/setfacl.c:558
+#, c-format
+msgid "%s: %s in line %d of file %s\n"
+msgstr "%s: %s in Zeile %d der Datei %s\n"
+
+#: ../setfacl/setfacl.c:566
+#, c-format
+msgid "%s: %s in line %d of standard input\n"
+msgstr "%s: %s in Zeile %d der Standardeingabe\n"
+
+#: ../setfacl/setfacl.c:676 ../getfacl/getfacl.c:749
+#, c-format
+msgid "Try `%s --help' for more information.\n"
+msgstr "Weiterführende Informationen mit `%s --help'.\n"
+
+#: ../getfacl/getfacl.c:449
+#, c-format
+msgid "%s: Removing leading '/' from absolute path names\n"
+msgstr "%s: Entferne führende '/' von absoluten Pfadnamen\n"
+
+#: ../getfacl/getfacl.c:516
+#, c-format
+msgid "%s %s -- get file access control lists\n"
+msgstr "%s %s -- Datei-Zugriffskontrollisten (ACLs) anzeigen\n"
+
+#: ../getfacl/getfacl.c:518 ../getfacl/getfacl.c:747
+#, c-format
+msgid "Usage: %s [-%s] file ...\n"
+msgstr "Aufruf: %s [-%s] datei ...\n"
+
+#: ../getfacl/getfacl.c:524
+msgid " -d, --default display the default access control list\n"
+msgstr " -d, --default Die Vorgabe-ACL ausgeben\n"
+
+#: ../getfacl/getfacl.c:528
+msgid ""
+" --access display the file access control list only\n"
+" -d, --default display the default access control list only\n"
+" --omit-header do not display the comment header\n"
+" --all-effective print all effective rights\n"
+" --no-effective print no effective rights\n"
+" --skip-base skip files that only have the base entries\n"
+" -R, --recursive recurse into subdirectories\n"
+" -L, --logical logical walk, follow symbolic links\n"
+" -P --physical physical walk, do not follow symbolic links\n"
+" --tabular use tabular output format\n"
+" --numeric print numeric user/group identifiers\n"
+" --absolute-names don't strip leading '/' in pathnames\n"
+msgstr ""
+" --access Nur die Zugriffs-ACL ausgeben\n"
+" -d, --default Nur die Vorgabe-ACL ausgeben\n"
+" --omit-header Keine Datei-Kommentare ausgeben\n"
+" --all-effective Alle Effektivrechte-Kommentare ausgeben\n"
+" --no-effective Keine Effektivrechte-Kommentare ausgeben\n"
+" --skip-base Überspringe Dateien mit Basiseinträgen\n"
+" -R, --recursive In Unterverzeichnisse wechseln\n"
+" -L, --logical Symbolische Links verfolgen\n"
+" -P, --physical Symbolische Links nicht verfolgen\n"
+" --tabular Tabellarisches Ausgabeformat verwenden\n"
+" --numeric Numerische Benutzer-/Gruppenkennungen ausgeben\n"
+" --absolute-names Führende '/' in Pfadnamen nicht entfernen\n"
+
+#: ../getfacl/getfacl.c:735
+#, c-format
+msgid "%s: Standard input: %s\n"
+msgstr "%s: Standardeingabe: %s\n"
+
+#: ../libacl/acl_error.c:34
+msgid "Multiple entries of same type"
+msgstr "Mehrere Einträge gleichen Typs"
+
+#: ../libacl/acl_error.c:36
+msgid "Duplicate entries"
+msgstr "Doppelte Einträge"
+
+#: ../libacl/acl_error.c:38
+msgid "Missing or wrong entry"
+msgstr "Fehlender oder falscher Eintrag"
+
+#: ../libacl/acl_error.c:40
+msgid "Invalid entry type"
+msgstr "Ungültiger Eintragstyp"
+
+#: ../libacl/perm_copy_fd.c:122 ../libacl/perm_copy_fd.c:132
+#: ../libacl/perm_copy_fd.c:183 ../libacl/perm_copy_file.c:122
+#: ../libacl/perm_copy_file.c:135 ../libacl/perm_copy_file.c:144
+#: ../libacl/perm_copy_file.c:214
+#, c-format
+msgid "setting permissions for %s"
+msgstr "Setzen der Zugriffsrechte für %s"
+
+#: ../libacl/perm_copy_fd.c:172 ../libacl/perm_copy_file.c:183
+#: ../libacl/perm_copy_file.c:205
+#, c-format
+msgid "preserving permissions for %s"
+msgstr "Erhalten der Zugriffsrechte für %s"
diff --git a/po/es.po b/po/es.po
new file mode 100644
index 0000000..be464d8
--- /dev/null
+++ b/po/es.po
@@ -0,0 +1,355 @@
+# Spanish translation for ACL utilities
+# Copyright (C) 2007 Free Software Foundation, Inc.
+# Antonio Trueba <atrueba@users.sourceforge.net>, 2007.
+#
+# 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 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 <http://www.gnu.org/licenses/>.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: acl-2.2.43.1\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2007-03-16 19:00+0100\n"
+"PO-Revision-Date: 2007-03-16 23:25+0100\n"
+"Last-Translator: Antonio Trueba <atrueba@users.sourceforge.net>\n"
+"Language-Team: Spanish\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=utf-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Poedit-Language: Spanish\n"
+
+#: ../chacl/chacl.c:45
+#, c-format
+msgid "Usage:\n"
+msgstr "Uso:\n"
+
+#: ../chacl/chacl.c:46
+#, c-format
+msgid "\t%s acl pathname...\n"
+msgstr "\t%s nombre de ruta de ACL...\n"
+
+#: ../chacl/chacl.c:47
+#, c-format
+msgid "\t%s -b acl dacl pathname...\n"
+msgstr "\t%s -b nombre de ruta ACL DACL...\n"
+
+#: ../chacl/chacl.c:48
+#, c-format
+msgid "\t%s -d dacl pathname...\n"
+msgstr "\t%s -d nombre de ruta de ACL...\n"
+
+#: ../chacl/chacl.c:49
+#, c-format
+msgid "\t%s -R pathname...\n"
+msgstr "\t%s -R ruta...\n"
+
+#: ../chacl/chacl.c:50
+#, c-format
+msgid "\t%s -D pathname...\n"
+msgstr "\t%s -D ruta...\n"
+
+#: ../chacl/chacl.c:51
+#, c-format
+msgid "\t%s -B pathname...\n"
+msgstr "\t%s -B ruta...\n"
+
+#: ../chacl/chacl.c:52
+#, c-format
+msgid "\t%s -l pathname...\t[not IRIX compatible]\n"
+msgstr "\t%s -l ruta...\t[no compatible con IRIX]\n"
+
+#: ../chacl/chacl.c:54
+#, c-format
+msgid "\t%s -r pathname...\t[not IRIX compatible]\n"
+msgstr "\t%s -r ruta...\t[no compatible con IRIX]\n"
+
+#: ../chacl/chacl.c:145
+#, c-format
+msgid "%s: error removing access acl on \"%s\": %s\n"
+msgstr "%s: error borrando ACL de acceso en \"%s\": %s\n"
+
+#: ../chacl/chacl.c:152
+#, c-format
+msgid "%s: error removing default acl on \"%s\": %s\n"
+msgstr "%s: error borrando ACL predeterminado en \"%s\": %s\n"
+
+#: ../chacl/chacl.c:171
+#: ../chacl/chacl.c:190
+#, c-format
+msgid "%s: access ACL '%s': %s at entry %d\n"
+msgstr "%s: ACL de acceso '%s': %s en posición %d\n"
+
+#: ../chacl/chacl.c:258
+#, c-format
+msgid "%s: cannot get access ACL on '%s': %s\n"
+msgstr "%s: no se pudo obtener ACL de acceso en '%s': %s\n"
+
+#: ../chacl/chacl.c:264
+#, c-format
+msgid "%s: cannot get default ACL on '%s': %s\n"
+msgstr "%s: no se pudo obtener ACL predeterminado en '%s': %s\n"
+
+#: ../chacl/chacl.c:270
+#, c-format
+msgid "%s: cannot get access ACL text on '%s': %s\n"
+msgstr "%s: no se pudo obtener texto ACL de acceso en '%s': %s\n"
+
+#: ../chacl/chacl.c:277
+#, c-format
+msgid "%s: cannot get default ACL text on '%s': %s\n"
+msgstr "%s: no se pudo obtener texto de ACL predeterminado en '%s': %s\n"
+
+#: ../chacl/chacl.c:303
+#, c-format
+msgid "%s: cannot set access acl on \"%s\": %s\n"
+msgstr "%s: no se pudo establecer ACL de acceso en \"%s\": %s\n"
+
+#: ../chacl/chacl.c:309
+#, c-format
+msgid "%s: cannot set default acl on \"%s\": %s\n"
+msgstr "%s: no se pudo establecer ACL predeterminado a \"%s\": %s\n"
+
+#: ../chacl/chacl.c:327
+#, c-format
+msgid "%s: opendir failed: %s\n"
+msgstr "%s: falló la apertura: %s\n"
+
+#: ../chacl/chacl.c:341
+#, c-format
+msgid "%s: malloc failed: %s\n"
+msgstr "%s: falló la asignación de memoria: %s\n"
+
+#: ../setfacl/do_set.c:391
+#, c-format
+msgid "%s: %s: Malformed access ACL `%s': %s at entry %d\n"
+msgstr "%s: %s: ACL incorrecto `%s': %s en posición %d\n"
+
+#: ../setfacl/do_set.c:418
+#, c-format
+msgid "%s: %s: Malformed default ACL `%s': %s at entry %d\n"
+msgstr "%s: %s: ACL predeterminado incorrecto `%s': %s en posición %d\n"
+
+#: ../setfacl/do_set.c:480
+#, c-format
+msgid "%s: %s: Only directories can have default ACLs\n"
+msgstr "%s: %s: Sólo los directorios pueden tener ACLs predeterminados\n"
+
+#: ../setfacl/setfacl.c:151
+#, c-format
+msgid "%s: %s: No filename found in line %d, aborting\n"
+msgstr "%s: %s: No se encontró nombre de archivo en línea %d, abortando\n"
+
+#: ../setfacl/setfacl.c:156
+#, c-format
+msgid "%s: No filename found in line %d of standard input, aborting\n"
+msgstr "%s: %s: No se encontró nombre de archivo en línea %d de entrada estándar, abortando\n"
+
+#: ../setfacl/setfacl.c:176
+#, c-format
+msgid "%s: %s: %s in line %d\n"
+msgstr "%s: %s: %s en línea %d\n"
+
+#: ../setfacl/setfacl.c:200
+#, c-format
+msgid "%s: %s: Cannot change owner/group: %s\n"
+msgstr "%s: %s: No se pudo cambiar el propietario/grupo: %s\n"
+
+#: ../setfacl/setfacl.c:240
+#, c-format
+msgid "%s %s -- set file access control lists\n"
+msgstr "%s %s -- establecer listas de control de acceso a archivo\n"
+
+#: ../setfacl/setfacl.c:242
+#: ../setfacl/setfacl.c:692
+#, c-format
+msgid "Usage: %s %s\n"
+msgstr "Uso: %s %s\n"
+
+#: ../setfacl/setfacl.c:245
+#, c-format
+msgid ""
+" -m, --modify=acl modify the current ACL(s) of file(s)\n"
+" -M, --modify-file=file read ACL entries to modify from file\n"
+" -x, --remove=acl remove entries from the ACL(s) of file(s)\n"
+" -X, --remove-file=file read ACL entries to remove from file\n"
+" -b, --remove-all remove all extended ACL entries\n"
+" -k, --remove-default remove the default ACL\n"
+msgstr ""
+" -m, --modify=acl modificar ACL actual(es) de archivo(s)\n"
+" -M, --modify-file=arch leer entradas ACL desde \"arch\"\n"
+" -x, --remove=acl eliminar entradas desde ACL(s) de archivo(s)\n"
+" -X, --remove-file=arch leer entradas de ACL a borrar desde \"arch\"\n"
+" -b, --remove-all eliminar todas las entradas ACL extendidas\n"
+" -k, --remove-default eliminar el ACL predeterminado\n"
+
+#: ../setfacl/setfacl.c:254
+#, c-format
+msgid ""
+" --set=acl set the ACL of file(s), replacing the current ACL\n"
+" --set-file=file read ACL entries to set from file\n"
+" --mask do recalculate the effective rights mask\n"
+msgstr ""
+" --set=acl establecer ACL(s) de archivo(s), reemplazando el actual\n"
+" --set-file=arch leer entradas ACL a establecer desde \"arch\"\n"
+" --mask recalcular la máscara de permisos efectivos\n"
+
+#: ../setfacl/setfacl.c:260
+#, c-format
+msgid ""
+" -n, --no-mask don't recalculate the effective rights mask\n"
+" -d, --default operations apply to the default ACL\n"
+msgstr ""
+" -n, --no-mask no recalcular la máscara de derechos efectivos\n"
+" -d, --default las operaciones afectal al ACL predeterminado\n"
+
+#: ../setfacl/setfacl.c:265
+#, c-format
+msgid ""
+" -R, --recursive recurse into subdirectories\n"
+" -L, --logical logical walk, follow symbolic links\n"
+" -P, --physical physical walk, do not follow symbolic links\n"
+" --restore=file restore ACLs (inverse of `getfacl -R')\n"
+" --test test mode (ACLs are not modified)\n"
+msgstr ""
+" -R, --recursive recorrer subdirectorios recursivamente\n"
+" -L, --logical recorrido lógico, siguiendo enlaces simbólicos\n"
+" -P, --physical recorrido físico, sin seguir enlaces simbólicos\n"
+" --restore=file restaurar ACLs (inverso de `getfacl -R')\n"
+" --test modo de prueba (los ACLs no se modifican)\n"
+
+#: ../setfacl/setfacl.c:273
+#: ../getfacl/getfacl.c:559
+#, c-format
+msgid ""
+" --version print version and exit\n"
+" --help this help text\n"
+msgstr ""
+" --version escribir versión y salir\n"
+" --help este texto de ayuda\n"
+
+#: ../setfacl/setfacl.c:358
+#: ../getfacl/getfacl.c:768
+#, c-format
+msgid "%s: Standard input: %s\n"
+msgstr "%s: Entrada estándar: %s\n"
+
+#: ../setfacl/setfacl.c:494
+#, c-format
+msgid "%s: Option -%c incomplete\n"
+msgstr "%s: Opción -%c incompleta\n"
+
+#: ../setfacl/setfacl.c:499
+#, c-format
+msgid "%s: Option -%c: %s near character %d\n"
+msgstr "%s: Opción -%c: %s cerca del carácter %d\n"
+
+#: ../setfacl/setfacl.c:575
+#, c-format
+msgid "%s: %s in line %d of file %s\n"
+msgstr "%s: %s en línea %d de archivo %s\n"
+
+#: ../setfacl/setfacl.c:583
+#, c-format
+msgid "%s: %s in line %d of standard input\n"
+msgstr "%s: %s en línea %d de entrada estándar\n"
+
+#: ../setfacl/setfacl.c:694
+#: ../getfacl/getfacl.c:782
+#, c-format
+msgid "Try `%s --help' for more information.\n"
+msgstr "Escriba `%s --help' para más información.\n"
+
+#: ../getfacl/getfacl.c:463
+#, c-format
+msgid "%s: Removing leading '/' from absolute path names\n"
+msgstr "%s: Eliminando '/' inicial en nombres de ruta absolutos\n"
+
+#: ../getfacl/getfacl.c:532
+#, c-format
+msgid "%s %s -- get file access control lists\n"
+msgstr "%s %s -- obtener listas de control de acceso a archivo\n"
+
+#: ../getfacl/getfacl.c:534
+#: ../getfacl/getfacl.c:780
+#, c-format
+msgid "Usage: %s [-%s] file ...\n"
+msgstr "Uso: %s [-%s] archivo ...\n"
+
+#: ../getfacl/getfacl.c:540
+#, c-format
+msgid " -d, --default display the default access control list\n"
+msgstr " -d, --default mostrar la lista de control de acceso predeterminada\n"
+
+#: ../getfacl/getfacl.c:544
+#, c-format
+msgid ""
+" --access display the file access control list only\n"
+" -d, --default display the default access control list only\n"
+" --omit-header do not display the comment header\n"
+" --all-effective print all effective rights\n"
+" --no-effective print no effective rights\n"
+" --skip-base skip files that only have the base entries\n"
+" -R, --recursive recurse into subdirectories\n"
+" -L, --logical logical walk, follow symbolic links\n"
+" -P --physical physical walk, do not follow symbolic links\n"
+" --tabular use tabular output format\n"
+" --numeric print numeric user/group identifiers\n"
+" --absolute-names don't strip leading '/' in pathnames\n"
+msgstr ""
+" --access sólo mostrar la lista de control de acceso a fichero\n"
+" -d, --default sólo mostrar la lista de acceso predeterminada\n"
+" --omit-header no mostrar el encabezado de comentarios\n"
+" --all-effective mostrar todos los permisos efectivos\n"
+" --no-effective mostrar los permisos no efectivos\n"
+" --skip-base ignorar archivos que sólo tienen las entradas básicas\n"
+" -R, --recursive descender recursivamente en los subdirectorios\n"
+" -L, --logical recorrido lógico, siguiendo enlaces simbólicos\n"
+" -P --physical recorrido físico, sin seguir enlaces simbólicos\n"
+" --tabular usar formato de salida tabular\n"
+" --numeric mostrar identificadores numéricos de usuario/grupo\n"
+" --absolute-names no eliminar '/' inicial en nombres de ruta\n"
+
+#: ../libacl/acl_error.c:34
+msgid "Multiple entries of same type"
+msgstr "Múltiples entradas del mismo tipo"
+
+#: ../libacl/acl_error.c:36
+msgid "Duplicate entries"
+msgstr "Entradas duplicadas"
+
+#: ../libacl/acl_error.c:38
+msgid "Missing or wrong entry"
+msgstr "Falta una posición o es errónea"
+
+#: ../libacl/acl_error.c:40
+msgid "Invalid entry type"
+msgstr "Tipo de posición inválido"
+
+#: ../libacl/perm_copy_fd.c:124
+#: ../libacl/perm_copy_fd.c:136
+#: ../libacl/perm_copy_fd.c:198
+#: ../libacl/perm_copy_file.c:124
+#: ../libacl/perm_copy_file.c:139
+#: ../libacl/perm_copy_file.c:150
+#: ../libacl/perm_copy_file.c:235
+#, c-format
+msgid "setting permissions for %s"
+msgstr "estableciendo permisos a %s"
+
+#: ../libacl/perm_copy_fd.c:186
+#: ../libacl/perm_copy_file.c:199
+#: ../libacl/perm_copy_file.c:224
+#, c-format
+msgid "preserving permissions for %s"
+msgstr "manteniendo permisos a %s"
+
diff --git a/po/fr.po b/po/fr.po
new file mode 100644
index 0000000..15ac1ef
--- /dev/null
+++ b/po/fr.po
@@ -0,0 +1,348 @@
+# Français translation of Acl.
+# Copyright (C) 2005 Free Software Foundation, Inc.
+# Sylvain Archenault <sylvain.archenault@laposte.net>, 2005.
+#
+# 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 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 <http://www.gnu.org/licenses/>.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: Acl\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2005-09-20 21:50+0200\n"
+"PO-Revision-Date: 2005-09-24 15:46+0200\n"
+"Last-Translator: Sylvain Archenault <sylvain.archenault@laposte.net>\n"
+"Language-Team: french <debian-l10n-french@lists.debian.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=iso-8859-15\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: "
+
+#: ../chacl/chacl.c:59
+msgid "Usage:\n"
+msgstr "Utilisation :\n"
+
+#: ../chacl/chacl.c:60
+#, c-format
+msgid "\t%s acl pathname...\n"
+msgstr "\t%s répertoire acl...\n"
+
+#: ../chacl/chacl.c:61
+#, c-format
+msgid "\t%s -b acl dacl pathname...\n"
+msgstr "\t%s -b acl dacl répertoire...\n"
+
+#: ../chacl/chacl.c:62
+#, c-format
+msgid "\t%s -d dacl pathname...\n"
+msgstr "\t%s -d dacl répertoire...\n"
+
+#: ../chacl/chacl.c:63
+#, c-format
+msgid "\t%s -R pathname...\n"
+msgstr "\t%s -R répertoire...\n"
+
+#: ../chacl/chacl.c:64
+#, c-format
+msgid "\t%s -D pathname...\n"
+msgstr "\t%s -D répertoire...\n"
+
+#: ../chacl/chacl.c:65
+#, c-format
+msgid "\t%s -B pathname...\n"
+msgstr "\t%s -B répertoire...\n"
+
+#: ../chacl/chacl.c:66
+#, c-format
+msgid "\t%s -l pathname...\t[not IRIX compatible]\n"
+msgstr "\t%s -l répertoire...\t[pas compatible IRIX]\n"
+
+#: ../chacl/chacl.c:68
+#, c-format
+msgid "\t%s -r pathname...\t[not IRIX compatible]\n"
+msgstr "\t%s -r répertoire...\t[pas compatible IRIX]\n"
+
+#: ../chacl/chacl.c:159
+#, c-format
+msgid "%s: error removing access acl on \"%s\": %s\n"
+msgstr "%s : erreur de suppression de l'accès acl de « %s » : %s\n"
+
+#: ../chacl/chacl.c:166
+#, c-format
+msgid "%s: error removing default acl on \"%s\": %s\n"
+msgstr ""
+"%s : erreur de suppression de l'accès acl par défaut de « %s » : %s\n"
+
+#: ../chacl/chacl.c:185 ../chacl/chacl.c:204
+#, c-format
+msgid "%s: access ACL '%s': %s at entry %d\n"
+msgstr "%s : accès ACL « %s » : %s à l'entrée %d\n"
+
+#: ../chacl/chacl.c:272
+#, c-format
+msgid "%s: cannot get access ACL on '%s': %s\n"
+msgstr "%s : impossible d'obtenir l'accès ACL de « %s » : %s\n"
+
+#: ../chacl/chacl.c:278
+#, c-format
+msgid "%s: cannot get default ACL on '%s': %s\n"
+msgstr "%s : impossible d'obtenir l'accès ACL par défaut de « %s » : %s\n"
+
+#: ../chacl/chacl.c:284
+#, c-format
+msgid "%s: cannot get access ACL text on '%s': %s\n"
+msgstr "%s : impossible d'obtenir l'accès texte ACL de « %s » : %s\n"
+
+#: ../chacl/chacl.c:291
+#, c-format
+msgid "%s: cannot get default ACL text on '%s': %s\n"
+msgstr "%s : impossible d'obtenir le texte ACL par défaut de « %s » : %s\n"
+
+#: ../chacl/chacl.c:317
+#, c-format
+msgid "%s: cannot set access acl on \"%s\": %s\n"
+msgstr "%s : impossible de modifier l'accès ACL de « %s »: %s\n"
+
+#: ../chacl/chacl.c:323
+#, c-format
+msgid "%s: cannot set default acl on \"%s\": %s\n"
+msgstr "%s : impossible de définir l'ACL par défaut de « %s » : %s\n"
+
+#: ../chacl/chacl.c:341
+#, c-format
+msgid "%s: opendir failed: %s\n"
+msgstr "%s : échec d'opendir : %s\n"
+
+#: ../chacl/chacl.c:355
+#, c-format
+msgid "%s: malloc failed: %s\n"
+msgstr "%s : échec de malloc : %s\n"
+
+#: ../setfacl/do_set.c:404
+#, c-format
+msgid "%s: %s: Malformed access ACL `%s': %s at entry %d\n"
+msgstr "%s : %s : ACL d'accès mal formulé « %s » : %s à l'entrée %d\n"
+
+#: ../setfacl/do_set.c:431
+#, c-format
+msgid "%s: %s: Malformed default ACL `%s': %s at entry %d\n"
+msgstr ""
+"%s : %s : entrée ACL par défaut mal formulée « %s » : %s à l'entrée·%d\n"
+
+#: ../setfacl/do_set.c:494
+#, c-format
+msgid "%s: %s: Only directories can have default ACLs\n"
+msgstr ""
+"%s : %s : seuls les répertoires peuvent avoir une entrée ACL par défaut\n"
+
+#: ../setfacl/setfacl.c:151
+#, c-format
+msgid "%s: %s: No filename found in line %d, aborting\n"
+msgstr "%s : %s : nom de fichier manquant à la ligne %d, annulation\n"
+
+#: ../setfacl/setfacl.c:156
+#, c-format
+msgid "%s: No filename found in line %d of standard input, aborting\n"
+msgstr ""
+"%s : nom de fichier manquant à la ligne %d de la sortie standard, "
+"annulation\n"
+
+#: ../setfacl/setfacl.c:177
+#, c-format
+msgid "%s: %s: %s in line %d\n"
+msgstr "%s : %s : %s à la ligne %d\n"
+
+#: ../setfacl/setfacl.c:201
+#, c-format
+msgid "%s: %s: Cannot change owner/group: %s\n"
+msgstr "%s : %s : impossible de changer de propriétaire/groupe : %s\n"
+
+#: ../setfacl/setfacl.c:241
+#, c-format
+msgid "%s %s -- set file access control lists\n"
+msgstr ""
+"%s %s -- définir les listes de contrôle d'accès des fichiers (ACL)\n"
+
+#: ../setfacl/setfacl.c:243 ../setfacl/setfacl.c:701
+#, c-format
+msgid "Usage: %s %s\n"
+msgstr "Utilisation : %s %s\n"
+
+#: ../setfacl/setfacl.c:246
+msgid ""
+" -m, --modify=acl modify the current ACL(s) of file(s)\n"
+" -M, --modify-file=file read ACL entries to modify from file\n"
+" -x, --remove=acl remove entries from the ACL(s) of file(s)\n"
+" -X, --remove-file=file read ACL entries to remove from file\n"
+" -b, --remove-all remove all extended ACL entries\n"
+" -k, --remove-default remove the default ACL\n"
+msgstr ""
+" -m, --modify=acl modifier l'ACL(s) actuel de fichier(s)\n"
+" -M, --modify-file=fichier lire l'entrée ACL à modifier du fichier\n"
+" -x, --remove=acl supprimer les entrées de l'ACL des fichier\n"
+" -X, --remove-file=fichier lire les entrées ACL à supprimer du fichier\n"
+" -b, --remove-all supprimer toutes les entrées ACL étendues\n"
+" -k, --remove-default supprimer l'ACL par défaut\n"
+
+#: ../setfacl/setfacl.c:255
+msgid ""
+" --set=acl set the ACL of file(s), replacing the current ACL\n"
+" --set-file=fichier read ACL entries to set from file\n"
+" --mask do recalculate the effective rights mask\n"
+msgstr ""
+" --set=acl définir l'ACL des fichier(s) en remplaçant l'ACL\n"
+" actuel\n"
+" --set-file=fichier lire les entrées ACL à modifier du fichier\n"
+" --mask recalculer les masques des droits en vigueur\n"
+
+#: ../setfacl/setfacl.c:261
+msgid ""
+" -n, --no-mask don't recalculate the effective rights mask\n"
+" -d, --default operations apply to the default ACL\n"
+msgstr ""
+" -n, --no-mask ne pas recalculer les masques de droits en vigueur\n"
+" -d, --default les opérations s'appliquent à l'ACL par défaut\n"
+
+#: ../setfacl/setfacl.c:266
+msgid ""
+" -R, --recursive recurse into subdirectories\n"
+" -L, --logical logical walk, follow symbolic links\n"
+" -P, --physical physical walk, do not follow symbolic links\n"
+" --restore=file restore ACLs (inverse of `getfacl -R')\n"
+" --test test mode (ACLs are not modified)\n"
+msgstr ""
+" -R, --recursive parcourir récursivement les sous-répertoires\n"
+" -L, --logical suivre les liens symboliques\n"
+" -P, --physical ne pas suivre les liens symboliques\n"
+" --restore=fichier restaurer les ACL (inverse de « getfacl -R »)\n"
+" --test mode test (les ACL ne sont pas modifiés)\n"
+
+#: ../setfacl/setfacl.c:274 ../getfacl/getfacl.c:558
+msgid ""
+" --version print version and exit\n"
+" --help this help text\n"
+msgstr ""
+" --version afficher la version et quitter\n"
+" --help afficher ce message d'aide\n"
+
+#: ../setfacl/setfacl.c:493
+#, c-format
+msgid "%s: Option -%c incomplete\n"
+msgstr "%s : Option -%c incomplète\n"
+
+#: ../setfacl/setfacl.c:498
+#, c-format
+msgid "%s: Option -%c: %s near character %d\n"
+msgstr "%s : Option -%c : %s près du caractère %d\n"
+
+#: ../setfacl/setfacl.c:584
+#, c-format
+msgid "%s: %s in line %d of file %s\n"
+msgstr "%s : %s à la ligne %d du fichier %s\n"
+
+#: ../setfacl/setfacl.c:592
+#, c-format
+msgid "%s: %s in line %d of standard input\n"
+msgstr "%s : %s à la ligne %d de la sortie standard\n"
+
+#: ../setfacl/setfacl.c:703 ../getfacl/getfacl.c:774
+#, c-format
+msgid "Try `%s --help' for more information.\n"
+msgstr "Essayer « %s --help » pour plus d'informations.\n"
+
+#: ../getfacl/getfacl.c:462
+#, c-format
+msgid "%s: Removing leading '/' from absolute path names\n"
+msgstr "%s : suppression du premier « / » des noms de chemins absolus\n"
+
+#: ../getfacl/getfacl.c:531
+#, c-format
+msgid "%s %s -- get file access control lists\n"
+msgstr "%s %s -- obtenir les listes de contrôle d'accès du fichier\n"
+
+#: ../getfacl/getfacl.c:533 ../getfacl/getfacl.c:772
+#, c-format
+msgid "Usage: %s [-%s] file ...\n"
+msgstr "Utilisation : %s [-%s] fichier...\n"
+
+#: ../getfacl/getfacl.c:539
+msgid " -d, --default display the default access control list\n"
+msgstr ""
+"-d, --default afficher la liste de contrôle d'accès par défaut\n"
+
+#: ../getfacl/getfacl.c:543
+msgid ""
+" --access display the file access control list only\n"
+" -d, --default display the default access control list only\n"
+" --omit-header do not display the comment header\n"
+" --all-effective print all effective rights\n"
+" --no-effective print no effective rights\n"
+" --skip-base skip files that only have the base entries\n"
+" -R, --recursive recurse into subdirectories\n"
+" -L, --logical logical walk, follow symbolic links\n"
+" -P --physical physical walk, do not follow symbolic links\n"
+" --tabular use tabular output format\n"
+" --numeric print numeric user/group identifiers\n"
+" --absolute-names don't strip leading '/' in pathnames\n"
+msgstr ""
+" --access affiche seulement le fichier ACL\n"
+" -d, --default affiche seulement le fichier ACL par défaut\n"
+" --omit-header n'affiche pas les commentaires d'en-tête\n"
+" --all-effective affiche tous les droits en vigueur\n"
+" --no-effective affiche les droits inactifs\n"
+" --skip-base ignorer les fichiers qui ont seulement les entrées\n"
+" de base\n"
+" -R, --recursive parcourir récursivement les sous-répertoires\n"
+" -L, --logical suivre les liens symboliques\n"
+" -P, --physical ne pas suivre les liens symboliques\n"
+" --tabular sortie tabulée\n"
+" --numeric afficher les identifiants numériques des\n"
+" utilisateurs/groupes\n"
+" --absolute-names ne pas enlever le premier « / » dans les chemins\n"
+
+#: ../getfacl/getfacl.c:760
+#, c-format
+msgid "%s: Standard input: %s\n"
+msgstr "%s : Sortie standard : %s\n"
+
+#: ../libacl/acl_error.c:34
+msgid "Multiple entries of same type"
+msgstr "Plusieurs entrées de même type"
+
+#: ../libacl/acl_error.c:36
+msgid "Duplicate entries"
+msgstr "Entrées dupliquées"
+
+#: ../libacl/acl_error.c:38
+msgid "Missing or wrong entry"
+msgstr "Entrée erronée ou manquante"
+
+#: ../libacl/acl_error.c:40
+msgid "Invalid entry type"
+msgstr "Type d'entrée non valable"
+
+#: ../libacl/perm_copy_fd.c:123 ../libacl/perm_copy_fd.c:135
+#: ../libacl/perm_copy_fd.c:197 ../libacl/perm_copy_file.c:123
+#: ../libacl/perm_copy_file.c:138 ../libacl/perm_copy_file.c:149
+#: ../libacl/perm_copy_file.c:234
+#, c-format
+msgid "setting permissions for %s"
+msgstr "modifier les permissions pour %s"
+
+#: ../libacl/perm_copy_fd.c:185 ../libacl/perm_copy_file.c:198
+#: ../libacl/perm_copy_file.c:223
+#, c-format
+msgid "preserving permissions for %s"
+msgstr "conserver les permissions pour %s"
+
+
diff --git a/po/gl.po b/po/gl.po
new file mode 100644
index 0000000..ae7b700
--- /dev/null
+++ b/po/gl.po
@@ -0,0 +1,355 @@
+# Galician translation for ACL utilities
+# Copyright (C) 2007 Free Software Foundation, Inc.
+# Antonio Trueba <atrueba@users.sourceforge.net>, 2007.
+#
+# 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 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 <http://www.gnu.org/licenses/>.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: acl-2.2.43.1\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2007-03-06 12:08+0100\n"
+"PO-Revision-Date: 2007-03-16 18:52+0100\n"
+"Last-Translator: Antonio Trueba <atrueba@users.sourceforge.net>\n"
+"Language-Team: Galician\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=utf-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Poedit-Language: Galician\n"
+
+#: ../chacl/chacl.c:45
+#, c-format
+msgid "Usage:\n"
+msgstr "Uso:\n"
+
+#: ../chacl/chacl.c:46
+#, c-format
+msgid "\t%s acl pathname...\n"
+msgstr "\t%s nome de rota do ACL...\n"
+
+#: ../chacl/chacl.c:47
+#, c-format
+msgid "\t%s -b acl dacl pathname...\n"
+msgstr "\t%s -b nome de ruta ACL DACL..\n"
+
+#: ../chacl/chacl.c:48
+#, c-format
+msgid "\t%s -d dacl pathname...\n"
+msgstr "\t%s -d rota ó ACL...\n"
+
+#: ../chacl/chacl.c:49
+#, c-format
+msgid "\t%s -R pathname...\n"
+msgstr "\t%s -R rota...\n"
+
+#: ../chacl/chacl.c:50
+#, c-format
+msgid "\t%s -D pathname...\n"
+msgstr "\t%s -D rota...\n"
+
+#: ../chacl/chacl.c:51
+#, c-format
+msgid "\t%s -B pathname...\n"
+msgstr "\t%s -B rota...\n"
+
+#: ../chacl/chacl.c:52
+#, c-format
+msgid "\t%s -l pathname...\t[not IRIX compatible]\n"
+msgstr "\t%s -l rota...\t[non compatible con IRIX]\n"
+
+#: ../chacl/chacl.c:54
+#, c-format
+msgid "\t%s -r pathname...\t[not IRIX compatible]\n"
+msgstr "\t%s -r rota...\t[non compatible con IRIX]\n"
+
+#: ../chacl/chacl.c:145
+#, c-format
+msgid "%s: error removing access acl on \"%s\": %s\n"
+msgstr "%s: erro borrando ACL de acceso en \"%s\": %s\n"
+
+#: ../chacl/chacl.c:152
+#, c-format
+msgid "%s: error removing default acl on \"%s\": %s\n"
+msgstr "%s: erro borrando ACL predeterminado en \"%s\": %s\n"
+
+#: ../chacl/chacl.c:171
+#: ../chacl/chacl.c:190
+#, c-format
+msgid "%s: access ACL '%s': %s at entry %d\n"
+msgstr "%s: ACL de acceso '%s': %s en posición %d\n"
+
+#: ../chacl/chacl.c:258
+#, c-format
+msgid "%s: cannot get access ACL on '%s': %s\n"
+msgstr "%s: non se puido obter ACL de acceso en '%s': %s\n"
+
+#: ../chacl/chacl.c:264
+#, c-format
+msgid "%s: cannot get default ACL on '%s': %s\n"
+msgstr "%s: non se puido obter ACL predeterminado en '%s': %s\n"
+
+#: ../chacl/chacl.c:270
+#, c-format
+msgid "%s: cannot get access ACL text on '%s': %s\n"
+msgstr "%s: non se puido obter texto ACL de acceso en '%s': %s\n"
+
+#: ../chacl/chacl.c:277
+#, c-format
+msgid "%s: cannot get default ACL text on '%s': %s\n"
+msgstr "%s: non se puido obter texto de ACL predeterminado en '%s': %s\n"
+
+#: ../chacl/chacl.c:303
+#, c-format
+msgid "%s: cannot set access acl on \"%s\": %s\n"
+msgstr "%s: non se puido establecé-lo ACL de acceso en \"%s\": %s\n"
+
+#: ../chacl/chacl.c:309
+#, c-format
+msgid "%s: cannot set default acl on \"%s\": %s\n"
+msgstr "%s: non se puido establecé-lo ACL predeterminado en \"%s\": %s\n"
+
+#: ../chacl/chacl.c:327
+#, c-format
+msgid "%s: opendir failed: %s\n"
+msgstr "%s: a chamada a opendir fallou: %s\n"
+
+#: ../chacl/chacl.c:341
+#, c-format
+msgid "%s: malloc failed: %s\n"
+msgstr "%s: a chamada a malloc fallou: %s\n"
+
+#: ../setfacl/do_set.c:391
+#, c-format
+msgid "%s: %s: Malformed access ACL `%s': %s at entry %d\n"
+msgstr "%s: %s: ACL incorrecto `%s': %s na posición %d\n"
+
+#: ../setfacl/do_set.c:418
+#, c-format
+msgid "%s: %s: Malformed default ACL `%s': %s at entry %d\n"
+msgstr "%s: %s: ACL predeterminado incorrecto `%s': %s na posición %d\n"
+
+#: ../setfacl/do_set.c:480
+#, c-format
+msgid "%s: %s: Only directories can have default ACLs\n"
+msgstr "%s: %s: Só os directorios poden ter ACLs predeterminados\n"
+
+#: ../setfacl/setfacl.c:151
+#, c-format
+msgid "%s: %s: No filename found in line %d, aborting\n"
+msgstr "%s: %s: Non se atopou nome de ficheiro na liña %d, abortando\n"
+
+#: ../setfacl/setfacl.c:156
+#, c-format
+msgid "%s: No filename found in line %d of standard input, aborting\n"
+msgstr "%s: Non se atopou nome de ficheiro na liña %d da entrada estándar, abortando\n"
+
+#: ../setfacl/setfacl.c:176
+#, c-format
+msgid "%s: %s: %s in line %d\n"
+msgstr "%s: %s: %s na liña %d\n"
+
+#: ../setfacl/setfacl.c:200
+#, c-format
+msgid "%s: %s: Cannot change owner/group: %s\n"
+msgstr "%s: %s: Non se pode cambiá-lo propietario/grupo: %s\n"
+
+#: ../setfacl/setfacl.c:240
+#, c-format
+msgid "%s %s -- set file access control lists\n"
+msgstr "%s %s -- establecer listas de control de acceso a ficheiro\n"
+
+#: ../setfacl/setfacl.c:242
+#: ../setfacl/setfacl.c:692
+#, c-format
+msgid "Usage: %s %s\n"
+msgstr "Uso: %s %s\n"
+
+#: ../setfacl/setfacl.c:245
+#, c-format
+msgid ""
+" -m, --modify=acl modify the current ACL(s) of file(s)\n"
+" -M, --modify-file=file read ACL entries to modify from file\n"
+" -x, --remove=acl remove entries from the ACL(s) of file(s)\n"
+" -X, --remove-file=file read ACL entries to remove from file\n"
+" -b, --remove-all remove all extended ACL entries\n"
+" -k, --remove-default remove the default ACL\n"
+msgstr ""
+" -m, --modify=ACL modificá-lo ACL actual de ficheiro(s)\n"
+" -M, --modify-file=fich ler entradas ACL a modificar dende ficheiro\n"
+" -x, --remove=ACL borrar entradas do ACL de ficheiro(s)\n"
+" -X, --remove-file=fich ler entradas dACL a borrar dende ficheiro\n"
+" -b, --remove-all borrar tódalas entradas de ACL extendidas\n"
+" -k, --remove-default borrar ó ACL predeterminado\n"
+
+#: ../setfacl/setfacl.c:254
+#, c-format
+msgid ""
+" --set=acl set the ACL of file(s), replacing the current ACL\n"
+" --set-file=file read ACL entries to set from file\n"
+" --mask do recalculate the effective rights mask\n"
+msgstr ""
+" --set=ACL estableceé-lo ACL de ficheiro(s), substituindo ó ACL actual\n"
+" --set-file=fich ler entradas ACL a establecer dende ficheiro\n"
+" --mask recalculá-la máscara de dereitos efectiva\n"
+
+#: ../setfacl/setfacl.c:260
+#, c-format
+msgid ""
+" -n, --no-mask don't recalculate the effective rights mask\n"
+" -d, --default operations apply to the default ACL\n"
+msgstr ""
+" -n, --no-mask non recalculá-la máscara de dereitos efectiva\n"
+" -d, --default as operacións afectan ó ACL predeterminado\n"
+
+#: ../setfacl/setfacl.c:265
+#, c-format
+msgid ""
+" -R, --recursive recurse into subdirectories\n"
+" -L, --logical logical walk, follow symbolic links\n"
+" -P, --physical physical walk, do not follow symbolic links\n"
+" --restore=file restore ACLs (inverse of `getfacl -R')\n"
+" --test test mode (ACLs are not modified)\n"
+msgstr ""
+" -R, --recursive recorrer subdirectorios recursivamente\n"
+" -L, --logical percorrido lóxico, seguindo enlaces simbólicos\n"
+" -P, --physical percorrido físico, non seguir enlaces simbólicos\n"
+" --restore=fich restaurar ACLs (inverso de 'getfacl -R')\n"
+" --test modo de proba (os ACLs non son modificados)\n"
+
+#: ../setfacl/setfacl.c:273
+#: ../getfacl/getfacl.c:559
+#, c-format
+msgid ""
+" --version print version and exit\n"
+" --help this help text\n"
+msgstr ""
+" --version amosar versión e sair\n"
+" --help este texto de axuda\n"
+
+#: ../setfacl/setfacl.c:358
+#: ../getfacl/getfacl.c:768
+#, c-format
+msgid "%s: Standard input: %s\n"
+msgstr "%s: Entrada estándar: %s\n"
+
+#: ../setfacl/setfacl.c:494
+#, c-format
+msgid "%s: Option -%c incomplete\n"
+msgstr "%s: Opción -%c incompleta\n"
+
+#: ../setfacl/setfacl.c:499
+#, c-format
+msgid "%s: Option -%c: %s near character %d\n"
+msgstr "%s: Opción -%c: %s preto do carácter %d\n"
+
+#: ../setfacl/setfacl.c:575
+#, c-format
+msgid "%s: %s in line %d of file %s\n"
+msgstr "%s: %s na liña %d do ficheiro %s\n"
+
+#: ../setfacl/setfacl.c:583
+#, c-format
+msgid "%s: %s in line %d of standard input\n"
+msgstr "%s: %s na liña %d da entrada estándar\n"
+
+#: ../setfacl/setfacl.c:694
+#: ../getfacl/getfacl.c:782
+#, c-format
+msgid "Try `%s --help' for more information.\n"
+msgstr "Escriba \"%s --help\" para máis información.\n"
+
+#: ../getfacl/getfacl.c:463
+#, c-format
+msgid "%s: Removing leading '/' from absolute path names\n"
+msgstr "%s: Eliminando '/' iniciais en nomes de ruta absolutos\n"
+
+#: ../getfacl/getfacl.c:532
+#, c-format
+msgid "%s %s -- get file access control lists\n"
+msgstr "%s %s -- obter listas de control de acceso a ficheiro\n"
+
+#: ../getfacl/getfacl.c:534
+#: ../getfacl/getfacl.c:780
+#, c-format
+msgid "Usage: %s [-%s] file ...\n"
+msgstr "Uso: %s [-%s] ficheiro ...\n"
+
+#: ../getfacl/getfacl.c:540
+#, c-format
+msgid " -d, --default display the default access control list\n"
+msgstr " -d, --default amosá-la lista de control de acceso predeterminada\n"
+
+#: ../getfacl/getfacl.c:544
+#, c-format
+msgid ""
+" --access display the file access control list only\n"
+" -d, --default display the default access control list only\n"
+" --omit-header do not display the comment header\n"
+" --all-effective print all effective rights\n"
+" --no-effective print no effective rights\n"
+" --skip-base skip files that only have the base entries\n"
+" -R, --recursive recurse into subdirectories\n"
+" -L, --logical logical walk, follow symbolic links\n"
+" -P --physical physical walk, do not follow symbolic links\n"
+" --tabular use tabular output format\n"
+" --numeric print numeric user/group identifiers\n"
+" --absolute-names don't strip leading '/' in pathnames\n"
+msgstr ""
+" --access só amosá-la lista de control de acceso ó ficheiro\n"
+" -d, --default só mostrá-la lista de control de acceso predeterminada\n"
+" --omit-header non amosá-lo comentario de encabezamento\n"
+" --all-effective amosar tódolos dereitos efectivos\n"
+" --no-effective non amosar ningún dereito efectivo\n"
+" --skip-base saltar ficheiros que só teñan as entradas básicas\n"
+" -R, --recursive descender recursivamente nos subdirectorios\n"
+" -L, --logical percorrido lóxico, seguindo enlaces simbólicos\n"
+" -P --physical percorrido físico, non seguir enlaces simbólicos\n"
+" --tabular usar formato de saída tabular\n"
+" --numeric amosar identificadores numéricos de propietario/grupo\n"
+" --absolute-names non eliminá-la '/' en nomes de ruta\n"
+
+#: ../libacl/acl_error.c:34
+msgid "Multiple entries of same type"
+msgstr "Varias entradas do mesmo tipo"
+
+#: ../libacl/acl_error.c:36
+msgid "Duplicate entries"
+msgstr "Entradas duplicadas"
+
+#: ../libacl/acl_error.c:38
+msgid "Missing or wrong entry"
+msgstr "Falta un atributo, ou está mal formado"
+
+#: ../libacl/acl_error.c:40
+msgid "Invalid entry type"
+msgstr "Tipo de entrada non válido"
+
+#: ../libacl/perm_copy_fd.c:124
+#: ../libacl/perm_copy_fd.c:136
+#: ../libacl/perm_copy_fd.c:198
+#: ../libacl/perm_copy_file.c:124
+#: ../libacl/perm_copy_file.c:139
+#: ../libacl/perm_copy_file.c:150
+#: ../libacl/perm_copy_file.c:235
+#, c-format
+msgid "setting permissions for %s"
+msgstr "establecendo permisos para %s"
+
+#: ../libacl/perm_copy_fd.c:186
+#: ../libacl/perm_copy_file.c:199
+#: ../libacl/perm_copy_file.c:224
+#, c-format
+msgid "preserving permissions for %s"
+msgstr "mantendo permisos de %s"
+
diff --git a/po/pl.po b/po/pl.po
new file mode 100644
index 0000000..186507a
--- /dev/null
+++ b/po/pl.po
@@ -0,0 +1,347 @@
+# Polish translation for acl.
+# Copyright (C) 2004 Free Software Foundation, Inc.
+# Jakub Bogusz <qboosh@pld-linux.org>, 2004.
+#
+# 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 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 <http://www.gnu.org/licenses/>.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: acl-2.2.22\n"
+"POT-Creation-Date: 2004-01-28 22:30+0100\n"
+"PO-Revision-Date: 2004-01-28 22:31+0100\n"
+"Last-Translator: Jakub Bogusz <qboosh@pld-linux.org>\n"
+"Language-Team: Polish <translation-team-pl@lists.sourceforge.net>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=ISO-8859-2\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+#: ../chacl/chacl.c:59
+#, c-format
+msgid "Usage:\n"
+msgstr "Sk³adnia:\n"
+
+#: ../chacl/chacl.c:60
+#, c-format
+msgid "\t%s acl pathname...\n"
+msgstr "\t%s acl ¶cie¿ka...\n"
+
+#: ../chacl/chacl.c:61
+#, c-format
+msgid "\t%s -b acl dacl pathname...\n"
+msgstr "\t%s -b acl dacl ¶cie¿ka...\n"
+
+#: ../chacl/chacl.c:62
+#, c-format
+msgid "\t%s -d dacl pathname...\n"
+msgstr "\t%s -d dacl ¶cie¿ka...\n"
+
+#: ../chacl/chacl.c:63
+#, c-format
+msgid "\t%s -R pathname...\n"
+msgstr "\t%s -R ¶cie¿ka...\n"
+
+#: ../chacl/chacl.c:64
+#, c-format
+msgid "\t%s -D pathname...\n"
+msgstr "\t%s -D ¶cie¿ka...\n"
+
+#: ../chacl/chacl.c:65
+#, c-format
+msgid "\t%s -B pathname...\n"
+msgstr "\t%s -B ¶cie¿ka...\n"
+
+#: ../chacl/chacl.c:66
+#, c-format
+msgid "\t%s -l pathname...\t[not IRIX compatible]\n"
+msgstr "\t%s -l ¶cie¿ka...\t[niekompatybilne z IRIX-em]\n"
+
+#: ../chacl/chacl.c:68
+#, c-format
+msgid "\t%s -r pathname...\t[not IRIX compatible]\n"
+msgstr "\t%s -r ¶cie¿ka...\t[niekompatybilne z IRIX-em]\n"
+
+#: ../chacl/chacl.c:159
+#, c-format
+msgid "%s: error removing access acl on \"%s\": %s\n"
+msgstr "%s: b³±d przy usuwaniu dostêpowego acl dla \"%s\": %s\n"
+
+#: ../chacl/chacl.c:166
+#, c-format
+msgid "%s: error removing default acl on \"%s\": %s\n"
+msgstr "%s: b³±d przy usuwaniu domy¶lnego acl dla \"%s\": %s\n"
+
+#: ../chacl/chacl.c:185 ../chacl/chacl.c:204
+#, c-format
+msgid "%s: access ACL '%s': %s at entry %d\n"
+msgstr "%s: dostêpowe ACL '%s': %s na pozycji %d\n"
+
+#: ../chacl/chacl.c:272
+#, c-format
+msgid "%s: cannot get access ACL on '%s': %s\n"
+msgstr "%s: nie mo¿na odczytaæ dostêpowego ACL dla '%s': %s\n"
+
+#: ../chacl/chacl.c:278
+#, c-format
+msgid "%s: cannot get default ACL on '%s': %s\n"
+msgstr "%s: nie mo¿na odczytaæ domy¶lnego ACL dla '%s': %s\n"
+
+#: ../chacl/chacl.c:284
+#, c-format
+msgid "%s: cannot get access ACL text on '%s': %s\n"
+msgstr "%s: nie mo¿na odczytaæ dostêpowego tekstu ACL dla '%s': %s\n"
+
+#: ../chacl/chacl.c:291
+#, c-format
+msgid "%s: cannot get default ACL text on '%s': %s\n"
+msgstr "%s: nie mo¿na odczytaæ domy¶lnego tekstu ACL dla '%s': %s\n"
+
+#: ../chacl/chacl.c:317
+#, c-format
+msgid "%s: cannot set access acl on \"%s\": %s\n"
+msgstr "%s: nie mo¿na ustawiæ dostêpowego acl dla \"%s\": %s\n"
+
+#: ../chacl/chacl.c:323
+#, c-format
+msgid "%s: cannot set default acl on \"%s\": %s\n"
+msgstr "%s: nie mo¿na ustawiæ domy¶lnego acl dla \"%s\": %s\n"
+
+#: ../chacl/chacl.c:341
+#, c-format
+msgid "%s: opendir failed: %s\n"
+msgstr "%s: opendir nie powiod³o siê: %s\n"
+
+#: ../chacl/chacl.c:355
+#, c-format
+msgid "%s: malloc failed: %s\n"
+msgstr "%s: malloc nie powiód³ siê: %s\n"
+
+#: ../setfacl/do_set.c:404
+#, c-format
+msgid "%s: %s: Malformed access ACL `%s': %s at entry %d\n"
+msgstr "%s: %s: ¬le sformu³owane dostêpowe ACL `%s': %s na pozycji %d\n"
+
+#: ../setfacl/do_set.c:431
+#, c-format
+msgid "%s: %s: Malformed default ACL `%s': %s at entry %d\n"
+msgstr "%s: %s: ¬le sformu³owane domy¶lne ACL `%s': %s na pozycji %d\n"
+
+#: ../setfacl/do_set.c:494
+#, c-format
+msgid "%s: %s: Only directories can have default ACLs\n"
+msgstr "%s: %s: Tylko katalogi mog± mieæ domy¶lne ACL-e\n"
+
+#: ../setfacl/setfacl.c:151
+#, c-format
+msgid "%s: %s: No filename found in line %d, aborting\n"
+msgstr "%s: %s: Nie znaleziono nazwy pliku w linii %d, przerwanie pracy\n"
+
+#: ../setfacl/setfacl.c:156
+#, c-format
+msgid "%s: No filename found in line %d of standard input, aborting\n"
+msgstr "%s: Nie znaleziono nazwy pliku w linii %d standardowego wej¶cia, przerwanie pracy\n"
+
+#: ../setfacl/setfacl.c:177
+#, c-format
+msgid "%s: %s: %s in line %d\n"
+msgstr "%s: %s: %s w linii %d\n"
+
+#: ../setfacl/setfacl.c:201
+#, c-format
+msgid "%s: %s: Cannot change owner/group: %s\n"
+msgstr "%s: %s: Nie mo¿na zmieniæ w³a¶ciciela/grupy: %s\n"
+
+#: ../setfacl/setfacl.c:241
+#, c-format
+msgid "%s %s -- set file access control lists\n"
+msgstr "%s %s -- ustawianie list kontroli dostêpu do plików (ACL-i)\n"
+
+#: ../setfacl/setfacl.c:243 ../setfacl/setfacl.c:701
+#, c-format
+msgid "Usage: %s %s\n"
+msgstr "Sk³adnia: %s %s\n"
+
+#: ../setfacl/setfacl.c:246
+#, c-format
+msgid ""
+" -m, --modify=acl modify the current ACL(s) of file(s)\n"
+" -M, --modify-file=file read ACL entries to modify from file\n"
+" -x, --remove=acl remove entries from the ACL(s) of file(s)\n"
+" -X, --remove-file=file read ACL entries to remove from file\n"
+" -b, --remove-all remove all extended ACL entries\n"
+" -k, --remove-default remove the default ACL\n"
+msgstr ""
+" -m, --modify=acl zmiana aktualnego(ych) ACL(-i) pliku(ów)\n"
+" -M, --modify-file=plik odczyt z pliku pozycji ACL do zmodyfikowania\n"
+" -x, --remove=acl usuniêcie wpisów z ACL(-i) pliku(ów)\n"
+" -X, --remove-file=plik odczyt z pliku pozycji ACL do usuniêcia\n"
+" -b, --remove-all usuniêcie wszystkich rozszerzonych pozycji ACL\n"
+" -k, --remove-default usuniêcie domy¶lnego ACL\n"
+
+#: ../setfacl/setfacl.c:255
+#, c-format
+msgid ""
+" --set=acl set the ACL of file(s), replacing the current ACL\n"
+" --set-file=file read ACL entries to set from file\n"
+" --mask do recalculate the effective rights mask\n"
+msgstr ""
+" --set=acl ustawienie ACL pliku(ów), zastêpuj±c aktualne\n"
+" --set-file=plik odczytanie z pliku pozycji ACL do ustawienia\n"
+" --mask przeliczenie maski efektywnych uprawnieñ\n"
+
+#: ../setfacl/setfacl.c:261
+#, c-format
+msgid ""
+" -n, --no-mask don't recalculate the effective rights mask\n"
+" -d, --default operations apply to the default ACL\n"
+msgstr ""
+" -n, --no-mask nie przeliczanie maski efektywnych uprawnieñ\n"
+" -d, --default wykonywanie operacji na domy¶lnym ACL\n"
+
+#: ../setfacl/setfacl.c:266
+#, c-format
+msgid ""
+" -R, --recursive recurse into subdirectories\n"
+" -L, --logical logical walk, follow symbolic links\n"
+" -P, --physical physical walk, do not follow symbolic links\n"
+" --restore=file restore ACLs (inverse of `getfacl -R')\n"
+" --test test mode (ACLs are not modified)\n"
+msgstr ""
+" -R, --recursive rekurencyjne wchodzenie do katalogów\n"
+" -L, --logical przechodzenie logiczne, pod±¿anie za dowi±zaniami\n"
+" symbolicznymi\n"
+" -P, --physical przechodzenie fizyczne, nie pod±¿anie za dowi±zaniami\n"
+" symbolicznymi\n"
+" --restore=plik odtworzenie ACL-i (odwrotno¶æ `getfacl -R')\n"
+" --test tryb testowy (ACL-e nie s± modyfikowane)\n"
+
+#: ../setfacl/setfacl.c:274 ../getfacl/getfacl.c:558
+#, c-format
+msgid ""
+" --version print version and exit\n"
+" --help this help text\n"
+msgstr ""
+" --version wy¶wietlenie informacji o wersji i zakoñczenie\n"
+" --help ten tekst pomocy\n"
+
+#: ../setfacl/setfacl.c:493
+#, c-format
+msgid "%s: Option -%c incomplete\n"
+msgstr "%s: Opcja -%c niekompletna\n"
+
+#: ../setfacl/setfacl.c:498
+#, c-format
+msgid "%s: Option -%c: %s near character %d\n"
+msgstr "%s: Opcja -%c: %s obok znaku %d\n"
+
+#: ../setfacl/setfacl.c:584
+#, c-format
+msgid "%s: %s in line %d of file %s\n"
+msgstr "%s: %s w linii %d pliku %s\n"
+
+#: ../setfacl/setfacl.c:592
+#, c-format
+msgid "%s: %s in line %d of standard input\n"
+msgstr "%s: %s w linii %d standardowego wej¶cia\n"
+
+#: ../setfacl/setfacl.c:703 ../getfacl/getfacl.c:774
+#, c-format
+msgid "Try `%s --help' for more information.\n"
+msgstr "`%s --help' wy¶wietli wiêcej informacji.\n"
+
+#: ../getfacl/getfacl.c:462
+#, c-format
+msgid "%s: Removing leading '/' from absolute path names\n"
+msgstr "%s: Usuniêcie wiod±cego '/' ze ¶cie¿ek bezwzglêdnych\n"
+
+#: ../getfacl/getfacl.c:531
+#, c-format
+msgid "%s %s -- get file access control lists\n"
+msgstr "%s %s -- odczyt list kontroli dostêpu do plików (ACL-i)\n"
+
+#: ../getfacl/getfacl.c:533 ../getfacl/getfacl.c:772
+#, c-format
+msgid "Usage: %s [-%s] file ...\n"
+msgstr "Sk³adnia: %s [-%s] plik ...\n"
+
+#: ../getfacl/getfacl.c:539
+#, c-format
+msgid " -d, --default display the default access control list\n"
+msgstr " -d, --default wy¶wietlenie domy¶lnej listy kontroli dostêpu\n"
+
+#: ../getfacl/getfacl.c:543
+#, c-format
+msgid ""
+" --access display the file access control list only\n"
+" -d, --default display the default access control list only\n"
+" --omit-header do not display the comment header\n"
+" --all-effective print all effective rights\n"
+" --no-effective print no effective rights\n"
+" --skip-base skip files that only have the base entries\n"
+" -R, --recursive recurse into subdirectories\n"
+" -L, --logical logical walk, follow symbolic links\n"
+" -P --physical physical walk, do not follow symbolic links\n"
+" --tabular use tabular output format\n"
+" --numeric print numeric user/group identifiers\n"
+" --absolute-names don't strip leading '/' in pathnames\n"
+msgstr ""
+" --access wy¶wietlenie tylko listy kontroli dostêpu do pliku\n"
+" -d, --default wy¶wietlenie tylko domy¶lnej listy kontroli dostêpu\n"
+" --omit-header nie wy¶wietlanie nag³ówka z komentarzem\n"
+" --all-effective wy¶wietlanie wszystkich efektywnych uprawnieñ\n"
+" --no-effective nie wy¶wietlanie efektywnych uprawnieñ\n"
+" --skip-base pominiêcie plików z sam± podstawow± pozycj±\n"
+" -R, --recursive rekurencyjne wchodzenie do katalogów\n"
+" -L, --logical przechodzenie logiczne, pod±¿anie za dowi±zaniami\n"
+" symbolicznymi\n"
+" -P, --physical przechodzenie fizyczne, nie pod±¿anie za dowi±zaniami\n"
+" symbolicznymi\n"
+" --tabular wyj¶cie w formacie tabeli\n"
+" --numeric wy¶wietlanie liczbowych identyfikatorów\n"
+" u¿ytkowników/grup\n"
+" --absolute-names nie usuwanie wiod±cego '/' z nazw plików\n"
+
+#: ../getfacl/getfacl.c:760
+#, c-format
+msgid "%s: Standard input: %s\n"
+msgstr "%s: Standardowe wej¶cie: %s\n"
+
+#: ../libacl/acl_error.c:34
+msgid "Multiple entries of same type"
+msgstr "Wiele pozycji tego samego typu"
+
+#: ../libacl/acl_error.c:36
+msgid "Duplicate entries"
+msgstr "Powtórzone pozycje"
+
+#: ../libacl/acl_error.c:38
+msgid "Missing or wrong entry"
+msgstr "Brakuj±ca lub b³êdna pozycja"
+
+#: ../libacl/acl_error.c:40
+msgid "Invalid entry type"
+msgstr "Nieprawid³owy typ pozycji"
+
+#: ../libacl/perm_copy_fd.c:123 ../libacl/perm_copy_fd.c:135
+#: ../libacl/perm_copy_fd.c:197 ../libacl/perm_copy_file.c:123
+#: ../libacl/perm_copy_file.c:138 ../libacl/perm_copy_file.c:149
+#: ../libacl/perm_copy_file.c:234
+#, c-format
+msgid "setting permissions for %s"
+msgstr "ustawianie uprawnieñ dla %s"
+
+#: ../libacl/perm_copy_fd.c:185 ../libacl/perm_copy_file.c:198
+#: ../libacl/perm_copy_file.c:223
+#, c-format
+msgid "preserving permissions for %s"
+msgstr "zachowywanie uprawnieñ dla %s"
diff --git a/po/sv.po b/po/sv.po
new file mode 100644
index 0000000..2348eca
--- /dev/null
+++ b/po/sv.po
@@ -0,0 +1,345 @@
+# Swedish translation for acl.
+# Copyright (C) 2006 Free Software Foundation, Inc.
+# Daniel Nylander <po@danielnylander.se>, 2006.
+#
+# 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 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 <http://www.gnu.org/licenses/>.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: acl 2.2.37\n"
+"POT-Creation-Date: \n"
+"PO-Revision-Date: 2006-05-23 22:45+0100\n"
+"Last-Translator: Daniel Nylander <po@danielnylander.se>\n"
+"Language-Team: Swedish <tp-sv@listor.tp-sv.se>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=iso-8859-1\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+#: ../chacl/chacl.c:59
+msgid "Usage:\n"
+msgstr "Användning:\n"
+
+#: ../chacl/chacl.c:60
+#, c-format
+msgid "\t%s acl pathname...\n"
+msgstr "\t%s acl sökväg...\n"
+
+#: ../chacl/chacl.c:61
+#, c-format
+msgid "\t%s -b acl dacl pathname...\n"
+msgstr "\t%s -b acl dacl sökväg...\n"
+
+#: ../chacl/chacl.c:62
+#, c-format
+msgid "\t%s -d dacl pathname...\n"
+msgstr "\t%s -d dacl sökväg...\n"
+
+#: ../chacl/chacl.c:63
+#, c-format
+msgid "\t%s -R pathname...\n"
+msgstr "\t%s -R sökväg...\n"
+
+#: ../chacl/chacl.c:64
+#, c-format
+msgid "\t%s -D pathname...\n"
+msgstr "\t%s -D sökväg...\n"
+
+#: ../chacl/chacl.c:65
+#, c-format
+msgid "\t%s -B pathname...\n"
+msgstr "\t%s -B sökväg...\n"
+
+#: ../chacl/chacl.c:66
+#, c-format
+msgid "\t%s -l pathname...\t[not IRIX compatible]\n"
+msgstr "\t%s -l sökväg...\t[inte IRIX-kompatibel]\n"
+
+#: ../chacl/chacl.c:68
+#, c-format
+msgid "\t%s -r pathname...\t[not IRIX compatible]\n"
+msgstr "\t%s -r sökväg...\t[inte IRIX-kompatibel]\n"
+
+#: ../chacl/chacl.c:159
+#, c-format
+msgid "%s: error removing access acl on \"%s\": %s\n"
+msgstr "%s: fel vid borttagning av acl på \"%s\": %s\n"
+
+#: ../chacl/chacl.c:166
+#, c-format
+msgid "%s: error removing default acl on \"%s\": %s\n"
+msgstr "%s: fel vid borttagning av acl på \"%s\": %s\n"
+
+# Skum. Vad menar dom?
+#: ../chacl/chacl.c:185
+#: ../chacl/chacl.c:204
+#, c-format
+msgid "%s: access ACL '%s': %s at entry %d\n"
+msgstr "%s: åtkomst-ACL \"%s\": %s vid posten %d\n"
+
+#: ../chacl/chacl.c:272
+#, c-format
+msgid "%s: cannot get access ACL on '%s': %s\n"
+msgstr "%s: kan inte få åtkomst-ACL på \"%s\": %s\n"
+
+#: ../chacl/chacl.c:278
+#, c-format
+msgid "%s: cannot get default ACL on '%s': %s\n"
+msgstr "%s: kan inte få standard-ACL på \"%s\": %s\n"
+
+#: ../chacl/chacl.c:284
+#, c-format
+msgid "%s: cannot get access ACL text on '%s': %s\n"
+msgstr "%s: kan inte få åtkomst-ACL-text på \"%s\": %s\n"
+
+#: ../chacl/chacl.c:291
+#, c-format
+msgid "%s: cannot get default ACL text on '%s': %s\n"
+msgstr "%s: kan inte få standard-ACL-text på \"%s\": %s\n"
+
+#: ../chacl/chacl.c:317
+#, c-format
+msgid "%s: cannot set access acl on \"%s\": %s\n"
+msgstr "%s: kan inte ställa in åtkomst-acl på \"%s\": %s\n"
+
+#: ../chacl/chacl.c:323
+#, c-format
+msgid "%s: cannot set default acl on \"%s\": %s\n"
+msgstr "%s: kan inte ställa in standard-acl på \"%s\": %s\n"
+
+#: ../chacl/chacl.c:341
+#, c-format
+msgid "%s: opendir failed: %s\n"
+msgstr "%s: opendir misslyckades: %s\n"
+
+#: ../chacl/chacl.c:355
+#, c-format
+msgid "%s: malloc failed: %s\n"
+msgstr "%s: malloc misslyckades: %s\n"
+
+#: ../setfacl/do_set.c:404
+#, c-format
+msgid "%s: %s: Malformed access ACL `%s': %s at entry %d\n"
+msgstr "%s: %s: Felaktigt formulerad åtkomst-ACL \"%s\": %s vid posten %d\n"
+
+#: ../setfacl/do_set.c:431
+#, c-format
+msgid "%s: %s: Malformed default ACL `%s': %s at entry %d\n"
+msgstr "%s: %s: Felaktigt formulerad standard-ACL \"%s\": %s vid posten %d\n"
+
+#: ../setfacl/do_set.c:494
+#, c-format
+msgid "%s: %s: Only directories can have default ACLs\n"
+msgstr "%s: %s: Endast kataloger kan ha standard-ACL:er\n"
+
+#: ../setfacl/setfacl.c:151
+#, c-format
+msgid "%s: %s: No filename found in line %d, aborting\n"
+msgstr "%s: %s: Inget filnamn hittades på rad %d, avbryter\n"
+
+#: ../setfacl/setfacl.c:156
+#, c-format
+msgid "%s: No filename found in line %d of standard input, aborting\n"
+msgstr "%s: Inget filnamn hittades på rad %d i standard in, avbryter\n"
+
+#: ../setfacl/setfacl.c:177
+#, c-format
+msgid "%s: %s: %s in line %d\n"
+msgstr "%s: %s: %s på rad %d\n"
+
+#: ../setfacl/setfacl.c:201
+#, c-format
+msgid "%s: %s: Cannot change owner/group: %s\n"
+msgstr "%s: %s: Kan inte ändra ägare/grupp: %s\n"
+
+#: ../setfacl/setfacl.c:241
+#, c-format
+msgid "%s %s -- set file access control lists\n"
+msgstr "%s %s -- ställ in filåtkomstkontrollistor\n"
+
+#: ../setfacl/setfacl.c:243
+#: ../setfacl/setfacl.c:701
+#, c-format
+msgid "Usage: %s %s\n"
+msgstr "Användning: %s %s\n"
+
+#: ../setfacl/setfacl.c:246
+msgid ""
+" -m, --modify=acl modify the current ACL(s) of file(s)\n"
+" -M, --modify-file=file read ACL entries to modify from file\n"
+" -x, --remove=acl remove entries from the ACL(s) of file(s)\n"
+" -X, --remove-file=file read ACL entries to remove from file\n"
+" -b, --remove-all remove all extended ACL entries\n"
+" -k, --remove-default remove the default ACL\n"
+msgstr ""
+" -m, --modify=acl ändra aktuell(a) ACL(:er) på fil(erna)\n"
+" -M, --modify-file=fil läs ACL-poster att ändra från fil\n"
+" -x, --remove=acl ta bort poster från ACL(:er) på fil(erna)\n"
+" -X, --remove-file=fil läs ACL-poster att ta bort från fil\n"
+" -b, --remove-all ta bort alla utökade ACL-poster\n"
+" -k, --remove-default ta bort standard-ACL:en\n"
+
+#: ../setfacl/setfacl.c:255
+msgid ""
+" --set=acl set the ACL of file(s), replacing the current ACL\n"
+" --set-file=file read ACL entries to set from file\n"
+" --mask do recalculate the effective rights mask\n"
+msgstr ""
+" --set=acl ställ in ACL:en för fil(erna), ersätt aktuell ACL\n"
+" --set-file=fil läs ACL-poster att ställa in från fil\n"
+" --mask räkna om mask för effektiva rättigheter\n"
+
+#: ../setfacl/setfacl.c:261
+msgid ""
+" -n, --no-mask don't recalculate the effective rights mask\n"
+" -d, --default operations apply to the default ACL\n"
+msgstr ""
+" -n, --no-mask räkna inte om mask för effektiva rättigheter\n"
+" -d, --default åtgärder gällande för standard-ACL:en\n"
+
+#: ../setfacl/setfacl.c:266
+msgid ""
+" -R, --recursive recurse into subdirectories\n"
+" -L, --logical logical walk, follow symbolic links\n"
+" -P, --physical physical walk, do not follow symbolic links\n"
+" --restore=file restore ACLs (inverse of `getfacl -R')\n"
+" --test test mode (ACLs are not modified)\n"
+msgstr ""
+" -R, --recursive gå rekursivt ner i underkataloger\n"
+" -L, --logical logisk väg, följ symboliska länkar\n"
+" -P, --physical fysisk väg, följ inte symboliska länkar\n"
+" --restore=fil återställ ACL:er (invers av \"getfacl -R\")\n"
+" --test testläge (ACL:er ändras inte)\n"
+
+#: ../setfacl/setfacl.c:274
+#: ../getfacl/getfacl.c:558
+msgid ""
+" --version print version and exit\n"
+" --help this help text\n"
+msgstr ""
+" --version skriv ut version och avsluta\n"
+" --help denna hjälptext\n"
+
+#: ../setfacl/setfacl.c:493
+#, c-format
+msgid "%s: Option -%c incomplete\n"
+msgstr "%s: Flaggan -%c inte komplett\n"
+
+#: ../setfacl/setfacl.c:498
+#, c-format
+msgid "%s: Option -%c: %s near character %d\n"
+msgstr "%s: Flaggan -%c: %s nära tecknet %d\n"
+
+#: ../setfacl/setfacl.c:584
+#, c-format
+msgid "%s: %s in line %d of file %s\n"
+msgstr "%s: %s på rad %d i filen %s\n"
+
+#: ../setfacl/setfacl.c:592
+#, c-format
+msgid "%s: %s in line %d of standard input\n"
+msgstr "%s: %s på rad %d i standard in\n"
+
+#: ../setfacl/setfacl.c:703
+#: ../getfacl/getfacl.c:774
+#, c-format
+msgid "Try `%s --help' for more information.\n"
+msgstr "Prova \"%s --help\" för mer information.\n"
+
+#: ../getfacl/getfacl.c:462
+#, c-format
+msgid "%s: Removing leading '/' from absolute path names\n"
+msgstr "%s: Tar bort inledande \"/\" från absoluta sökvägar\n"
+
+#: ../getfacl/getfacl.c:531
+#, c-format
+msgid "%s %s -- get file access control lists\n"
+msgstr "%s %s -- hämta filåtkomstkontrollistor\n"
+
+#: ../getfacl/getfacl.c:533
+#: ../getfacl/getfacl.c:772
+#, c-format
+msgid "Usage: %s [-%s] file ...\n"
+msgstr "Användning: %s [-%s] fil ...\n"
+
+#: ../getfacl/getfacl.c:539
+msgid " -d, --default display the default access control list\n"
+msgstr " -d, --default visa standardåtkomstkontrollistan\n"
+
+#: ../getfacl/getfacl.c:543
+msgid ""
+" --access display the file access control list only\n"
+" -d, --default display the default access control list only\n"
+" --omit-header do not display the comment header\n"
+" --all-effective print all effective rights\n"
+" --no-effective print no effective rights\n"
+" --skip-base skip files that only have the base entries\n"
+" -R, --recursive recurse into subdirectories\n"
+" -L, --logical logical walk, follow symbolic links\n"
+" -P --physical physical walk, do not follow symbolic links\n"
+" --tabular use tabular output format\n"
+" --numeric print numeric user/group identifiers\n"
+" --absolute-names don't strip leading '/' in pathnames\n"
+msgstr ""
+" --access visa endast filåtkomstkontrollistan\n"
+" -d, --default visa endast standardåtkomstkontrollistan\n"
+" --omit-header visa inte kommentarshuvudet\n"
+" --all-effective skriv ut alla effektiva rättigheter\n"
+" --no-effective skriv inte ut några effektiva rättigheter\n"
+" --skip-base hoppa över filer som endast har basposterna\n"
+" -R, --recursive gå rekursivt ner i underkataloger\n"
+" -L, --logical logisk väg, följ symboliska länkar\n"
+" -P --physical fysisk väg, följ inte symboliska länkar\n"
+" --tabular använd tabulerat utformat\n"
+" --numeric skriv ut numeriska identifierare för användare/grupp\n"
+" --absolute-names ta inte bort inledande \"/\" i sökvägar\n"
+
+#: ../getfacl/getfacl.c:760
+#, c-format
+msgid "%s: Standard input: %s\n"
+msgstr "%s: Standard in: %s\n"
+
+#: ../libacl/acl_error.c:34
+msgid "Multiple entries of same type"
+msgstr "Flera poster av samma typ"
+
+#: ../libacl/acl_error.c:36
+msgid "Duplicate entries"
+msgstr "Dubbla poster"
+
+#: ../libacl/acl_error.c:38
+msgid "Missing or wrong entry"
+msgstr "Saknad eller felaktig post"
+
+#: ../libacl/acl_error.c:40
+msgid "Invalid entry type"
+msgstr "Ogiltig posttyp"
+
+#: ../libacl/perm_copy_fd.c:123
+#: ../libacl/perm_copy_fd.c:135
+#: ../libacl/perm_copy_fd.c:197
+#: ../libacl/perm_copy_file.c:123
+#: ../libacl/perm_copy_file.c:138
+#: ../libacl/perm_copy_file.c:149
+#: ../libacl/perm_copy_file.c:234
+#, c-format
+msgid "setting permissions for %s"
+msgstr "ställer in rättigheter för %s"
+
+#: ../libacl/perm_copy_fd.c:185
+#: ../libacl/perm_copy_file.c:198
+#: ../libacl/perm_copy_file.c:223
+#, c-format
+msgid "preserving permissions for %s"
+msgstr "bevarar rättigheter för %s"
+
diff --git a/setfacl/Makefile b/setfacl/Makefile
new file mode 100644
index 0000000..46b74d9
--- /dev/null
+++ b/setfacl/Makefile
@@ -0,0 +1,36 @@
+#
+# Copyright (c) 2000, 2002 Silicon Graphics, Inc. All Rights Reserved.
+#
+# 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 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, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+
+TOPDIR = ..
+include $(TOPDIR)/include/builddefs
+
+LTCOMMAND = setfacl
+CFILES = setfacl.c do_set.c sequence.c parse.c
+HFILES = sequence.h parse.h
+
+LLDLIBS = $(LIBMISC) $(LIBACL) $(LIBATTR)
+LTDEPENDENCIES = $(LIBMISC) $(LIBACL)
+
+default: $(LTCOMMAND)
+
+include $(BUILDRULES)
+
+install: default
+ $(INSTALL) -m 755 -d $(PKG_BIN_DIR)
+ $(LTINSTALL) -m 755 $(LTCOMMAND) $(PKG_BIN_DIR)
+install-dev install-lib:
diff --git a/setfacl/do_set.c b/setfacl/do_set.c
new file mode 100644
index 0000000..b9c0ce7
--- /dev/null
+++ b/setfacl/do_set.c
@@ -0,0 +1,524 @@
+/*
+ File: do_set.c
+ (Linux Access Control List Management)
+
+ Copyright (C) 1999, 2000
+ Andreas Gruenbacher, <a.gruenbacher@bestbits.at>
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#include <stdio.h>
+#include <errno.h>
+#include <sys/acl.h>
+#include <acl/libacl.h>
+
+#include <stdlib.h>
+#include <string.h>
+#include <getopt.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <dirent.h>
+#include <ftw.h>
+#include "sequence.h"
+#include "parse.h"
+#include "config.h"
+#include "walk_tree.h"
+
+
+extern const char *progname;
+extern int opt_recalculate;
+extern int opt_test;
+extern int print_options;
+
+acl_entry_t
+find_entry(
+ acl_t acl,
+ acl_tag_t type,
+ id_t id)
+{
+ acl_entry_t ent;
+ acl_tag_t e_type;
+ id_t *e_id_p;
+
+ if (acl_get_entry(acl, ACL_FIRST_ENTRY, &ent) != 1)
+ return NULL;
+
+ for(;;) {
+ acl_get_tag_type(ent, &e_type);
+ if (type == e_type) {
+ if (id != ACL_UNDEFINED_ID) {
+ e_id_p = acl_get_qualifier(ent);
+ if (e_id_p == NULL)
+ return NULL;
+ if (*e_id_p == id) {
+ acl_free(e_id_p);
+ return ent;
+ }
+ acl_free(e_id_p);
+ } else {
+ return ent;
+ }
+ }
+ if (acl_get_entry(acl, ACL_NEXT_ENTRY, &ent) != 1)
+ return NULL;
+ }
+}
+
+int
+has_execute_perms(
+ acl_t acl)
+{
+ acl_entry_t ent;
+
+ if (acl_get_entry(acl, ACL_FIRST_ENTRY, &ent) != 1)
+ return 0;
+
+ for(;;) {
+ acl_permset_t permset;
+
+ acl_get_permset(ent, &permset);
+ if (acl_get_perm(permset, ACL_EXECUTE) != 0)
+ return 1;
+
+ if (acl_get_entry(acl, ACL_NEXT_ENTRY, &ent) != 1)
+ return 0;
+ }
+}
+
+int
+clone_entry(
+ acl_t from_acl,
+ acl_tag_t from_type,
+ acl_t *to_acl,
+ acl_tag_t to_type)
+{
+ acl_entry_t from_entry, to_entry;
+ from_entry = find_entry(from_acl, from_type, ACL_UNDEFINED_ID);
+ if (from_entry) {
+ if (acl_create_entry(to_acl, &to_entry) != 0)
+ return -1;
+ acl_copy_entry(to_entry, from_entry);
+ acl_set_tag_type(to_entry, to_type);
+ return 0;
+ } else {
+ return 1;
+ }
+}
+
+
+void
+print_test(
+ FILE *file,
+ const char *path_p,
+ const struct stat *st,
+ const acl_t acl,
+ const acl_t default_acl)
+{
+ char *acl_text, *default_acl_text;
+
+ acl_text = acl_to_any_text(acl, NULL, ',', TEXT_ABBREVIATE);
+ default_acl_text =
+ acl_to_any_text(default_acl, "d:", ',', TEXT_ABBREVIATE);
+ fprintf(file, "%s: %s,%s\n", path_p,
+ acl_text ? acl_text : "*",
+ default_acl_text ? default_acl_text : "*");
+ acl_free(acl_text);
+ acl_free(default_acl_text);
+}
+
+
+static void
+set_perm(
+ acl_entry_t ent,
+ mode_t perm)
+{
+ acl_permset_t set;
+
+ acl_get_permset(ent, &set);
+ if (perm & CMD_PERM_READ)
+ acl_add_perm(set, ACL_READ);
+ else
+ acl_delete_perm(set, ACL_READ);
+ if (perm & CMD_PERM_WRITE)
+ acl_add_perm(set, ACL_WRITE);
+ else
+ acl_delete_perm(set, ACL_WRITE);
+ if (perm & CMD_PERM_EXECUTE)
+ acl_add_perm(set, ACL_EXECUTE);
+ else
+ acl_delete_perm(set, ACL_EXECUTE);
+}
+
+
+static int
+retrieve_acl(
+ const char *path_p,
+ acl_type_t type,
+ const struct stat *st,
+ acl_t *old_acl,
+ acl_t *acl)
+{
+ if (*acl)
+ return 0;
+ *acl = NULL;
+ if (type == ACL_TYPE_ACCESS || S_ISDIR(st->st_mode)) {
+ *old_acl = acl_get_file(path_p, type);
+ if (*old_acl == NULL && (errno == ENOSYS || errno == ENOTSUP)) {
+ if (type == ACL_TYPE_DEFAULT)
+ *old_acl = acl_init(0);
+ else
+ *old_acl = acl_from_mode(st->st_mode);
+ }
+ } else
+ *old_acl = acl_init(0);
+ if (*old_acl == NULL)
+ return -1;
+ *acl = acl_dup(*old_acl);
+ if (*acl == NULL)
+ return -1;
+ return 0;
+}
+
+
+static int
+remove_extended_entries(
+ acl_t acl)
+{
+ acl_entry_t ent, group_obj;
+ acl_permset_t mask_permset, group_obj_permset;
+ acl_tag_t tag;
+ int error;
+
+ /*
+ * Removing the ACL_MASK entry from the ACL results in
+ * increased permissions for the owning group if the
+ * ACL_GROUP_OBJ entry contains permissions not contained
+ * in the ACL_MASK entry. We remove these permissions from
+ * the ACL_GROUP_OBJ entry to avoid that.
+ *
+ * After removing the ACL, the file owner and the owning group
+ * therefore have the same permissions as before.
+ */
+
+ ent = find_entry(acl, ACL_MASK, ACL_UNDEFINED_ID);
+ group_obj = find_entry(acl, ACL_GROUP_OBJ, ACL_UNDEFINED_ID);
+ if (ent && group_obj) {
+ if (!acl_get_permset(ent, &mask_permset) &&
+ !acl_get_permset(group_obj, &group_obj_permset)) {
+ if (!acl_get_perm(mask_permset, ACL_READ))
+ acl_delete_perm(group_obj_permset, ACL_READ);
+ if (!acl_get_perm(mask_permset, ACL_WRITE))
+ acl_delete_perm(group_obj_permset, ACL_WRITE);
+ if (!acl_get_perm(mask_permset, ACL_EXECUTE))
+ acl_delete_perm(group_obj_permset, ACL_EXECUTE);
+ }
+ }
+
+ error = acl_get_entry(acl, ACL_FIRST_ENTRY, &ent);
+ while (error == 1) {
+ acl_get_tag_type(ent, &tag);
+ switch(tag) {
+ case ACL_USER:
+ case ACL_GROUP:
+ case ACL_MASK:
+ acl_delete_entry(acl, ent);
+ break;
+ default:
+ break;
+ }
+
+ error = acl_get_entry(acl, ACL_NEXT_ENTRY, &ent);
+ }
+ if (error < 0)
+ return -1;
+ return 0;
+}
+
+
+#define RETRIEVE_ACL(type) do { \
+ error = retrieve_acl(path_p, type, st, old_xacl, xacl); \
+ if (error) \
+ goto fail; \
+ } while(0)
+
+int
+do_set(
+ const char *path_p,
+ const struct stat *st,
+ int walk_flags,
+ void *arg)
+{
+ const seq_t seq = (const seq_t)arg;
+ acl_t old_acl = NULL, old_default_acl = NULL;
+ acl_t acl = NULL, default_acl = NULL;
+ acl_t *xacl, *old_xacl;
+ acl_entry_t ent;
+ cmd_t cmd;
+ int which_entry;
+ int errors = 0, error;
+ char *acl_text;
+ int acl_modified = 0, default_acl_modified = 0;
+ int acl_mask_provided = 0, default_acl_mask_provided = 0;
+
+ if (walk_flags & WALK_TREE_FAILED) {
+ fprintf(stderr, "%s: %s: %s\n", progname, path_p, strerror(errno));
+ return 1;
+ }
+
+ /*
+ * Symlinks can never have ACLs, so when doing a physical walk, we
+ * skip symlinks altogether, and when doing a half-logical walk, we
+ * skip all non-toplevel symlinks.
+ */
+ if ((walk_flags & WALK_TREE_SYMLINK) &&
+ ((walk_flags & WALK_TREE_PHYSICAL) ||
+ !(walk_flags & (WALK_TREE_TOPLEVEL | WALK_TREE_LOGICAL))))
+ return 0;
+
+ /* Execute the commands in seq (read ACLs on demand) */
+ error = seq_get_cmd(seq, SEQ_FIRST_CMD, &cmd);
+ if (error == 0)
+ return 0;
+ while (error == 1) {
+ mode_t perm = cmd->c_perm;
+
+ if (cmd->c_type == ACL_TYPE_ACCESS) {
+ xacl = &acl;
+ old_xacl = &old_acl;
+ acl_modified = 1;
+ if (cmd->c_tag == ACL_MASK)
+ acl_mask_provided = 1;
+ } else {
+ xacl = &default_acl;
+ old_xacl = &old_default_acl;
+ default_acl_modified = 1;
+ if (cmd->c_tag == ACL_MASK)
+ default_acl_mask_provided = 1;
+ }
+
+ RETRIEVE_ACL(cmd->c_type);
+
+ /* Check for `X', and replace with `x' as appropriate. */
+ if (perm & CMD_PERM_COND_EXECUTE) {
+ perm &= ~CMD_PERM_COND_EXECUTE;
+ if (S_ISDIR(st->st_mode) || has_execute_perms(*xacl))
+ perm |= CMD_PERM_EXECUTE;
+ }
+
+ switch(cmd->c_cmd) {
+ case CMD_ENTRY_REPLACE:
+ ent = find_entry(*xacl, cmd->c_tag, cmd->c_id);
+ if (!ent) {
+ if (acl_create_entry(xacl, &ent) != 0)
+ goto fail;
+ acl_set_tag_type(ent, cmd->c_tag);
+ if (cmd->c_id != ACL_UNDEFINED_ID)
+ acl_set_qualifier(ent,
+ &cmd->c_id);
+ }
+ set_perm(ent, perm);
+ break;
+
+ case CMD_REMOVE_ENTRY:
+ ent = find_entry(*xacl, cmd->c_tag, cmd->c_id);
+ if (ent)
+ acl_delete_entry(*xacl, ent);
+ else
+ /* ignore */;
+ break;
+
+ case CMD_REMOVE_EXTENDED_ACL:
+ remove_extended_entries(acl);
+ break;
+
+ case CMD_REMOVE_ACL:
+ acl_free(*xacl);
+ *xacl = acl_init(5);
+ if (!*xacl)
+ goto fail;
+ break;
+
+ default:
+ errno = EINVAL;
+ goto fail;
+ }
+
+ error = seq_get_cmd(seq, SEQ_NEXT_CMD, &cmd);
+ }
+
+ if (error < 0)
+ goto fail;
+
+ /* Try to fill in missing entries */
+ if (default_acl && acl_entries(default_acl) != 0) {
+ xacl = &acl;
+ old_xacl = &old_acl;
+
+ if (!find_entry(default_acl, ACL_USER_OBJ, ACL_UNDEFINED_ID)) {
+ if (!acl)
+ RETRIEVE_ACL(ACL_TYPE_ACCESS);
+ clone_entry(acl, ACL_USER_OBJ,
+ &default_acl, ACL_USER_OBJ);
+ }
+ if (!find_entry(default_acl, ACL_GROUP_OBJ, ACL_UNDEFINED_ID)) {
+ if (!acl)
+ RETRIEVE_ACL(ACL_TYPE_ACCESS);
+ clone_entry(acl, ACL_GROUP_OBJ,
+ &default_acl, ACL_GROUP_OBJ);
+ }
+ if (!find_entry(default_acl, ACL_OTHER, ACL_UNDEFINED_ID)) {
+ if (!acl)
+ RETRIEVE_ACL(ACL_TYPE_ACCESS);
+ clone_entry(acl, ACL_OTHER,
+ &default_acl, ACL_OTHER);
+ }
+ }
+
+ /* update mask entries and check if ACLs are valid */
+ if (acl && acl_modified) {
+ if (acl_equiv_mode(acl, NULL) != 0) {
+ if (!acl_mask_provided &&
+ !find_entry(acl, ACL_MASK, ACL_UNDEFINED_ID))
+ clone_entry(acl, ACL_GROUP_OBJ,
+ &acl, ACL_MASK);
+ if (opt_recalculate != -1 &&
+ (!acl_mask_provided || opt_recalculate == 1))
+ acl_calc_mask(&acl);
+ }
+
+ error = acl_check(acl, &which_entry);
+ if (error < 0)
+ goto fail;
+ if (error > 0) {
+ acl_text = acl_to_any_text(acl, NULL, ',', 0);
+ fprintf(stderr, _("%s: %s: Malformed access ACL "
+ "`%s': %s at entry %d\n"), progname, path_p,
+ acl_text, acl_error(error), which_entry+1);
+ acl_free(acl_text);
+ errors++;
+ goto cleanup;
+ }
+ }
+
+ if (default_acl && acl_entries(default_acl) != 0 &&
+ default_acl_modified) {
+ if (acl_equiv_mode(default_acl, NULL) != 0) {
+ if (!default_acl_mask_provided &&
+ !find_entry(default_acl,ACL_MASK,ACL_UNDEFINED_ID))
+ clone_entry(default_acl, ACL_GROUP_OBJ,
+ &default_acl, ACL_MASK);
+ if (opt_recalculate != -1 &&
+ (!default_acl_mask_provided ||
+ opt_recalculate == 1))
+ acl_calc_mask(&default_acl);
+ }
+
+ error = acl_check(default_acl, &which_entry);
+ if (error < 0)
+ goto fail;
+ if (error > 0) {
+ acl_text = acl_to_any_text(default_acl, NULL, ',', 0);
+ fprintf(stderr, _("%s: %s: Malformed default ACL "
+ "`%s': %s at entry %d\n"),
+ progname, path_p, acl_text,
+ acl_error(error), which_entry+1);
+ acl_free(acl_text);
+ errors++;
+ goto cleanup;
+ }
+ }
+
+ /* Only directores can have default ACLs */
+ if (default_acl && !S_ISDIR(st->st_mode) && (walk_flags & WALK_TREE_RECURSIVE)) {
+ /* In recursive mode, ignore default ACLs for files */
+ acl_free(default_acl);
+ default_acl = NULL;
+ }
+
+ /* check which ACLs have changed */
+ if (acl && old_acl && acl_cmp(old_acl, acl) == 0) {
+ acl_free(acl);
+ acl = NULL;
+ }
+ if ((default_acl && old_default_acl &&
+ acl_cmp(old_default_acl, default_acl) == 0)) {
+ acl_free(default_acl);
+ default_acl = NULL;
+ }
+
+ /* update the file system */
+ if (opt_test) {
+ print_test(stdout, path_p, st,
+ acl, default_acl);
+ goto cleanup;
+ }
+ if (acl) {
+ if (acl_set_file(path_p, ACL_TYPE_ACCESS, acl) != 0) {
+ if (errno == ENOSYS || errno == ENOTSUP) {
+ int saved_errno = errno;
+ mode_t mode;
+
+ if (acl_equiv_mode(acl, &mode) != 0) {
+ errno = saved_errno;
+ goto fail;
+ } else if (chmod(path_p, mode) != 0)
+ goto fail;
+ } else
+ goto fail;
+ }
+ }
+ if (default_acl) {
+ if (S_ISDIR(st->st_mode)) {
+ if (acl_entries(default_acl) == 0) {
+ if (acl_delete_def_file(path_p) != 0 &&
+ errno != ENOSYS && errno != ENOTSUP)
+ goto fail;
+ } else {
+ if (acl_set_file(path_p, ACL_TYPE_DEFAULT,
+ default_acl) != 0)
+ goto fail;
+ }
+ } else {
+ if (acl_entries(default_acl) != 0) {
+ fprintf(stderr, _("%s: %s: Only directories "
+ "can have default ACLs\n"),
+ progname, path_p);
+ errors++;
+ goto cleanup;
+ }
+ }
+ }
+
+ error = 0;
+
+cleanup:
+ if (acl)
+ acl_free(acl);
+ if (old_acl)
+ acl_free(old_acl);
+ if (default_acl)
+ acl_free(default_acl);
+ if (old_default_acl)
+ acl_free(old_default_acl);
+ return errors;
+
+fail:
+ fprintf(stderr, "%s: %s: %s\n", progname, path_p, strerror(errno));
+ errors++;
+ goto cleanup;
+}
+
diff --git a/setfacl/parse.c b/setfacl/parse.c
new file mode 100644
index 0000000..daa32e2
--- /dev/null
+++ b/setfacl/parse.c
@@ -0,0 +1,566 @@
+/*
+ File: parse.c
+ (Linux Access Control List Management)
+
+ Copyright (C) 1999, 2000
+ Andreas Gruenbacher, <a.gruenbacher@bestbits.at>
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <limits.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <pwd.h>
+#include <grp.h>
+#include "sys/acl.h"
+
+#include "sequence.h"
+#include "parse.h"
+#include "misc.h"
+
+#define SKIP_WS(x) ({ \
+ while (*(x)==' ' || *(x)=='\t' || *(x)=='\n' || *(x)=='\r') \
+ (x)++; \
+ })
+
+
+static int
+skip_tag_name(
+ const char **text_p,
+ const char *token)
+{
+ size_t len = strlen(token);
+ const char *text = *text_p;
+
+ SKIP_WS(text);
+ if (strncmp(text, token, len) == 0) {
+ text += len;
+ goto delimiter;
+ }
+ if (*text == *token) {
+ text++;
+ goto delimiter;
+ }
+ return 0;
+
+delimiter:
+ SKIP_WS(text);
+ if (*text == ':') {
+ *text_p = text+1;
+ return 1;
+ }
+ if (*text == ',' || *text == '\0') {
+ *text_p = text;
+ return 1;
+ }
+ return 0;
+}
+
+
+static char *
+get_token(
+ const char **text_p)
+{
+ char *token = NULL, *t;
+ const char *bp, *ep;
+
+ bp = *text_p;
+ SKIP_WS(bp);
+ ep = bp;
+
+ while (*ep!='\0' && *ep!='\r' && *ep!='\n' && *ep!=':' && *ep!=',')
+ ep++;
+ if (ep == bp)
+ goto after_token;
+ token = (char*)malloc(ep - bp + 1);
+ if (token == NULL)
+ goto after_token;
+ memcpy(token, bp, ep - bp);
+
+ /* Trim trailing whitespace */
+ t = token + (ep - bp - 1);
+ while (t >= token &&
+ (*t==' ' || *t=='\t' || *t=='\n' || *t=='\r'))
+ t--;
+ *(t+1) = '\0';
+
+after_token:
+ if (*ep == ':')
+ ep++;
+ *text_p = ep;
+ return token;
+}
+
+
+static int
+get_id(
+ const char *token,
+ id_t *id_p)
+{
+ char *ep;
+ long l;
+ l = strtol(token, &ep, 0);
+ if (*ep != '\0')
+ return -1;
+ if (l < 0) {
+ /*
+ Negative values are interpreted as 16-bit numbers,
+ so that id -2 maps to 65534 (nobody/nogroup), etc.
+ */
+ l &= 0xFFFF;
+ }
+ *id_p = l;
+ return 0;
+}
+
+
+static int
+get_uid(
+ const char *token,
+ uid_t *uid_p)
+{
+ struct passwd *passwd;
+
+ if (get_id(token, (id_t *)uid_p) == 0)
+ goto accept;
+ passwd = getpwnam(token);
+ if (passwd) {
+ *uid_p = passwd->pw_uid;
+ goto accept;
+ }
+ return -1;
+
+accept:
+ return 0;
+}
+
+
+static int
+get_gid(
+ const char *token,
+ gid_t *gid_p)
+{
+ struct group *group;
+
+ if (get_id(token, (id_t *)gid_p) == 0)
+ goto accept;
+ group = getgrnam(token);
+ if (group) {
+ *gid_p = group->gr_gid;
+ goto accept;
+ }
+ return -1;
+
+accept:
+ return 0;
+}
+
+
+/*
+ Parses the next acl entry in text_p.
+
+ Returns:
+ -1 on error, 0 on success.
+*/
+
+cmd_t
+parse_acl_cmd(
+ const char **text_p,
+ int seq_cmd,
+ int parse_mode)
+{
+ cmd_t cmd = cmd_init();
+ char *str;
+ const char *backup;
+ int error, perm_chars;
+ if (!cmd)
+ return NULL;
+
+ cmd->c_cmd = seq_cmd;
+ if (parse_mode & SEQ_PROMOTE_ACL)
+ cmd->c_type = ACL_TYPE_DEFAULT;
+ else
+ cmd->c_type = ACL_TYPE_ACCESS;
+ cmd->c_id = ACL_UNDEFINED_ID;
+ cmd->c_perm = 0;
+
+ if (parse_mode & SEQ_PARSE_DEFAULT) {
+ /* check for default acl entry */
+ backup = *text_p;
+ if (skip_tag_name(text_p, "default")) {
+ if (parse_mode & SEQ_PROMOTE_ACL) {
+ /* if promoting from acl to default acl and
+ a default acl entry is found, fail. */
+ *text_p = backup;
+ goto fail;
+ }
+ cmd->c_type = ACL_TYPE_DEFAULT;
+ }
+ }
+
+ /* parse acl entry type */
+ switch (**text_p) {
+ case 'u': /* user */
+ skip_tag_name(text_p, "user");
+
+user_entry:
+ backup = *text_p;
+ str = get_token(text_p);
+ if (str) {
+ cmd->c_tag = ACL_USER;
+ error = get_uid(unquote(str), &cmd->c_id);
+ free(str);
+ if (error) {
+ *text_p = backup;
+ goto fail;
+ }
+ } else {
+ cmd->c_tag = ACL_USER_OBJ;
+ }
+ break;
+
+ case 'g': /* group */
+ if (!skip_tag_name(text_p, "group"))
+ goto user_entry;
+
+ backup = *text_p;
+ str = get_token(text_p);
+ if (str) {
+ cmd->c_tag = ACL_GROUP;
+ error = get_gid(unquote(str), &cmd->c_id);
+ free(str);
+ if (error) {
+ *text_p = backup;
+ goto fail;
+ }
+ } else {
+ cmd->c_tag = ACL_GROUP_OBJ;
+ }
+ break;
+
+ case 'o': /* other */
+ if (!skip_tag_name(text_p, "other"))
+ goto user_entry;
+ /* skip empty entry qualifier field (this field may
+ be missing for compatibility with Solaris.) */
+ SKIP_WS(*text_p);
+ if (**text_p == ':')
+ (*text_p)++;
+ cmd->c_tag = ACL_OTHER;
+ break;
+
+ case 'm': /* mask */
+ if (!skip_tag_name(text_p, "mask"))
+ goto user_entry;
+ /* skip empty entry qualifier field (this field may
+ be missing for compatibility with Solaris.) */
+ SKIP_WS(*text_p);
+ if (**text_p == ':')
+ (*text_p)++;
+ cmd->c_tag = ACL_MASK;
+ break;
+
+ default: /* assume "user:" */
+ goto user_entry;
+ }
+
+ SKIP_WS(*text_p);
+ if (**text_p == ',' || **text_p == '\0') {
+ if (parse_mode & SEQ_PARSE_NO_PERM)
+ return cmd;
+ else
+ goto fail;
+ }
+ if (!(parse_mode & SEQ_PARSE_WITH_PERM))
+ return cmd;
+
+ /* parse permissions */
+ SKIP_WS(*text_p);
+ if (**text_p >= '0' && **text_p <= '7') {
+ cmd->c_perm = 0;
+ while (**text_p == '0')
+ (*text_p)++;
+ if (**text_p >= '1' && **text_p <= '7') {
+ cmd->c_perm = (*(*text_p)++ - '0');
+ }
+
+ return cmd;
+ }
+
+ for (perm_chars=0; perm_chars<3; perm_chars++, (*text_p)++) {
+ switch(**text_p) {
+ case 'r': /* read */
+ if (cmd->c_perm & CMD_PERM_READ)
+ goto fail;
+ cmd->c_perm |= CMD_PERM_READ;
+ break;
+
+ case 'w': /* write */
+ if (cmd->c_perm & CMD_PERM_WRITE)
+ goto fail;
+ cmd->c_perm |= CMD_PERM_WRITE;
+ break;
+
+ case 'x': /* execute */
+ if (cmd->c_perm & CMD_PERM_EXECUTE)
+ goto fail;
+ cmd->c_perm |= CMD_PERM_EXECUTE;
+ break;
+
+ case 'X': /* execute only if directory or some
+ entries already have execute permissions
+ set */
+ if (cmd->c_perm & CMD_PERM_COND_EXECUTE)
+ goto fail;
+ cmd->c_perm |= CMD_PERM_COND_EXECUTE;
+ break;
+
+ case '-':
+ /* ignore */
+ break;
+
+ default:
+ if (perm_chars == 0)
+ goto fail;
+ return cmd;
+ }
+ }
+ if (perm_chars != 3)
+ goto fail;
+ return cmd;
+
+fail:
+ cmd_free(cmd);
+ return NULL;
+}
+
+
+/*
+ Parse a comma-separated list of acl entries.
+
+ which is set to the index of the first character that was not parsed,
+ or -1 in case of success.
+*/
+int
+parse_acl_seq(
+ seq_t seq,
+ const char *text_p,
+ int *which,
+ int seq_cmd,
+ int parse_mode)
+{
+ const char *initial_text_p = text_p;
+ cmd_t cmd;
+
+ if (which)
+ *which = -1;
+
+ while (*text_p != '\0') {
+ cmd = parse_acl_cmd(&text_p, seq_cmd, parse_mode);
+ if (cmd == NULL) {
+ errno = EINVAL;
+ goto fail;
+ }
+ if (seq_append(seq, cmd) != 0) {
+ cmd_free(cmd);
+ goto fail;
+ }
+ SKIP_WS(text_p);
+ if (*text_p != ',')
+ break;
+ text_p++;
+ }
+
+ if (*text_p != '\0') {
+ errno = EINVAL;
+ goto fail;
+ }
+
+ return 0;
+
+fail:
+ if (which)
+ *which = (text_p - initial_text_p);
+ return -1;
+}
+
+
+
+int
+read_acl_comments(
+ FILE *file,
+ int *line,
+ char **path_p,
+ uid_t *uid_p,
+ gid_t *gid_p)
+{
+ int c;
+ /*
+ Max PATH_MAX bytes even for UTF-8 path names and additional 9
+ bytes for "# file: ". Not a good solution but for now it is the
+ best I can do without too much impact on the code. [tw]
+ */
+ char linebuf[(4*PATH_MAX)+9];
+ char *cp;
+ char *p;
+ int comments_read = 0;
+
+ if (path_p)
+ *path_p = NULL;
+ if (uid_p)
+ *uid_p = ACL_UNDEFINED_ID;
+ if (gid_p)
+ *gid_p = ACL_UNDEFINED_ID;
+
+ for(;;) {
+ c = fgetc(file);
+ if (c == EOF)
+ break;
+ if (c==' ' || c=='\t' || c=='\r' || c=='\n') {
+ if (c=='\n')
+ (*line)++;
+ continue;
+ }
+ if (c != '#') {
+ ungetc(c, file);
+ break;
+ }
+ if (line)
+ (*line)++;
+
+ if (fgets(linebuf, sizeof(linebuf), file) == NULL)
+ break;
+
+ comments_read = 1;
+
+ p = strrchr(linebuf, '\0');
+ while (p > linebuf &&
+ (*(p-1)=='\r' || *(p-1)=='\n')) {
+ p--;
+ *p = '\0';
+ }
+
+ cp = linebuf;
+ SKIP_WS(cp);
+ if (strncmp(cp, "file:", 5) == 0) {
+ cp += 5;
+ SKIP_WS(cp);
+ cp = unquote(cp);
+
+ if (path_p) {
+ if (*path_p)
+ goto fail;
+ *path_p = (char*)malloc(strlen(cp)+1);
+ if (!*path_p)
+ return -1;
+ strcpy(*path_p, cp);
+ }
+ } else if (strncmp(cp, "owner:", 6) == 0) {
+ cp += 6;
+ SKIP_WS(cp);
+
+ if (uid_p) {
+ if (*uid_p != ACL_UNDEFINED_ID)
+ goto fail;
+ if (get_uid(unquote(cp), uid_p) != 0)
+ continue;
+ }
+ } else if (strncmp(cp, "group:", 6) == 0) {
+ cp += 6;
+ SKIP_WS(cp);
+
+ if (gid_p) {
+ if (*gid_p != ACL_UNDEFINED_ID)
+ goto fail;
+ if (get_gid(unquote(cp), gid_p) != 0)
+ continue;
+ }
+ }
+ }
+ if (ferror(file))
+ return -1;
+ return comments_read;
+fail:
+ if (path_p && *path_p)
+ free(*path_p);
+ return -1;
+}
+
+
+int
+read_acl_seq(
+ FILE *file,
+ seq_t seq,
+ int seq_cmd,
+ int parse_mode,
+ int *line,
+ int *which)
+{
+ char linebuf[1024];
+ const char *cp;
+ cmd_t cmd;
+
+ if (which)
+ *which = -1;
+
+ for(;;) {
+ if (fgets(linebuf, sizeof(linebuf), file) == NULL)
+ break;
+ if (line)
+ (*line)++;
+
+ cp = linebuf;
+ SKIP_WS(cp);
+ if (*cp == '\0') {
+ if (!(parse_mode & SEQ_PARSE_MULTI))
+ continue;
+ break;
+ } else if (*cp == '#') {
+ continue;
+ }
+
+ cmd = parse_acl_cmd(&cp, seq_cmd, parse_mode);
+ if (cmd == NULL) {
+ errno = EINVAL;
+ goto fail;
+ }
+ if (seq_append(seq, cmd) != 0) {
+ cmd_free(cmd);
+ goto fail;
+ }
+
+ SKIP_WS(cp);
+ if (*cp != '\0' && *cp != '#') {
+ errno = EINVAL;
+ goto fail;
+ }
+ }
+
+ if (ferror(file))
+ goto fail;
+ return 0;
+
+fail:
+ if (which)
+ *which = (cp - linebuf);
+ return -1;
+}
+
diff --git a/setfacl/parse.h b/setfacl/parse.h
new file mode 100644
index 0000000..b6b7e01
--- /dev/null
+++ b/setfacl/parse.h
@@ -0,0 +1,84 @@
+/*
+ File: parse.h
+ (Linux Access Control List Management)
+
+ Copyright (C) 1999 by Andreas Gruenbacher
+ <a.gruenbacher@computer.org>
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#ifndef __PARSE_H
+#define __PARSE_H
+
+
+#include <stdlib.h>
+#include <sys/types.h>
+#include "sequence.h"
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/* parse options */
+
+#define SEQ_PARSE_WITH_PERM (0x0001)
+#define SEQ_PARSE_NO_PERM (0x0002)
+#define SEQ_PARSE_ANY_PERM (0x0001|0x0002)
+
+#define SEQ_PARSE_MULTI (0x0010)
+#define SEQ_PARSE_DEFAULT (0x0020) /* "default:" = default acl */
+
+#define SEQ_PROMOTE_ACL (0x0040) /* promote from acl
+ to default acl */
+
+cmd_t
+parse_acl_cmd(
+ const char **text_p,
+ int seq_cmd,
+ int parse_mode);
+int
+parse_acl_seq(
+ seq_t seq,
+ const char *text_p,
+ int *which,
+ int seq_cmd,
+ int parse_mode);
+int
+read_acl_comments(
+ FILE *file,
+ int *line,
+ char **path_p,
+ uid_t *uid_p,
+ gid_t *gid_p);
+int
+read_acl_seq(
+ FILE *file,
+ seq_t seq,
+ int seq_cmd,
+ int parse_mode,
+ int *line,
+ int *which);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif /* __PARSE_H */
+
diff --git a/setfacl/sequence.c b/setfacl/sequence.c
new file mode 100644
index 0000000..a418b23
--- /dev/null
+++ b/setfacl/sequence.c
@@ -0,0 +1,162 @@
+/*
+ File: sequence.c
+ (Linux Access Control List Management)
+
+ Copyright (C) 1999, 2000
+ Andreas Gruenbacher, <a.gruenbacher@bestbits.at>
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+
+#include <stdlib.h>
+#include "sequence.h"
+
+
+cmd_t
+cmd_init(
+ void)
+{
+ return (cmd_t)malloc(sizeof(struct cmd_obj));
+}
+
+
+void
+cmd_free(
+ cmd_t cmd)
+{
+ free(cmd);
+}
+
+
+seq_t
+seq_init(
+ void)
+{
+ seq_t seq = (seq_t)malloc(sizeof(struct seq_obj));
+ if (seq == NULL)
+ return NULL;
+ seq->s_first = seq->s_last = NULL;
+ return seq;
+}
+
+
+int
+seq_free(
+ seq_t seq)
+{
+ cmd_t cmd = seq->s_first;
+ while (cmd) {
+ seq->s_first = seq->s_first->c_next;
+ cmd_free(cmd);
+ cmd = seq->s_first;
+ }
+ free(seq);
+ return 0;
+}
+
+
+int
+seq_empty(
+ seq_t seq)
+{
+ return (seq->s_first == NULL);
+}
+
+
+int
+seq_append(
+ seq_t seq,
+ cmd_t cmd)
+{
+ cmd->c_next = NULL;
+ if (seq->s_first == NULL) {
+ seq->s_first = seq->s_last = cmd;
+ } else {
+ seq->s_last->c_next = cmd;
+ seq->s_last = cmd;
+ }
+ return 0;
+}
+
+
+int
+seq_append_cmd(
+ seq_t seq,
+ cmd_tag_t cmd,
+ acl_type_t type)
+{
+ cmd_t cmd_d = cmd_init();
+ if (cmd_d == NULL)
+ return -1;
+ cmd_d->c_cmd = cmd;
+ cmd_d->c_type = type;
+ if (seq_append(seq, cmd_d) != 0) {
+ cmd_free(cmd_d);
+ return -1;
+ }
+ return 0;
+}
+
+
+int
+seq_get_cmd(
+ seq_t seq,
+ int which,
+ cmd_t *cmd)
+{
+ if (which == SEQ_FIRST_CMD) {
+ if (seq->s_first == NULL)
+ return 0;
+ if (cmd)
+ *cmd = seq->s_first;
+ return 1;
+ } else if (which == SEQ_NEXT_CMD) {
+ if (cmd == NULL)
+ return -1;
+ if (*cmd) {
+ *cmd = (*cmd)->c_next;
+ return (*cmd == NULL) ? 0 : 1;
+ }
+ return 0;
+ } else {
+ return -1;
+ }
+}
+
+
+int
+seq_delete_cmd(
+ seq_t seq,
+ cmd_t cmd)
+{
+ cmd_t prev = seq->s_first;
+
+ if (cmd == seq->s_first) {
+ seq->s_first = seq->s_first->c_next;
+ cmd_free(cmd);
+ return 0;
+ }
+ while (prev != NULL && prev->c_next != cmd)
+ prev = prev->c_next;
+ if (prev == NULL)
+ return -1;
+ if (cmd == seq->s_last)
+ seq->s_last = prev;
+ prev->c_next = cmd->c_next;
+ cmd_free(cmd);
+ return 0;
+}
+
diff --git a/setfacl/sequence.h b/setfacl/sequence.h
new file mode 100644
index 0000000..c5d7403
--- /dev/null
+++ b/setfacl/sequence.h
@@ -0,0 +1,115 @@
+/*
+ File: sequence.h
+ (Linux Access Control List Management)
+
+ Copyright (C) 1999 by Andreas Gruenbacher
+ <a.gruenbacher@computer.org>
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+
+#ifndef __SEQUENCE_H
+#define __SEQUENCE_H
+
+
+#include <sys/acl.h>
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+typedef unsigned int cmd_tag_t;
+
+struct cmd_obj {
+ cmd_tag_t c_cmd;
+ acl_type_t c_type;
+ acl_tag_t c_tag;
+ uid_t c_id;
+ mode_t c_perm;
+ struct cmd_obj *c_next;
+};
+
+typedef struct cmd_obj *cmd_t;
+
+struct seq_obj {
+ cmd_t s_first;
+ cmd_t s_last;
+};
+
+typedef struct seq_obj *seq_t;
+
+/* command types */
+#define CMD_ENTRY_REPLACE (0)
+#define CMD_REMOVE_ENTRY (3)
+#define CMD_REMOVE_EXTENDED_ACL (4)
+#define CMD_REMOVE_ACL (5)
+
+/* constants for permission specifiers */
+#define CMD_PERM_READ (4)
+#define CMD_PERM_WRITE (2)
+#define CMD_PERM_EXECUTE (1)
+#define CMD_PERM_COND_EXECUTE (8)
+
+/* iteration over command sequence */
+#define SEQ_FIRST_CMD (0)
+#define SEQ_NEXT_CMD (1)
+
+/* command sequence manipulation */
+
+cmd_t
+cmd_init(
+ void);
+void
+cmd_free(
+ cmd_t cmd);
+seq_t
+seq_init(
+ void);
+int
+seq_free(
+ seq_t seq);
+int
+seq_empty(
+ seq_t seq);
+int
+seq_append(
+ seq_t seq,
+ cmd_t cmd);
+int
+seq_append_cmd(
+ seq_t seq,
+ cmd_tag_t cmd,
+ acl_type_t type);
+int
+seq_get_cmd(
+ seq_t seq,
+ int which,
+ cmd_t *cmd);
+int
+seq_delete_cmd(
+ seq_t seq,
+ cmd_t cmd);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif /* __SEQUENCE_H */
+
diff --git a/setfacl/setfacl.c b/setfacl/setfacl.c
new file mode 100644
index 0000000..7d94350
--- /dev/null
+++ b/setfacl/setfacl.c
@@ -0,0 +1,640 @@
+/*
+ File: setfacl.c
+ (Linux Access Control List Management)
+
+ Copyright (C) 1999-2002
+ Andreas Gruenbacher, <a.gruenbacher@bestbits.at>
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#include <limits.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+#include <errno.h>
+#include <sys/stat.h>
+#include <dirent.h>
+#include <libgen.h>
+#include <getopt.h>
+#include <locale.h>
+#include "config.h"
+#include "sequence.h"
+#include "parse.h"
+#include "walk_tree.h"
+#include "misc.h"
+
+extern int do_set(const char *path_p, const struct stat *stat_p, int flags, void *arg);
+
+#define POSIXLY_CORRECT_STR "POSIXLY_CORRECT"
+
+/* '-' stands for `process non-option arguments in loop' */
+#if !POSIXLY_CORRECT
+# define CMD_LINE_OPTIONS "-:bkndvhm:M:x:X:RLP"
+# define CMD_LINE_SPEC "[-bkndRLP] { -m|-M|-x|-X ... } file ..."
+#endif
+#define POSIXLY_CMD_LINE_OPTIONS "-:bkndvhm:M:x:X:"
+#define POSIXLY_CMD_LINE_SPEC "[-bknd] {-m|-M|-x|-X ... } file ..."
+
+struct option long_options[] = {
+#if !POSIXLY_CORRECT
+ { "set", 1, 0, 's' },
+ { "set-file", 1, 0, 'S' },
+
+ { "mask", 0, 0, 'r' },
+ { "recursive", 0, 0, 'R' },
+ { "logical", 0, 0, 'L' },
+ { "physical", 0, 0, 'P' },
+ { "restore", 1, 0, 'B' },
+ { "test", 0, 0, 't' },
+#endif
+ { "modify", 1, 0, 'm' },
+ { "modify-file", 1, 0, 'M' },
+ { "remove", 1, 0, 'x' },
+ { "remove-file", 1, 0, 'X' },
+
+ { "default", 0, 0, 'd' },
+ { "no-mask", 0, 0, 'n' },
+ { "remove-all", 0, 0, 'b' },
+ { "remove-default", 0, 0, 'k' },
+ { "version", 0, 0, 'v' },
+ { "help", 0, 0, 'h' },
+ { NULL, 0, 0, 0 },
+};
+
+const char *progname;
+const char *cmd_line_options, *cmd_line_spec;
+
+int walk_flags = WALK_TREE_DEREFERENCE;
+int opt_recalculate; /* recalculate mask entry (0=default, 1=yes, -1=no) */
+int opt_promote; /* promote access ACL to default ACL */
+int opt_test; /* do not write to the file system.
+ Print what would happen instead. */
+#if POSIXLY_CORRECT
+const int posixly_correct = 1; /* Posix compatible behavior! */
+#else
+int posixly_correct; /* Posix compatible behavior? */
+#endif
+int chown_error;
+int promote_warning;
+
+
+static const char *xquote(const char *str)
+{
+ const char *q = quote(str);
+ if (q == NULL) {
+ fprintf(stderr, "%s: %s\n", progname, strerror(errno));
+ exit(1);
+ }
+ return q;
+}
+
+int
+has_any_of_type(
+ cmd_t cmd,
+ acl_type_t acl_type)
+{
+ while (cmd) {
+ if (cmd->c_type == acl_type)
+ return 1;
+ cmd = cmd->c_next;
+ }
+ return 0;
+}
+
+
+#if !POSIXLY_CORRECT
+int
+restore(
+ FILE *file,
+ const char *filename)
+{
+ char *path_p;
+ struct stat st;
+ uid_t uid;
+ gid_t gid;
+ seq_t seq = NULL;
+ int line = 0, backup_line;
+ int error, status = 0;
+
+ memset(&st, 0, sizeof(st));
+
+ for(;;) {
+ backup_line = line;
+ error = read_acl_comments(file, &line, &path_p, &uid, &gid);
+ if (error < 0)
+ goto fail;
+ if (error == 0)
+ return status;
+
+ if (path_p == NULL) {
+ if (filename) {
+ fprintf(stderr, _("%s: %s: No filename found "
+ "in line %d, aborting\n"),
+ progname, xquote(filename),
+ backup_line);
+ } else {
+ fprintf(stderr, _("%s: No filename found in "
+ "line %d of standard input, "
+ "aborting\n"),
+ progname, backup_line);
+ }
+ status = 1;
+ goto getout;
+ }
+
+ if (!(seq = seq_init()))
+ goto fail;
+ if (seq_append_cmd(seq, CMD_REMOVE_ACL, ACL_TYPE_ACCESS) ||
+ seq_append_cmd(seq, CMD_REMOVE_ACL, ACL_TYPE_DEFAULT))
+ goto fail;
+
+ error = read_acl_seq(file, seq, CMD_ENTRY_REPLACE,
+ SEQ_PARSE_WITH_PERM |
+ SEQ_PARSE_DEFAULT |
+ SEQ_PARSE_MULTI,
+ &line, NULL);
+ if (error != 0) {
+ fprintf(stderr, _("%s: %s: %s in line %d\n"),
+ progname, xquote(filename), strerror(errno),
+ line);
+ status = 1;
+ goto getout;
+ }
+
+ error = stat(path_p, &st);
+ if (opt_test && error != 0) {
+ fprintf(stderr, "%s: %s: %s\n", progname,
+ xquote(path_p), strerror(errno));
+ status = 1;
+ }
+
+ error = do_set(path_p, &st, 0, seq);
+ if (error != 0) {
+ status = 1;
+ goto resume;
+ }
+
+ if (uid != ACL_UNDEFINED_ID && uid != st.st_uid)
+ st.st_uid = uid;
+ else
+ st.st_uid = -1;
+ if (gid != ACL_UNDEFINED_ID && gid != st.st_gid)
+ st.st_gid = gid;
+ else
+ st.st_gid = -1;
+ if (!opt_test &&
+ (st.st_uid != -1 || st.st_gid != -1)) {
+ if (chown(path_p, st.st_uid, st.st_gid) != 0) {
+ fprintf(stderr, _("%s: %s: Cannot change "
+ "owner/group: %s\n"),
+ progname, xquote(path_p),
+ strerror(errno));
+ status = 1;
+ }
+ }
+resume:
+ if (path_p) {
+ free(path_p);
+ path_p = NULL;
+ }
+ if (seq) {
+ seq_free(seq);
+ seq = NULL;
+ }
+ }
+
+getout:
+ if (path_p) {
+ free(path_p);
+ path_p = NULL;
+ }
+ if (seq) {
+ seq_free(seq);
+ seq = NULL;
+ }
+ return status;
+
+fail:
+ fprintf(stderr, "%s: %s: %s\n", progname, xquote(filename),
+ strerror(errno));
+ status = 1;
+ goto getout;
+}
+#endif
+
+
+void help(void)
+{
+ printf(_("%s %s -- set file access control lists\n"),
+ progname, VERSION);
+ printf(_("Usage: %s %s\n"),
+ progname, cmd_line_spec);
+ printf(_(
+" -m, --modify=acl modify the current ACL(s) of file(s)\n"
+" -M, --modify-file=file read ACL entries to modify from file\n"
+" -x, --remove=acl remove entries from the ACL(s) of file(s)\n"
+" -X, --remove-file=file read ACL entries to remove from file\n"
+" -b, --remove-all remove all extended ACL entries\n"
+" -k, --remove-default remove the default ACL\n"));
+#if !POSIXLY_CORRECT
+ if (!posixly_correct) {
+ printf(_(
+" --set=acl set the ACL of file(s), replacing the current ACL\n"
+" --set-file=file read ACL entries to set from file\n"
+" --mask do recalculate the effective rights mask\n"));
+ }
+#endif
+ printf(_(
+" -n, --no-mask don't recalculate the effective rights mask\n"
+" -d, --default operations apply to the default ACL\n"));
+#if !POSIXLY_CORRECT
+ if (!posixly_correct) {
+ printf(_(
+" -R, --recursive recurse into subdirectories\n"
+" -L, --logical logical walk, follow symbolic links\n"
+" -P, --physical physical walk, do not follow symbolic links\n"
+" --restore=file restore ACLs (inverse of `getfacl -R')\n"
+" --test test mode (ACLs are not modified)\n"));
+ }
+#endif
+ printf(_(
+" -v, --version print version and exit\n"
+" -h, --help this help text\n"));
+}
+
+
+int next_file(const char *arg, seq_t seq)
+{
+ char *line;
+ int errors = 0;
+
+ if (strcmp(arg, "-") == 0) {
+ while ((line = next_line(stdin)))
+ errors = walk_tree(line, walk_flags, 0, do_set, seq);
+ if (!feof(stdin)) {
+ fprintf(stderr, _("%s: Standard input: %s\n"),
+ progname, strerror(errno));
+ errors = 1;
+ }
+ } else {
+ errors = walk_tree(arg, walk_flags, 0, do_set, seq);
+ }
+ return errors ? 1 : 0;
+}
+
+
+#define ERRNO_ERROR(s) \
+ ({status = (s); goto errno_error; })
+
+
+int main(int argc, char *argv[])
+{
+ int opt;
+ int saw_files = 0;
+ int status = 0;
+ FILE *file;
+ int which;
+ int lineno;
+ int error;
+ seq_t seq;
+ int seq_cmd, parse_mode;
+
+ progname = basename(argv[0]);
+
+#if POSIXLY_CORRECT
+ cmd_line_options = POSIXLY_CMD_LINE_OPTIONS;
+ cmd_line_spec = _(POSIXLY_CMD_LINE_SPEC);
+#else
+ if (getenv(POSIXLY_CORRECT_STR))
+ posixly_correct = 1;
+ if (!posixly_correct) {
+ cmd_line_options = CMD_LINE_OPTIONS;
+ cmd_line_spec = _(CMD_LINE_SPEC);
+ } else {
+ cmd_line_options = POSIXLY_CMD_LINE_OPTIONS;
+ cmd_line_spec = _(POSIXLY_CMD_LINE_SPEC);
+ }
+#endif
+
+ setlocale(LC_CTYPE, "");
+ setlocale(LC_MESSAGES, "");
+ bindtextdomain(PACKAGE, LOCALEDIR);
+ textdomain(PACKAGE);
+
+ seq = seq_init();
+ if (!seq)
+ ERRNO_ERROR(1);
+
+ while ((opt = getopt_long(argc, argv, cmd_line_options,
+ long_options, NULL)) != -1) {
+ /* we remember the two REMOVE_ACL commands of the set
+ operations because we may later need to delete them. */
+ cmd_t seq_remove_default_acl_cmd = NULL;
+ cmd_t seq_remove_acl_cmd = NULL;
+
+ if (opt != '\1' && saw_files) {
+ seq_free(seq);
+ seq = seq_init();
+ if (!seq)
+ ERRNO_ERROR(1);
+ saw_files = 0;
+ }
+
+ switch (opt) {
+ case 'b': /* remove all extended entries */
+ if (seq_append_cmd(seq, CMD_REMOVE_EXTENDED_ACL,
+ ACL_TYPE_ACCESS) ||
+ seq_append_cmd(seq, CMD_REMOVE_ACL,
+ ACL_TYPE_DEFAULT))
+ ERRNO_ERROR(1);
+ break;
+
+ case 'k': /* remove default ACL */
+ if (seq_append_cmd(seq, CMD_REMOVE_ACL,
+ ACL_TYPE_DEFAULT))
+ ERRNO_ERROR(1);
+ break;
+
+ case 'n': /* do not recalculate mask */
+ opt_recalculate = -1;
+ break;
+
+ case 'r': /* force recalculate mask */
+ opt_recalculate = 1;
+ break;
+
+ case 'd': /* operations apply to default ACL */
+ opt_promote = 1;
+ break;
+
+ case 's': /* set */
+ if (seq_append_cmd(seq, CMD_REMOVE_ACL,
+ ACL_TYPE_ACCESS))
+ ERRNO_ERROR(1);
+ seq_remove_acl_cmd = seq->s_last;
+ if (seq_append_cmd(seq, CMD_REMOVE_ACL,
+ ACL_TYPE_DEFAULT))
+ ERRNO_ERROR(1);
+ seq_remove_default_acl_cmd = seq->s_last;
+
+ seq_cmd = CMD_ENTRY_REPLACE;
+ parse_mode = SEQ_PARSE_WITH_PERM;
+ goto set_modify_delete;
+
+ case 'm': /* modify */
+ seq_cmd = CMD_ENTRY_REPLACE;
+ parse_mode = SEQ_PARSE_WITH_PERM;
+ goto set_modify_delete;
+
+ case 'x': /* delete */
+ seq_cmd = CMD_REMOVE_ENTRY;
+#if POSIXLY_CORRECT
+ parse_mode = SEQ_PARSE_ANY_PERM;
+#else
+ if (posixly_correct)
+ parse_mode = SEQ_PARSE_ANY_PERM;
+ else
+ parse_mode = SEQ_PARSE_NO_PERM;
+#endif
+ goto set_modify_delete;
+
+ set_modify_delete:
+ if (!posixly_correct)
+ parse_mode |= SEQ_PARSE_DEFAULT;
+ if (opt_promote)
+ parse_mode |= SEQ_PROMOTE_ACL;
+ if (parse_acl_seq(seq, optarg, &which,
+ seq_cmd, parse_mode) != 0) {
+ if (which < 0 ||
+ (size_t) which >= strlen(optarg)) {
+ fprintf(stderr, _(
+ "%s: Option "
+ "-%c incomplete\n"),
+ progname, opt);
+ } else {
+ fprintf(stderr, _(
+ "%s: Option "
+ "-%c: %s near "
+ "character %d\n"),
+ progname, opt,
+ strerror(errno),
+ which+1);
+ }
+ status = 2;
+ goto cleanup;
+ }
+ break;
+
+ case 'S': /* set from file */
+ if (seq_append_cmd(seq, CMD_REMOVE_ACL,
+ ACL_TYPE_ACCESS))
+ ERRNO_ERROR(1);
+ seq_remove_acl_cmd = seq->s_last;
+ if (seq_append_cmd(seq, CMD_REMOVE_ACL,
+ ACL_TYPE_DEFAULT))
+ ERRNO_ERROR(1);
+ seq_remove_default_acl_cmd = seq->s_last;
+
+ seq_cmd = CMD_ENTRY_REPLACE;
+ parse_mode = SEQ_PARSE_WITH_PERM;
+ goto set_modify_delete_from_file;
+
+ case 'M': /* modify from file */
+ seq_cmd = CMD_ENTRY_REPLACE;
+ parse_mode = SEQ_PARSE_WITH_PERM;
+ goto set_modify_delete_from_file;
+
+ case 'X': /* delete from file */
+ seq_cmd = CMD_REMOVE_ENTRY;
+#if POSIXLY_CORRECT
+ parse_mode = SEQ_PARSE_ANY_PERM;
+#else
+ if (posixly_correct)
+ parse_mode = SEQ_PARSE_ANY_PERM;
+ else
+ parse_mode = SEQ_PARSE_NO_PERM;
+#endif
+ goto set_modify_delete_from_file;
+
+ set_modify_delete_from_file:
+ if (!posixly_correct)
+ parse_mode |= SEQ_PARSE_DEFAULT;
+ if (opt_promote)
+ parse_mode |= SEQ_PROMOTE_ACL;
+ if (strcmp(optarg, "-") == 0) {
+ file = stdin;
+ } else {
+ file = fopen(optarg, "r");
+ if (file == NULL) {
+ fprintf(stderr, "%s: %s: %s\n",
+ progname,
+ xquote(optarg),
+ strerror(errno));
+ status = 2;
+ goto cleanup;
+ }
+ }
+
+ lineno = 0;
+ error = read_acl_seq(file, seq, seq_cmd,
+ parse_mode, &lineno, NULL);
+
+ if (file != stdin) {
+ fclose(file);
+ }
+
+ if (error) {
+ if (!errno)
+ errno = EINVAL;
+
+ if (file != stdin) {
+ fprintf(stderr, _(
+ "%s: %s in line "
+ "%d of file %s\n"),
+ progname,
+ strerror(errno),
+ lineno,
+ xquote(optarg));
+ } else {
+ fprintf(stderr, _(
+ "%s: %s in line "
+ "%d of standard "
+ "input\n"), progname,
+ strerror(errno),
+ lineno);
+ }
+ status = 2;
+ goto cleanup;
+ }
+ break;
+
+
+ case '\1': /* file argument */
+ if (seq_empty(seq))
+ goto synopsis;
+ saw_files = 1;
+
+ status = next_file(optarg, seq);
+ break;
+
+ case 'B': /* restore ACL backup */
+ saw_files = 1;
+
+ if (strcmp(optarg, "-") == 0)
+ file = stdin;
+ else {
+ file = fopen(optarg, "r");
+ if (file == NULL) {
+ fprintf(stderr, "%s: %s: %s\n",
+ progname,
+ xquote(optarg),
+ strerror(errno));
+ status = 2;
+ goto cleanup;
+ }
+ }
+
+ status = restore(file,
+ (file == stdin) ? NULL : optarg);
+
+ if (file != stdin)
+ fclose(file);
+ if (status != 0)
+ goto cleanup;
+ break;
+
+ case 'R': /* recursive */
+ walk_flags |= WALK_TREE_RECURSIVE;
+ break;
+
+ case 'L': /* follow symlinks */
+ walk_flags |= WALK_TREE_LOGICAL;
+ walk_flags &= ~WALK_TREE_PHYSICAL;
+ break;
+
+ case 'P': /* do not follow symlinks */
+ walk_flags |= WALK_TREE_PHYSICAL;
+ walk_flags &= ~WALK_TREE_LOGICAL;
+ break;
+
+ case 't': /* test mode */
+ opt_test = 1;
+ break;
+
+ case 'v': /* print version and exit */
+ printf("%s " VERSION "\n", progname);
+ status = 0;
+ goto cleanup;
+
+ case 'h': /* help! */
+ help();
+ status = 0;
+ goto cleanup;
+
+ case ':': /* option missing */
+ case '?': /* unknown option */
+ default:
+ goto synopsis;
+ }
+ if (seq_remove_acl_cmd) {
+ /* This was a set operation. Check if there are
+ actually entries of ACL_TYPE_ACCESS; if there
+ are none, we need to remove this command! */
+ if (!has_any_of_type(seq_remove_acl_cmd->c_next,
+ ACL_TYPE_ACCESS))
+ seq_delete_cmd(seq, seq_remove_acl_cmd);
+ }
+ if (seq_remove_default_acl_cmd) {
+ /* This was a set operation. Check if there are
+ actually entries of ACL_TYPE_DEFAULT; if there
+ are none, we need to remove this command! */
+ if (!has_any_of_type(seq_remove_default_acl_cmd->c_next,
+ ACL_TYPE_DEFAULT))
+ seq_delete_cmd(seq, seq_remove_default_acl_cmd);
+ }
+ }
+ while (optind < argc) {
+ if(!seq)
+ goto synopsis;
+ if (seq_empty(seq))
+ goto synopsis;
+ saw_files = 1;
+
+ status = next_file(argv[optind++], seq);
+ }
+ if (!saw_files)
+ goto synopsis;
+
+ goto cleanup;
+
+synopsis:
+ fprintf(stderr, _("Usage: %s %s\n"),
+ progname, cmd_line_spec);
+ fprintf(stderr, _("Try `%s --help' for more information.\n"),
+ progname);
+ status = 2;
+ goto cleanup;
+
+errno_error:
+ fprintf(stderr, "%s: %s\n", progname, strerror(errno));
+ goto cleanup;
+
+cleanup:
+ if (seq)
+ seq_free(seq);
+ return status;
+}
+
diff --git a/test/Makefile b/test/Makefile
new file mode 100644
index 0000000..a15e9e4
--- /dev/null
+++ b/test/Makefile
@@ -0,0 +1,49 @@
+#
+# Copyright (c) 2001-2002 Silicon Graphics, Inc. All Rights Reserved.
+#
+# 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 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, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+
+TOPDIR = ..
+include $(TOPDIR)/include/builddefs
+
+TESTS = $(wildcard *.test)
+ROOT = $(wildcard root/*.test)
+NFS = $(wildcard nfs/*.test)
+LSRCFILES = run make-tree $(TESTS) $(ROOT) $(NFS)
+
+include $(BUILDRULES)
+
+default install install-dev install-lib:
+
+PATH := $(abspath ../getfacl/):$(abspath ../setfacl/):$(abspath ../chacl/):$(PATH)
+
+tests: $(TESTS)
+root-tests: $(ROOT)
+nfs-tests: $(NFS)
+
+$(TESTS):
+ @echo "*** $@ ***"; perl run $@
+
+$(NFS):
+ @echo "NFS specific tests"; @echo "*** $@ ***"; perl run $@
+
+$(ROOT):
+ @echo "Note: Tests must run as root"; @echo "*** $@ ***"; perl run $@
+
+.PHONY: $(TESTS) $(NFS) $(ROOT)
+.NOTPARALLEL:
+
+
diff --git a/test/cp.test b/test/cp.test
new file mode 100644
index 0000000..a888c04
--- /dev/null
+++ b/test/cp.test
@@ -0,0 +1,46 @@
+The cp utility should only copy ACLs if `-p' is given.
+
+ $ umask 022
+ $ mkdir d
+ $ cd d
+ $ touch f
+ $ setfacl -m u:bin:rw f
+ $ ls -l f | awk -- '{ print $1 }'
+ > -rw-rw-r--+
+
+ $ cp f g
+ $ ls -l g | awk -- '{ print $1 }'
+ > -rw-r--r--
+
+ $ rm g
+ $ cp -p f g
+ $ ls -l f | awk -- '{ print $1 }'
+ > -rw-rw-r--+
+
+ $ mkdir h
+ $ echo blubb > h/x
+ $ cp -rp h i
+ $ cat i/x
+ > blubb
+
+ $ rm -r i
+ $ setfacl -R -m u:bin:rwx h
+ $ getfacl --omit-header h/x
+ > user::rw-
+ > user:bin:rwx
+ > group::r--
+ > mask::rwx
+ > other::r--
+ >
+
+ $ cp -rp h i
+ $ getfacl --omit-header i/x
+ > user::rw-
+ > user:bin:rwx
+ > group::r--
+ > mask::rwx
+ > other::r--
+ >
+
+ $ cd ..
+ $ rm -r d
diff --git a/test/getfacl-noacl.test b/test/getfacl-noacl.test
new file mode 100644
index 0000000..6d730c4
--- /dev/null
+++ b/test/getfacl-noacl.test
@@ -0,0 +1,55 @@
+Getfacl utility option parsing tests. This test can be run on a
+filesystem with or without ACL support.
+
+ $ mkdir test
+ $ cd test
+ $ umask 027
+ $ touch x
+ $ getfacl --omit-header x
+ > user::rw-
+ > group::r--
+ > other::---
+ >
+
+ $ getfacl --omit-header --access x
+ > user::rw-
+ > group::r--
+ > other::---
+ >
+
+ $ getfacl --omit-header -d x
+ $ getfacl --omit-header -d .
+ $ getfacl --omit-header -d /
+ > getfacl: Removing leading '/' from absolute path names
+
+ $ getfacl --skip-base x
+ $ getfacl --omit-header --all-effective x
+ > user::rw-
+ > group::r--
+ > other::---
+ >
+
+ $ getfacl --omit-header --no-effective x
+ > user::rw-
+ > group::r--
+ > other::---
+ >
+
+ $ mkdir d
+ $ touch d/y
+ $ ln -s d l
+ $ getfacl -dR . | grep file | sort
+ > # file: .
+ > # file: d
+ > # file: d/y
+ > # file: x
+
+ $ ln -s l ll
+ $ getfacl -dLR ll | grep file | sort
+ > # file: ll
+ > # file: ll/y
+
+ $ rm l ll x
+ $ rm -rf d
+ $ cd ..
+ $ rmdir test
diff --git a/test/getfacl-recursive.test b/test/getfacl-recursive.test
new file mode 100644
index 0000000..b88c211
--- /dev/null
+++ b/test/getfacl-recursive.test
@@ -0,0 +1,194 @@
+Tests for proper path recursion
+
+ $ mkdir -p 1/2/3
+ $ mkdir 1/link
+ $ touch 1/link/file
+ $ ln -s `pwd`/1/link 1/2/link
+ $ getfacl -P -R 1/2 | ./sort-getfacl-output
+ > # file: 1/2
+ > # owner: %TUSER
+ > # group: %TGROUP
+ > user::rwx
+ > group::r-x
+ > other::r-x
+ >
+ > # file: 1/2/3
+ > # owner: %TUSER
+ > # group: %TGROUP
+ > user::rwx
+ > group::r-x
+ > other::r-x
+ >
+
+ $ getfacl -R 1/2 | ./sort-getfacl-output
+ > # file: 1/2
+ > # owner: %TUSER
+ > # group: %TGROUP
+ > user::rwx
+ > group::r-x
+ > other::r-x
+ >
+ > # file: 1/2/3
+ > # owner: %TUSER
+ > # group: %TGROUP
+ > user::rwx
+ > group::r-x
+ > other::r-x
+ >
+
+ $ getfacl -R -L 1/2 | ./sort-getfacl-output
+ > # file: 1/2
+ > # owner: %TUSER
+ > # group: %TGROUP
+ > user::rwx
+ > group::r-x
+ > other::r-x
+ >
+ > # file: 1/2/3
+ > # owner: %TUSER
+ > # group: %TGROUP
+ > user::rwx
+ > group::r-x
+ > other::r-x
+ >
+ > # file: 1/2/link
+ > # owner: %TUSER
+ > # group: %TGROUP
+ > user::rwx
+ > group::r-x
+ > other::r-x
+ >
+ > # file: 1/2/link/file
+ > # owner: %TUSER
+ > # group: %TGROUP
+ > user::rw-
+ > group::r--
+ > other::r--
+ >
+
+ $ getfacl -P -R 1 | ./sort-getfacl-output
+ > # file: 1
+ > # owner: %TUSER
+ > # group: %TGROUP
+ > user::rwx
+ > group::r-x
+ > other::r-x
+ >
+ > # file: 1/2
+ > # owner: %TUSER
+ > # group: %TGROUP
+ > user::rwx
+ > group::r-x
+ > other::r-x
+ >
+ > # file: 1/2/3
+ > # owner: %TUSER
+ > # group: %TGROUP
+ > user::rwx
+ > group::r-x
+ > other::r-x
+ >
+ > # file: 1/link
+ > # owner: %TUSER
+ > # group: %TGROUP
+ > user::rwx
+ > group::r-x
+ > other::r-x
+ >
+ > # file: 1/link/file
+ > # owner: %TUSER
+ > # group: %TGROUP
+ > user::rw-
+ > group::r--
+ > other::r--
+ >
+
+ $ getfacl -R 1 | ./sort-getfacl-output
+ > # file: 1
+ > # owner: %TUSER
+ > # group: %TGROUP
+ > user::rwx
+ > group::r-x
+ > other::r-x
+ >
+ > # file: 1/2
+ > # owner: %TUSER
+ > # group: %TGROUP
+ > user::rwx
+ > group::r-x
+ > other::r-x
+ >
+ > # file: 1/2/3
+ > # owner: %TUSER
+ > # group: %TGROUP
+ > user::rwx
+ > group::r-x
+ > other::r-x
+ >
+ > # file: 1/link
+ > # owner: %TUSER
+ > # group: %TGROUP
+ > user::rwx
+ > group::r-x
+ > other::r-x
+ >
+ > # file: 1/link/file
+ > # owner: %TUSER
+ > # group: %TGROUP
+ > user::rw-
+ > group::r--
+ > other::r--
+ >
+
+ $ getfacl -R -L 1 | ./sort-getfacl-output
+ > # file: 1
+ > # owner: %TUSER
+ > # group: %TGROUP
+ > user::rwx
+ > group::r-x
+ > other::r-x
+ >
+ > # file: 1/2
+ > # owner: %TUSER
+ > # group: %TGROUP
+ > user::rwx
+ > group::r-x
+ > other::r-x
+ >
+ > # file: 1/2/3
+ > # owner: %TUSER
+ > # group: %TGROUP
+ > user::rwx
+ > group::r-x
+ > other::r-x
+ >
+ > # file: 1/2/link
+ > # owner: %TUSER
+ > # group: %TGROUP
+ > user::rwx
+ > group::r-x
+ > other::r-x
+ >
+ > # file: 1/2/link/file
+ > # owner: %TUSER
+ > # group: %TGROUP
+ > user::rw-
+ > group::r--
+ > other::r--
+ >
+ > # file: 1/link
+ > # owner: %TUSER
+ > # group: %TGROUP
+ > user::rwx
+ > group::r-x
+ > other::r-x
+ >
+ > # file: 1/link/file
+ > # owner: %TUSER
+ > # group: %TGROUP
+ > user::rw-
+ > group::r--
+ > other::r--
+ >
+
+ $ rm -R 1/
diff --git a/test/make-tree b/test/make-tree
new file mode 100644
index 0000000..472c1cd
--- /dev/null
+++ b/test/make-tree
@@ -0,0 +1,45 @@
+#!/bin/sh
+
+LEVELS=3 ; [ -z "$1" ] || LEVELS=$1
+DIRS=10 ; [ -z "$2" ] || DIRS=$2
+FILES=10 ; [ -z "$2" ] || FILES=$3
+NUMBER_OF_ACLS=50 ; [ -z "$3" ] || NUMBER_OF_ACLS=$4
+
+function random_dir() {
+ mkdir -p $1
+ #setfacl -s "u::rwx,u:$[($RANDOM % $NUMBER_OF_ACLS)+1000]:rwx,g::rx,o:-" $1
+}
+
+function random_file() {
+ touch $1
+ #setfacl -s "u::rw,u:$[($RANDOM % $NUMBER_OF_ACLS)+1000]:rw,g::r,o:-" $1
+}
+
+function create () {
+ local LEVEL=$1
+ if [ $LEVEL -eq 0 ]; then
+ local I=0
+ while [ $I -lt $FILES ]; do
+ random_file file$I
+ I=$[$I+1]
+ done
+ echo -n "."
+ else
+ local I=0
+ while [ $I -lt $DIRS ]; do
+ random_dir dir$I
+ cd dir$I
+ create $[$LEVEL-1]
+ cd ..
+ I=$[$I+1]
+ done
+ fi
+ return
+}
+
+mkdir -p tree
+cd tree
+create $LEVELS
+cd ..
+echo
+
diff --git a/test/misc.test b/test/misc.test
new file mode 100644
index 0000000..7c62c64
--- /dev/null
+++ b/test/misc.test
@@ -0,0 +1,426 @@
+Pretty comprehensive ACL tests.
+
+This must be run on a filesystem with ACL support. Also, you will need
+two dummy users (bin and daemon) and a dummy group (daemon).
+
+ $ umask 027
+ $ touch f
+
+Only change a base ACL:
+ $ setfacl -m u::r f
+ $ setfacl -m u::rw,u:bin:rw f
+ $ ls -dl f | awk '{print $1}'
+ > -rw-rw----+
+
+ $ getfacl --omit-header f
+ > user::rw-
+ > user:bin:rw-
+ > group::r--
+ > mask::rw-
+ > other::---
+ >
+
+ $ rm f
+ $ umask 022
+ $ touch f
+ $ setfacl -m u:bin:rw f
+ $ ls -dl f | awk '{print $1}'
+ > -rw-rw-r--+
+
+ $ getfacl --omit-header f
+ > user::rw-
+ > user:bin:rw-
+ > group::r--
+ > mask::rw-
+ > other::r--
+ >
+
+ $rm f
+ $ umask 027
+ $ mkdir d
+ $ setfacl -m u:bin:rwx d
+ $ ls -dl d | awk '{print $1}'
+ > drwxrwx---+
+
+ $ getfacl --omit-header d
+ > user::rwx
+ > user:bin:rwx
+ > group::r-x
+ > mask::rwx
+ > other::---
+ >
+
+ $ rmdir d
+ $ umask 022
+ $ mkdir d
+ $ setfacl -m u:bin:rwx d
+ $ ls -dl d | awk '{print $1}'
+ > drwxrwxr-x+
+
+ $ getfacl --omit-header d
+ > user::rwx
+ > user:bin:rwx
+ > group::r-x
+ > mask::rwx
+ > other::r-x
+ >
+
+ $ rmdir d
+
+
+Multiple users
+
+ $ umask 022
+ $ touch f
+ $ setfacl -m u:bin:rw,u:daemon:r f
+ $ ls -dl f | awk '{print $1}'
+ > -rw-rw-r--+
+
+ $ getfacl --omit-header f
+ > user::rw-
+ > user:bin:rw-
+ > user:daemon:r--
+ > group::r--
+ > mask::rw-
+ > other::r--
+ >
+
+Multiple groups
+
+ $ setfacl -m g:users:rw,g:daemon:r f
+ $ ls -dl f | awk '{print $1}'
+ > -rw-rw-r--+
+
+ $ getfacl --omit-header f
+ > user::rw-
+ > user:bin:rw-
+ > user:daemon:r--
+ > group::r--
+ > group:daemon:r--
+ > group:users:rw-
+ > mask::rw-
+ > other::r--
+ >
+
+Remove one group
+
+ $ setfacl -x g:users f
+ $ ls -dl f | awk '{print $1}'
+ > -rw-rw-r--+
+
+ $ getfacl --omit-header f
+ > user::rw-
+ > user:bin:rw-
+ > user:daemon:r--
+ > group::r--
+ > group:daemon:r--
+ > mask::rw-
+ > other::r--
+ >
+
+Remove one user
+
+ $ setfacl -x u:daemon f
+ $ ls -dl f | awk '{print $1}'
+ > -rw-rw-r--+
+
+ $ getfacl --omit-header f
+ > user::rw-
+ > user:bin:rw-
+ > group::r--
+ > group:daemon:r--
+ > mask::rw-
+ > other::r--
+ >
+
+ $ rm f
+
+Default ACL
+
+ $ umask 027
+ $ mkdir d
+ $ setfacl -m u:bin:rwx,u:daemon:rw,d:u:bin:rwx,d:m:rx d
+ $ ls -dl d | awk '{print $1}'
+ > drwxrwx---+
+
+ $ getfacl --omit-header d
+ > user::rwx
+ > user:bin:rwx
+ > user:daemon:rw-
+ > group::r-x
+ > mask::rwx
+ > other::---
+ > default:user::rwx
+ > default:user:bin:rwx #effective:r-x
+ > default:group::r-x
+ > default:mask::r-x
+ > default:other::---
+ >
+
+Umask now ignored?
+
+ $ umask 027
+ $ touch d/f
+ $ ls -dl d/f | awk '{print $1}'
+ > -rw-r-----+
+
+ $ getfacl --omit-header d/f
+ > user::rw-
+ > user:bin:rwx #effective:r--
+ > group::r-x #effective:r--
+ > mask::r--
+ > other::---
+ >
+
+ $ rm d/f
+ $ umask 022
+ $ touch d/f
+ $ ls -dl d/f | awk '{print $1}'
+ > -rw-r-----+
+
+ $ getfacl --omit-header d/f
+ > user::rw-
+ > user:bin:rwx #effective:r--
+ > group::r-x #effective:r--
+ > mask::r--
+ > other::---
+ >
+
+ $ rm d/f
+
+Default ACL copying
+
+ $ umask 000
+ $ mkdir d/d
+ $ ls -dl d/d | awk '{print $1}'
+ > drwxr-x---+
+
+ $ getfacl --omit-header d/d
+ > user::rwx
+ > user:bin:rwx #effective:r-x
+ > group::r-x
+ > mask::r-x
+ > other::---
+ > default:user::rwx
+ > default:user:bin:rwx #effective:r-x
+ > default:group::r-x
+ > default:mask::r-x
+ > default:other::---
+ >
+
+ $ rmdir d/d
+ $ umask 022
+ $ mkdir d/d
+ $ ls -dl d/d | awk '{print $1}'
+ > drwxr-x---+
+
+ $ getfacl --omit-header d/d
+ > user::rwx
+ > user:bin:rwx #effective:r-x
+ > group::r-x
+ > mask::r-x
+ > other::---
+ > default:user::rwx
+ > default:user:bin:rwx #effective:r-x
+ > default:group::r-x
+ > default:mask::r-x
+ > default:other::---
+ >
+
+Add some users and groups
+
+ $ setfacl -nm u:daemon:rx,d:u:daemon:rx,g:users:rx,g:daemon:rwx d/d
+ $ ls -dl d/d | awk '{print $1}'
+ > drwxr-x---+
+
+ $ getfacl --omit-header d/d
+ > user::rwx
+ > user:bin:rwx #effective:r-x
+ > user:daemon:r-x
+ > group::r-x
+ > group:daemon:rwx #effective:r-x
+ > group:users:r-x
+ > mask::r-x
+ > other::---
+ > default:user::rwx
+ > default:user:bin:rwx #effective:r-x
+ > default:user:daemon:r-x
+ > default:group::r-x
+ > default:mask::r-x
+ > default:other::---
+ >
+
+Symlink in directory with default ACL?
+
+ $ ln -s d d/l
+ $ ls -dl d/l | awk '{print $1}'
+ > lrwxrwxrwx
+
+ $ ls -dl -L d/l | awk '{print $1}'
+ > drwxr-x---+
+
+ $ getfacl --omit-header d/l
+ > user::rwx
+ > user:bin:rwx #effective:r-x
+ > user:daemon:r-x
+ > group::r-x
+ > group:daemon:rwx #effective:r-x
+ > group:users:r-x
+ > mask::r-x
+ > other::---
+ > default:user::rwx
+ > default:user:bin:rwx #effective:r-x
+ > default:user:daemon:r-x
+ > default:group::r-x
+ > default:mask::r-x
+ > default:other::---
+ >
+
+ $ rm d/l
+
+Does mask manipulation work?
+
+ $ setfacl -m g:daemon:rx,u:bin:rx d/d
+ $ ls -dl d/d | awk '{print $1}'
+ > drwxr-x---+
+
+ $ getfacl --omit-header d/d
+ > user::rwx
+ > user:bin:r-x
+ > user:daemon:r-x
+ > group::r-x
+ > group:daemon:r-x
+ > group:users:r-x
+ > mask::r-x
+ > other::---
+ > default:user::rwx
+ > default:user:bin:rwx #effective:r-x
+ > default:user:daemon:r-x
+ > default:group::r-x
+ > default:mask::r-x
+ > default:other::---
+ >
+
+ $ setfacl -m d:u:bin:rwx d/d
+ $ ls -dl d/d | awk '{print $1}'
+ > drwxr-x---+
+
+ $ getfacl --omit-header d/d
+ > user::rwx
+ > user:bin:r-x
+ > user:daemon:r-x
+ > group::r-x
+ > group:daemon:r-x
+ > group:users:r-x
+ > mask::r-x
+ > other::---
+ > default:user::rwx
+ > default:user:bin:rwx
+ > default:user:daemon:r-x
+ > default:group::r-x
+ > default:mask::rwx
+ > default:other::---
+ >
+
+ $ rmdir d/d
+
+Remove the default ACL
+
+ $ setfacl -k d
+ $ ls -dl d | awk '{print $1}'
+ > drwxrwx---+
+
+ $ getfacl --omit-header d
+ > user::rwx
+ > user:bin:rwx
+ > user:daemon:rw-
+ > group::r-x
+ > mask::rwx
+ > other::---
+ >
+
+Reset to base entries
+
+ $ setfacl -b d
+ $ ls -dl d | awk '{print $1}'
+ > drwxr-x---
+
+ $ getfacl --omit-header d
+ > user::rwx
+ > group::r-x
+ > other::---
+ >
+
+Now, chmod should change the group_obj entry
+
+ $ chmod 775 d
+ $ ls -dl d | awk '{print $1}'
+ > drwxrwxr-x
+
+ $ getfacl --omit-header d
+ > user::rwx
+ > group::rwx
+ > other::r-x
+ >
+
+ $ rmdir d
+ $ umask 002
+ $ mkdir d
+ $ setfacl -m u:daemon:rwx,u:bin:rx,d:u:daemon:rwx,d:u:bin:rx d
+ $ ls -dl d | awk '{print $1}'
+ > drwxrwxr-x+
+
+ $ getfacl --omit-header d
+ > user::rwx
+ > user:bin:r-x
+ > user:daemon:rwx
+ > group::rwx
+ > mask::rwx
+ > other::r-x
+ > default:user::rwx
+ > default:user:bin:r-x
+ > default:user:daemon:rwx
+ > default:group::rwx
+ > default:mask::rwx
+ > default:other::r-x
+ >
+
+ $ chmod 750 d
+ $ ls -dl d | awk '{print $1}'
+ > drwxr-x---+
+
+ $ getfacl --omit-header d
+ > user::rwx
+ > user:bin:r-x
+ > user:daemon:rwx #effective:r-x
+ > group::rwx #effective:r-x
+ > mask::r-x
+ > other::---
+ > default:user::rwx
+ > default:user:bin:r-x
+ > default:user:daemon:rwx
+ > default:group::rwx
+ > default:mask::rwx
+ > default:other::r-x
+ >
+
+ $ chmod 750 d
+ $ ls -dl d | awk '{print $1}'
+ > drwxr-x---+
+
+ $ getfacl --omit-header d
+ > user::rwx
+ > user:bin:r-x
+ > user:daemon:rwx #effective:r-x
+ > group::rwx #effective:r-x
+ > mask::r-x
+ > other::---
+ > default:user::rwx
+ > default:user:bin:r-x
+ > default:user:daemon:rwx
+ > default:group::rwx
+ > default:mask::rwx
+ > default:other::r-x
+ >
+
+ $ rmdir d
diff --git a/test/nfs/nfs-dir.test b/test/nfs/nfs-dir.test
new file mode 100644
index 0000000..33e5f5f
--- /dev/null
+++ b/test/nfs/nfs-dir.test
@@ -0,0 +1,50 @@
+This is a regression test for a bug in 2.4 kernels. The test must be run
+as root on a machine that has a loopback mounted NFS export. The mount
+must have root squashing enabled. The test must be run in the root of
+the nfs mount, and requires the following environment variable:
+
+EXPORT_PATH => the path that is mounted at the working directory.
+
+ Create a test directory and file.
+
+ $ umask 022
+ $ mkdir %{EXPORT_PATH}/test
+ $ echo blah > %{EXPORT_PATH}/test/blah
+
+ Make sure the file can be accessed before.
+
+ $ su bin
+ $ cat test/blah
+ > blah
+
+ Set up a situation that triggers the bug.
+
+ $ su
+ $ chmod go-rwx %{EXPORT_PATH}/test
+ $ setfacl -m u:bin:rx %{EXPORT_PATH}/test
+ $ ls -dl %{EXPORT_PATH}/test | awk '{print $1, $3, $4}'
+ > drwxr-x---+ root root
+ $ getfacl --omit-header %{EXPORT_PATH}/test 2> /dev/null
+ > user::rwx
+ > user:bin:r-x
+ > group::---
+ > mask::r-x
+ > other::---
+ >
+
+ This should also succeed. With the bug, reading the file would
+ fail with "Stale NFS file handle" or "Input/output error".
+
+ $ su bin
+ $ cat test/blah
+ > blah
+ $ sleep 3
+ $ cat test/blah
+ > blah
+ $ cat test/blah
+ > blah
+
+ Clean up.
+
+ $ su
+ $ rm -rf %{EXPORT_PATH}/test
diff --git a/test/nfs/nfsacl.test b/test/nfs/nfsacl.test
new file mode 100644
index 0000000..4f37322
--- /dev/null
+++ b/test/nfs/nfsacl.test
@@ -0,0 +1,42 @@
+This is a regression test for bugs in the nfsacl protocol extension.
+The test should be run on an NFS export mount with ACL support.
+
+ Create a test directory and file.
+
+ $ umask 022
+ $ mkdir -p test/sub
+ $ echo blah > test/sub/blah
+
+ $ cp -rp test/sub test/sub2
+ $ find test/sub2 | sort | xargs ls -dl | awk '{print $1,$8}'
+ > drwxr-xr-x test/sub2
+ > -rw-r--r-- test/sub2/blah
+
+ $ rm -rf test/sub2
+
+ $ setfacl -m u:daemon:rwx test/sub
+ $ setfacl -dm u:daemon:rwx test/sub
+ $ getfattr -m- test/sub
+ > # file: test/sub
+ > system.posix_acl_access
+ > system.posix_acl_default
+ >
+
+ $ cp -rp test/sub test/sub2
+ $ find test/sub2 | sort | xargs ls -dl | awk '{print $1,$8}'
+ > drwxrwxr-x+ test/sub2
+ > -rw-r--r-- test/sub2/blah
+
+ $ rm -rf test/sub2
+
+ $ setfacl -m u:daemon:rw test/sub/blah
+ $ cp -rp test/sub test/sub2
+ $ find test/sub2 | sort | xargs ls -dl | awk '{print $1,$8}'
+ > drwxrwxr-x+ test/sub2
+ > -rw-rw-r--+ test/sub2/blah
+
+ $ rm -rf test/sub2
+
+ Clean up.
+
+ $ rm -rf test
diff --git a/test/root/permissions.test b/test/root/permissions.test
new file mode 100644
index 0000000..afaf5f0
--- /dev/null
+++ b/test/root/permissions.test
@@ -0,0 +1,279 @@
+This script tests if file permissions are properly checked with and
+without ACLs. The script must be run as root to allow switching users.
+The following users are required. They must be a member in the groups
+listed in parentheses.
+
+ bin (bin)
+ daemon (bin, daemon)
+
+
+Cry immediately if we are not running as root.
+
+ $ id -u
+ > 0
+
+
+First, set up a temporary directory and create a regular file with
+defined permissions.
+
+ $ mkdir d
+ $ cd d
+ $ umask 027
+ $ touch f
+ $ ls -l f | awk -- '{ print $1, $3, $4 }'
+ > -rw-r----- root root
+
+
+Make sure root has access to the file. Verify that user daemon does not
+have access to the file owned by root.
+
+ $ echo root > f
+
+ $ su daemon
+ $ echo daemon >> f
+ >~ .*f: Permission denied$
+
+ $ su
+
+
+Now, change the ownership of the file to bin:bin and verify that this
+gives user bin write access.
+
+ $ chown bin:bin f
+ $ ls -l f | awk -- '{ print $1, $3, $4 }'
+ > -rw-r----- bin bin
+ $ su bin
+ $ echo bin >> f
+
+
+User daemon is a member in the owning group, which has only read access.
+Verify this.
+
+ $ su daemon
+ $ cat f
+ > root
+ > bin
+
+ $ echo daemon >> f
+ >~ .*f: Permission denied$
+
+
+Now, add an ACL entry for user daemon that grants him rw- access. File
+owners and users capable of CAP_FOWNER are allowed to change ACLs.
+
+ $ su bin
+ $ setfacl -m u:daemon:rw f
+ $ getfacl --omit-header f
+ > user::rw-
+ > user:daemon:rw-
+ > group::r--
+ > mask::rw-
+ > other::---
+ >
+
+
+Verify that the additional ACL entry grants user daemon write access.
+
+ $ su daemon
+ $ echo daemon >> f
+ $ cat f
+ > root
+ > bin
+ > daemon
+
+
+Remove write access from the group class permission bits, and
+verify that this masks daemon's write permission.
+
+ $ su bin
+ $ chmod g-w f
+ $ getfacl --omit-header f
+ > user::rw-
+ > user:daemon:rw- #effective:r--
+ > group::r--
+ > mask::r--
+ > other::---
+ >
+
+ $ su daemon
+ $ echo daemon >> f
+ >~ .*f: Permission denied$
+
+
+Add an entry for group daemon with rw- access, and change the
+permissions for user daemon to r--. Also change the others permissions t
+rw-. The user entry should take precedence, so daemon should be denied
+access.
+
+ $ su bin
+ $ setfacl -m u:daemon:r,g:daemon:rw-,o::rw- f
+
+ $ su daemon
+ $ echo daemon >> f
+ >~ .*f: Permission denied$
+
+
+Remove the entry for user daemon. The group daemon permissions should
+now give user daemon rw- access.
+
+ $ su bin
+ $ setfacl -x u:daemon f
+
+ $ su daemon
+ $ echo daemon2 >> f
+ $ cat f
+ > root
+ > bin
+ > daemon
+ > daemon2
+
+
+Set the group daemon permissions to r-- and verify that after than, user
+daemon does not have write access anymore.
+
+ $ su bin
+ $ setfacl -m g:daemon:r f
+
+ $ su daemon
+ $ echo daemon3 >> f
+ >~ .*f: Permission denied$
+
+
+Now, remove the group daemon entry. Because user daemon is a member in
+the owning group, he should still have no write access.
+
+ $ su bin
+ $ setfacl -x g:daemon f
+
+ $ su daemon
+ $ echo daemon4 >> f
+ >~ .*f: Permission denied$
+
+
+Change the owning group. The other permissions should now grant user
+daemon write access.
+
+ $ su
+ $ chgrp root f
+
+ $ su daemon
+ $ echo daemon5 >> f
+ $ cat f
+ > root
+ > bin
+ > daemon
+ > daemon2
+ > daemon5
+
+
+Verify that permissions in separate matching ACL entries do not
+accumulate.
+
+ $ su
+ $ setfacl -m g:bin:r,g:daemon:w f
+
+ $ su daemon
+ $ : < f
+ $ : > f
+ $ : <> f
+ >~ .*f: Permission denied$
+
+
+Test if directories can have ACLs. We assume that only one access check
+algorithm is used for all file types the file system, so these tests
+only need to verify that ACL permissions make a difference.
+
+ $ su
+ $ mkdir -m 750 e
+ $ touch e/h
+
+ $ su bin
+ $ shopt -s nullglob ; echo e/*
+ >
+
+ $ echo i > e/i
+ >~ .*e/i: Permission denied$
+
+ $ su
+ $ setfacl -m u:bin:rx e
+
+ $ su bin
+ $ echo e/*
+ > e/h
+ $ echo i > e/i
+ >~ .*e/i: Permission denied$
+
+ $ su
+ $ setfacl -m u:bin:rwx e
+
+ $ su bin
+ $ echo i > e/i
+
+
+Test if symlinks are properly followed.
+
+ $ su
+ $ touch g
+ $ ln -s g l
+ $ setfacl -m u:bin:rw l
+ $ ls -l g | awk -- '{ print $1, $3, $4 }'
+ > -rw-rw----+ root root
+
+
+Test if ACLs are effective for block and character special files, fifos,
+sockets. This is done by creating special files locally. The devices do
+not need to exist: The access check is earlier in the code path than the
+test if the device exists.
+
+
+ $ mknod -m 0660 hdt b 91 64
+ $ mknod -m 0660 null c 1 3
+ $ mkfifo -m 0660 fifo
+
+ $ su bin
+ $ : < hdt
+ >~ .*hdt: Permission denied$
+ $ : < null
+ >~ .*null: Permission denied$
+ $ : < fifo
+ >~ .*fifo: Permission denied$
+
+ $ su
+ $ setfacl -m u:bin:rw hdt null fifo
+
+ $ su bin
+ $ : < hdt
+ >~ .*hdt: No such device or address$
+ $ : < null
+ $ ( echo blah > fifo & ) ; cat fifo
+ > blah
+
+
+Test if CAP_FOWNER is properly honored for directories. This addresses a
+specific bug in XFS 1.2, which does not grant root access to files in
+directories if the file has an ACL and only CAP_FOWNER would grant them.
+
+ $ su
+ $ mkdir -m 600 x
+ $ chown daemon:daemon x
+ $ echo j > x/j
+ $ ls -l x/j | awk -- '{ print $1, $3, $4 }'
+ > -rw-r----- root root
+
+ $ setfacl -m u:daemon:r x
+
+ $ ls -l x/j | awk -- '{ print $1, $3, $4 }'
+ > -rw-r----- root root
+ (With the bug this gives: `ls: x/j: Permission denied'.)
+
+ $ echo k > x/k
+ (With the bug this gives: `x/k: Permission denied'.)
+
+ $ chmod 750 x
+
+
+Clean up.
+
+ $ su
+ $ cd ..
+ $ rm -rf d
diff --git a/test/root/setfacl.test b/test/root/setfacl.test
new file mode 100644
index 0000000..630e9fb
--- /dev/null
+++ b/test/root/setfacl.test
@@ -0,0 +1,144 @@
+Setfacl utility tests. Run these tests on a filesystem with ACL support.
+
+ $ mkdir d
+ $ chown bin:bin d
+ $ cd d
+
+ $ su bin
+ $ sg bin
+ $ umask 027
+ $ touch g
+ $ ls -dl g | awk '{print $1}'
+ > -rw-r-----
+
+ $ setfacl -m m:- g
+ $ ls -dl g | awk '{print $1}'
+ > -rw-------+
+
+ $ getfacl g
+ > # file: g
+ > # owner: bin
+ > # group: bin
+ > user::rw-
+ > group::r-- #effective:---
+ > mask::---
+ > other::---
+ >
+
+ $ setfacl -x m g
+ $ getfacl g
+ > # file: g
+ > # owner: bin
+ > # group: bin
+ > user::rw-
+ > group::r--
+ > other::---
+ >
+
+ $ setfacl -m u:daemon:rw g
+ $ getfacl g
+ > # file: g
+ > # owner: bin
+ > # group: bin
+ > user::rw-
+ > user:daemon:rw-
+ > group::r--
+ > mask::rw-
+ > other::---
+ >
+
+ $ setfacl -m u::rwx,g::r-x,o:- g
+ $ getfacl g
+ > # file: g
+ > # owner: bin
+ > # group: bin
+ > user::rwx
+ > user:daemon:rw-
+ > group::r-x
+ > mask::rwx
+ > other::---
+ >
+
+ $ setfacl -m u::rwx,g::r-x,o:-,m:- g
+ $ getfacl g
+ > # file: g
+ > # owner: bin
+ > # group: bin
+ > user::rwx
+ > user:daemon:rw- #effective:---
+ > group::r-x #effective:---
+ > mask::---
+ > other::---
+ >
+
+ $ setfacl -m u::rwx,g::r-x,o:-,u:root:-,m:- g
+ $ getfacl g
+ > # file: g
+ > # owner: bin
+ > # group: bin
+ > user::rwx
+ > user:root:---
+ > user:daemon:rw- #effective:---
+ > group::r-x #effective:---
+ > mask::---
+ > other::---
+ >
+
+ $ setfacl -m u::rwx,g::r-x,o:-,u:root:-,m:- g
+ $ getfacl g
+ > # file: g
+ > # owner: bin
+ > # group: bin
+ > user::rwx
+ > user:root:---
+ > user:daemon:rw- #effective:---
+ > group::r-x #effective:---
+ > mask::---
+ > other::---
+ >
+
+ $ setfacl -m u::rwx,g::r-x,o:-,u:root:- g
+ $ getfacl g
+ > # file: g
+ > # owner: bin
+ > # group: bin
+ > user::rwx
+ > user:root:---
+ > user:daemon:rw-
+ > group::r-x
+ > mask::rwx
+ > other::---
+ >
+
+ $ setfacl --test -x u: g
+ > setfacl: g: Malformed access ACL `user:root:---,user:daemon:rw-,group::r-x,mask::rwx,other::---': Missing or wrong entry at entry 1
+
+ $ setfacl --test -x u:x
+ > setfacl: Option -x: Invalid argument near character 3
+
+ $ setfacl -m d:u:root:rwx g
+ > setfacl: g: Only directories can have default ACLs
+
+ $ setfacl -x m g
+ > setfacl: g: Malformed access ACL `user::rwx,user:root:---,user:daemon:rw-,group::r-x,other::---': Missing or wrong entry at entry 5
+ setfacl --test -m d:u:daemon:rwx setfacl
+ setfacl --test -n -m d:u:daemon:rwx setfacl
+
+Check if the mask is properly recalculated
+
+ $ mkdir d
+ $ setfacl --test -m u::rwx,u:bin:rwx,g::r-x,o::--- d
+ > d: u::rwx,u:bin:rwx,g::r-x,m::rwx,o::---,*
+
+ $ setfacl --test -m u::rwx,u:bin:rwx,g::r-x,m::---,o::--- d
+ > d: u::rwx,u:bin:rwx,g::r-x,m::---,o::---,*
+
+ $ setfacl --test -d -m u::rwx,u:bin:rwx,g::r-x,o::--- d
+ > d: *,d:u::rwx,d:u:bin:rwx,d:g::r-x,d:m::rwx,d:o::---
+
+ $ setfacl --test -d -m u::rwx,u:bin:rwx,g::r-x,m::---,o::--- d
+ > d: *,d:u::rwx,d:u:bin:rwx,d:g::r-x,d:m::---,d:o::---
+
+ $ su
+ $ cd ..
+ $ rm -r d
diff --git a/test/run b/test/run
new file mode 100755
index 0000000..0e0dee5
--- /dev/null
+++ b/test/run
@@ -0,0 +1,327 @@
+#!/usr/bin/perl -w -U
+
+# Copyright (c) 2007, 2008 Andreas Gruenbacher.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions, and the following disclaimer,
+# without modification, immediately at the beginning of the file.
+# 2. The name of the author may not be used to endorse or promote products
+# derived from this software without specific prior written permission.
+#
+# Alternatively, this software may be distributed under the terms of the
+# GNU Public License ("GPL").
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
+# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+
+#
+# Possible improvements:
+#
+# - distinguish stdout and stderr output
+# - add environment variable like assignments
+# - run up to a specific line
+# - resume at a specific line
+#
+
+use strict;
+use FileHandle;
+use Getopt::Std;
+use POSIX qw(isatty setuid getcwd);
+use vars qw($opt_l $opt_v);
+
+no warnings qw(taint);
+
+$opt_l = ~0; # a really huge number
+getopts('l:v');
+
+my ($OK, $FAILED) = ("ok", "failed");
+if (isatty(fileno(STDOUT))) {
+ $OK = "\033[32m" . $OK . "\033[m";
+ $FAILED = "\033[31m\033[1m" . $FAILED . "\033[m";
+}
+
+$ENV{"TUSER"} = getpwuid($>);
+$ENV{"TGROUP"} = getgrgid($));
+
+sub exec_test($$);
+sub process_test($$$$);
+
+my ($prog, $in, $out) = ([], [], []);
+my $prog_line = 0;
+my ($tests, $failed) = (0,0);
+my $lineno;
+my $width = ($ENV{COLUMNS} || 80) >> 1;
+
+for (;;) {
+ my $line = <>; $lineno++;
+ if (defined $line) {
+ # Substitute %VAR and %{VAR} with environment variables.
+ $line =~ s[%(\w+)][$ENV{$1}]eg;
+ $line =~ s[%{(\w+)}][$ENV{$1}]eg;
+ }
+ if (defined $line) {
+ if ($line =~ s/^\s*< ?//) {
+ push @$in, $line;
+ } elsif ($line =~ s/^\s*> ?//) {
+ push @$out, $line;
+ } else {
+ process_test($prog, $prog_line, $in, $out);
+ last if $prog_line >= $opt_l;
+
+ $prog = [];
+ $prog_line = 0;
+ }
+ if ($line =~ s/^\s*\$ ?//) {
+ $prog = [ map { s/\\(.)/$1/g; $_ } split /(?<!\\)\s+/, $line ];
+ $prog_line = $lineno;
+ $in = [];
+ $out = [];
+ }
+ } else {
+ process_test($prog, $prog_line, $in, $out);
+ last;
+ }
+}
+
+my $status = sprintf("%d commands (%d passed, %d failed)",
+ $tests, $tests-$failed, $failed);
+if (isatty(fileno(STDOUT))) {
+ if ($failed) {
+ $status = "\033[31m\033[1m" . $status . "\033[m";
+ } else {
+ $status = "\033[32m" . $status . "\033[m";
+ }
+}
+print $status, "\n";
+exit $failed ? 1 : 0;
+
+
+sub process_test($$$$) {
+ my ($prog, $prog_line, $in, $out) = @_;
+
+ return unless @$prog;
+
+ my $p = [ @$prog ];
+ print "[$prog_line] \$ ", join(' ',
+ map { s/\s/\\$&/g; $_ } @$p), " -- ";
+ my $result = exec_test($prog, $in);
+ my @good = ();
+ my $nmax = (@$out > @$result) ? @$out : @$result;
+ for (my $n=0; $n < $nmax; $n++) {
+ my $use_re;
+ if (defined $out->[$n] && $out->[$n] =~ /^~ /) {
+ $use_re = 1;
+ $out->[$n] =~ s/^~ //g;
+ }
+
+ if (!defined($out->[$n]) || !defined($result->[$n]) ||
+ (!$use_re && $result->[$n] ne $out->[$n]) ||
+ ( $use_re && $result->[$n] !~ /^$out->[$n]/)) {
+ push @good, ($use_re ? '!~' : '!=');
+ }
+ else {
+ push @good, ($use_re ? '=~' : '==');
+ }
+ }
+ my $good = !(grep /!/, @good);
+ $tests++;
+ $failed++ unless $good;
+ print $good ? $OK : $FAILED, "\n";
+ if (!$good || $opt_v) {
+ for (my $n=0; $n < $nmax; $n++) {
+ my $l = defined($out->[$n]) ? $out->[$n] : "~";
+ chomp $l;
+ my $r = defined($result->[$n]) ? $result->[$n] : "~";
+ chomp $r;
+ print sprintf("%-" . ($width-3) . "s %s %s\n",
+ $r, $good[$n], $l);
+ }
+ }
+}
+
+
+sub su($) {
+ my ($user) = @_;
+
+ $user ||= "root";
+
+ my ($login, $pass, $uid, $gid) = getpwnam($user)
+ or return [ "su: user $user does not exist\n" ];
+ my @groups = ();
+ my $fh = new FileHandle("/etc/group")
+ or return [ "opening /etc/group: $!\n" ];
+ while (<$fh>) {
+ chomp;
+ my ($group, $passwd, $gid, $users) = split /:/;
+ foreach my $u (split /,/, $users) {
+ push @groups, $gid
+ if ($user eq $u);
+ }
+ }
+ $fh->close;
+
+ my $groups = join(" ", ($gid, $gid, @groups));
+ #print STDERR "[[$groups]]\n";
+ $! = 0; # reset errno
+ $> = 0;
+ $( = $gid;
+ $) = $groups;
+ if ($!) {
+ return [ "su: $!\n" ];
+ }
+ if ($uid != 0) {
+ $> = $uid;
+ #$< = $uid;
+ if ($!) {
+ return [ "su: $prog->[1]: $!\n" ];
+ }
+ }
+ #print STDERR "[($>,$<)($(,$))]";
+ return [];
+}
+
+
+sub sg($) {
+ my ($group) = @_;
+
+ my $gid = getgrnam($group)
+ or return [ "sg: group $group does not exist\n" ];
+ my %groups = map { $_ eq $gid ? () : ($_ => 1) } (split /\s/, $));
+
+ #print STDERR "<<", join("/", keys %groups), ">>\n";
+ my $groups = join(" ", ($gid, $gid, keys %groups));
+ #print STDERR "[[$groups]]\n";
+ $! = 0; # reset errno
+ if ($> != 0) {
+ my $uid = $>;
+ $> = 0;
+ $( = $gid;
+ $) = $groups;
+ $> = $uid;
+ } else {
+ $( = $gid;
+ $) = $groups;
+ }
+ if ($!) {
+ return [ "sg: $!\n" ];
+ }
+ print STDERR "[($>,$<)($(,$))]";
+ return [];
+}
+
+
+sub exec_test($$) {
+ my ($prog, $in) = @_;
+ local (*IN, *IN_DUP, *IN2, *OUT_DUP, *OUT, *OUT2);
+ my $needs_shell = (join('', @$prog) =~ /[][|<>"'`\$\*\?]/);
+
+ if ($prog->[0] eq "umask") {
+ umask oct $prog->[1];
+ return [];
+ } elsif ($prog->[0] eq "cd") {
+ if (!chdir $prog->[1]) {
+ return [ "chdir: $prog->[1]: $!\n" ];
+ }
+ $ENV{PWD} = getcwd;
+ return [];
+ } elsif ($prog->[0] eq "su") {
+ return su($prog->[1]);
+ } elsif ($prog->[0] eq "sg") {
+ return sg($prog->[1]);
+ } elsif ($prog->[0] eq "export") {
+ my ($name, $value) = split /=/, $prog->[1];
+ # FIXME: need to evaluate $value, so that things like this will work:
+ # export dir=$PWD/dir
+ $ENV{$name} = $value;
+ return [];
+ } elsif ($prog->[0] eq "unset") {
+ delete $ENV{$prog->[1]};
+ return [];
+ }
+
+ pipe *IN2, *OUT
+ or die "Can't create pipe for reading: $!";
+ open *IN_DUP, "<&STDIN"
+ or *IN_DUP = undef;
+ open *STDIN, "<&IN2"
+ or die "Can't duplicate pipe for reading: $!";
+ close *IN2;
+
+ open *OUT_DUP, ">&STDOUT"
+ or die "Can't duplicate STDOUT: $!";
+ pipe *IN, *OUT2
+ or die "Can't create pipe for writing: $!";
+ open *STDOUT, ">&OUT2"
+ or die "Can't duplicate pipe for writing: $!";
+ close *OUT2;
+
+ *STDOUT->autoflush();
+ *OUT->autoflush();
+
+ if (fork()) {
+ # Server
+ if (*IN_DUP) {
+ open *STDIN, "<&IN_DUP"
+ or die "Can't duplicate STDIN: $!";
+ close *IN_DUP
+ or die "Can't close STDIN duplicate: $!";
+ }
+ open *STDOUT, ">&OUT_DUP"
+ or die "Can't duplicate STDOUT: $!";
+ close *OUT_DUP
+ or die "Can't close STDOUT duplicate: $!";
+
+ foreach my $line (@$in) {
+ #print "> $line";
+ print OUT $line;
+ }
+ close *OUT
+ or die "Can't close pipe for writing: $!";
+
+ my $result = [];
+ while (<IN>) {
+ #print "< $_";
+ if ($needs_shell) {
+ s#^/bin/sh: line \d+: ##;
+ }
+ push @$result, $_;
+ }
+ return $result;
+ } else {
+ # Client
+ $< = $>;
+ close IN
+ or die "Can't close read end for input pipe: $!";
+ close OUT
+ or die "Can't close write end for output pipe: $!";
+ close OUT_DUP
+ or die "Can't close STDOUT duplicate: $!";
+ local *ERR_DUP;
+ open ERR_DUP, ">&STDERR"
+ or die "Can't duplicate STDERR: $!";
+ open STDERR, ">&STDOUT"
+ or die "Can't join STDOUT and STDERR: $!";
+
+ if ($needs_shell) {
+ exec ('/bin/sh', '-c', join(" ", @$prog));
+ } else {
+ exec @$prog;
+ }
+ print STDERR $prog->[0], ": $!\n";
+ exit;
+ }
+}
+
diff --git a/test/setfacl-X.test b/test/setfacl-X.test
new file mode 100644
index 0000000..95b3cd9
--- /dev/null
+++ b/test/setfacl-X.test
@@ -0,0 +1,119 @@
+ $ umask 022
+ $ mkdir d
+ $ cd d
+
+ $ setfacl -dm u:bin:rwx .
+
+ $ touch f g
+ $ chmod ugo+x f
+ $ setfacl -m u:bin:rw,g::r g
+ $ setfacl -m u:root:rwX f g
+ $ getfacl --omit-header --no-effective f g
+ > user::rwx
+ > user:root:rwx
+ > user:bin:rwx
+ > group::r-x
+ > mask::rwx
+ > other::r-x
+ >
+ > user::rw-
+ > user:root:rw-
+ > user:bin:rw-
+ > group::r--
+ > mask::rw-
+ > other::r--
+ >
+
+ $ rm f g
+ $ touch f g
+ $ mkdir d e
+ $ setfacl -n -m u:root:rwX d f e g
+ $ getfacl --omit-header --no-effective d e f g
+ > user::rwx
+ > user:root:rwx
+ > user:bin:rwx
+ > group::r-x
+ > mask::rwx
+ > other::r-x
+ > default:user::rwx
+ > default:user:bin:rwx
+ > default:group::r-x
+ > default:mask::rwx
+ > default:other::r-x
+ >
+ > user::rwx
+ > user:root:rwx
+ > user:bin:rwx
+ > group::r-x
+ > mask::rwx
+ > other::r-x
+ > default:user::rwx
+ > default:user:bin:rwx
+ > default:group::r-x
+ > default:mask::rwx
+ > default:other::r-x
+ >
+ > user::rw-
+ > user:root:rwx
+ > user:bin:rwx
+ > group::r-x
+ > mask::rw-
+ > other::r--
+ >
+ > user::rw-
+ > user:root:rwx
+ > user:bin:rwx
+ > group::r-x
+ > mask::rw-
+ > other::r--
+ >
+
+ $ rm f g
+ $ rmdir d e
+ $ touch f g
+ $ mkdir d e
+ $ setfacl -n -m u:root:rwX f d g e
+ $ getfacl --omit-header --no-effective d e f g
+ > user::rwx
+ > user:root:rwx
+ > user:bin:rwx
+ > group::r-x
+ > mask::rwx
+ > other::r-x
+ > default:user::rwx
+ > default:user:bin:rwx
+ > default:group::r-x
+ > default:mask::rwx
+ > default:other::r-x
+ >
+ > user::rwx
+ > user:root:rwx
+ > user:bin:rwx
+ > group::r-x
+ > mask::rwx
+ > other::r-x
+ > default:user::rwx
+ > default:user:bin:rwx
+ > default:group::r-x
+ > default:mask::rwx
+ > default:other::r-x
+ >
+ > user::rw-
+ > user:root:rwx
+ > user:bin:rwx
+ > group::r-x
+ > mask::rw-
+ > other::r--
+ >
+ > user::rw-
+ > user:root:rwx
+ > user:bin:rwx
+ > group::r-x
+ > mask::rw-
+ > other::r--
+ >
+
+ $ rm f g
+ $ rmdir d e
+ $ cd ..
+ $ rm -rf d
diff --git a/test/sort-getfacl-output b/test/sort-getfacl-output
new file mode 100755
index 0000000..9901ed3
--- /dev/null
+++ b/test/sort-getfacl-output
@@ -0,0 +1,4 @@
+#! /usr/bin/perl -w
+
+undef $/;
+print join("\n\n", sort split(/\n\n/, <>)), "\n\n";
diff --git a/test/utf8-filenames.test b/test/utf8-filenames.test
new file mode 100644
index 0000000..dae0308
--- /dev/null
+++ b/test/utf8-filenames.test
@@ -0,0 +1,14 @@
++Test the setfacl --restore with utf8 paths.
++Regression test: https://bugzilla.redhat.com/show_bug.cgi?id=183181
+
+The utf string UPATH is 250 bytes long and is repeated 4 times to create the
+path that setfacl will use. This size should work on systems with a small 255
+NAME_MAX.
+
+ $ export UPATH="官官話官話官話官話官話官話官話官話官話官話官話官話官話官話官話官話官話官話官話官話官話官話官話官話官話官話官話官話官話官話官話官話官話官話話官話官話官話>官話官話話官話官"
+ $ mkdir -p $UPATH/$UPATH/$UPATH
+ $ touch $UPATH/$UPATH/$UPATH/$UPATH
+ $ getfacl $UPATH/$UPATH/$UPATH/$UPATH > utf8-filenames.acl
+ $ setfacl --restore=utf8-filenames.acl
+ $ rm -R $UPATH
+ $ rm utf8-filenames.acl