diff options
author | Lorry Tar Creator <lorry-tar-importer@lorry> | 2016-05-16 09:22:21 +0000 |
---|---|---|
committer | Lorry Tar Creator <lorry-tar-importer@lorry> | 2016-05-16 09:22:21 +0000 |
commit | d4fdeab4db0d0e699c8fbbb07f12c4e1f64d0f94 (patch) | |
tree | 72231a38ed1cdd48ac6e02acb8b3917acb9dbcf4 /lib | |
download | tar-tarball-d4fdeab4db0d0e699c8fbbb07f12c4e1f64d0f94.tar.gz |
Diffstat (limited to 'lib')
-rw-r--r-- | lib/Makefile.am | 61 | ||||
-rw-r--r-- | lib/Makefile.in | 1516 | ||||
-rw-r--r-- | lib/attr-xattr.in.h | 60 | ||||
-rw-r--r-- | lib/paxerror.c | 361 | ||||
-rw-r--r-- | lib/paxexit-status.c | 3 | ||||
-rw-r--r-- | lib/paxlib.h | 132 | ||||
-rw-r--r-- | lib/paxnames.c | 164 | ||||
-rw-r--r-- | lib/rmt.h | 99 | ||||
-rw-r--r-- | lib/rtapelib.c | 751 | ||||
-rw-r--r-- | lib/stdopen.c | 76 | ||||
-rw-r--r-- | lib/stdopen.h | 16 | ||||
-rw-r--r-- | lib/system-ioctl.h | 55 | ||||
-rw-r--r-- | lib/system.h | 490 | ||||
-rw-r--r-- | lib/wordsplit.c | 1628 | ||||
-rw-r--r-- | lib/wordsplit.h | 168 | ||||
-rw-r--r-- | lib/xattr-at.c | 114 | ||||
-rw-r--r-- | lib/xattr-at.h | 74 |
17 files changed, 5768 insertions, 0 deletions
diff --git a/lib/Makefile.am b/lib/Makefile.am new file mode 100644 index 0000000..c7318d9 --- /dev/null +++ b/lib/Makefile.am @@ -0,0 +1,61 @@ +# Makefile for GNU tar library. -*- Makefile -*- + +# Copyright 1994-1997, 1999-2001, 2003-2007, 2009-2010, 2013-2014, 2016 +# Free Software Foundation, Inc. + +# This file is part of GNU tar. + +# GNU tar is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. + +# GNU tar 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/>. + +noinst_LIBRARIES=libtar.a +rmt-command.h : Makefile + $(AM_V_GEN)rm -f $@-t $@ + $(AM_V_at)echo "#ifndef DEFAULT_RMT_COMMAND" >> $@-t + $(AM_V_at)echo "# define DEFAULT_RMT_COMMAND \"$(DEFAULT_RMT_DIR)/`echo rmt | sed '$(transform)'`$(EXEEXT)\"" >> $@-t + $(AM_V_at)echo "#endif" >> $@-t + $(AM_V_at)mv $@-t $@ +BUILT_SOURCES = rmt-command.h +CLEANFILES = rmt-command.h rmt-command.h-t +AM_CPPFLAGS = -I$(top_srcdir)/gnu -I../ -I../gnu +AM_CFLAGS = $(GNULIB_WARN_CFLAGS) $(WERROR_CFLAGS) + +noinst_HEADERS = \ + paxlib.h\ + rmt.h\ + stdopen.h\ + system.h\ + system-ioctl.h\ + wordsplit.h\ + xattr-at.h + +libtar_a_SOURCES = \ + paxerror.c paxexit-status.c paxlib.h paxnames.c \ + rtapelib.c \ + rmt.h \ + stdopen.c stdopen.h \ + system.h system-ioctl.h \ + wordsplit.c\ + xattr-at.c + +if !TAR_COND_XATTR_H +BUILT_SOURCES += attr/xattr.h +attr/xattr.h: attr-xattr.in.h $(top_builddir)/config.status + $(AM_V_at)$(MKDIR_P) attr + $(AM_V_GEN)rm -f $@-t $@ && \ + cp $(srcdir)/attr-xattr.in.h attr/xattr.h +endif + +MOSTLYCLEANFILES = attr/xattr.h + +EXTRA_DIST = attr-xattr.in.h diff --git a/lib/Makefile.in b/lib/Makefile.in new file mode 100644 index 0000000..77c68dd --- /dev/null +++ b/lib/Makefile.in @@ -0,0 +1,1516 @@ +# Makefile.in generated by automake 1.14 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2013 Free Software Foundation, Inc. + +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +# Makefile for GNU tar library. -*- Makefile -*- + +# Copyright 1994-1997, 1999-2001, 2003-2007, 2009-2010, 2013-2014, 2016 +# Free Software Foundation, Inc. + +# This file is part of GNU tar. + +# GNU tar is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. + +# GNU tar 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/>. + + +VPATH = @srcdir@ +am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +@TAR_COND_XATTR_H_FALSE@am__append_1 = attr/xattr.h +subdir = lib +DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ + $(top_srcdir)/build-aux/depcomp $(noinst_HEADERS) +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/00gnulib.m4 \ + $(top_srcdir)/m4/absolute-header.m4 $(top_srcdir)/m4/acl.m4 \ + $(top_srcdir)/m4/alloca.m4 $(top_srcdir)/m4/argp.m4 \ + $(top_srcdir)/m4/backupfile.m4 $(top_srcdir)/m4/bison.m4 \ + $(top_srcdir)/m4/btowc.m4 $(top_srcdir)/m4/canonicalize.m4 \ + $(top_srcdir)/m4/chdir-long.m4 $(top_srcdir)/m4/chown.m4 \ + $(top_srcdir)/m4/clock_time.m4 \ + $(top_srcdir)/m4/close-stream.m4 $(top_srcdir)/m4/close.m4 \ + $(top_srcdir)/m4/closedir.m4 $(top_srcdir)/m4/closeout.m4 \ + $(top_srcdir)/m4/codeset.m4 $(top_srcdir)/m4/configmake.m4 \ + $(top_srcdir)/m4/d-ino.m4 $(top_srcdir)/m4/dirent-safer.m4 \ + $(top_srcdir)/m4/dirent_h.m4 $(top_srcdir)/m4/dirfd.m4 \ + $(top_srcdir)/m4/dirname.m4 \ + $(top_srcdir)/m4/double-slash-root.m4 $(top_srcdir)/m4/dup.m4 \ + $(top_srcdir)/m4/dup2.m4 $(top_srcdir)/m4/eealloc.m4 \ + $(top_srcdir)/m4/environ.m4 $(top_srcdir)/m4/errno_h.m4 \ + $(top_srcdir)/m4/error.m4 $(top_srcdir)/m4/euidaccess.m4 \ + $(top_srcdir)/m4/exponentd.m4 $(top_srcdir)/m4/extensions.m4 \ + $(top_srcdir)/m4/extern-inline.m4 \ + $(top_srcdir)/m4/faccessat.m4 $(top_srcdir)/m4/fchdir.m4 \ + $(top_srcdir)/m4/fchmodat.m4 $(top_srcdir)/m4/fchownat.m4 \ + $(top_srcdir)/m4/fcntl-o.m4 $(top_srcdir)/m4/fcntl.m4 \ + $(top_srcdir)/m4/fcntl_h.m4 $(top_srcdir)/m4/fdopendir.m4 \ + $(top_srcdir)/m4/fileblocks.m4 $(top_srcdir)/m4/filenamecat.m4 \ + $(top_srcdir)/m4/flexmember.m4 $(top_srcdir)/m4/float_h.m4 \ + $(top_srcdir)/m4/fnmatch.m4 $(top_srcdir)/m4/fpending.m4 \ + $(top_srcdir)/m4/fseek.m4 $(top_srcdir)/m4/fseeko.m4 \ + $(top_srcdir)/m4/fstat.m4 $(top_srcdir)/m4/fstatat.m4 \ + $(top_srcdir)/m4/futimens.m4 \ + $(top_srcdir)/m4/getcwd-abort-bug.m4 \ + $(top_srcdir)/m4/getcwd-path-max.m4 $(top_srcdir)/m4/getcwd.m4 \ + $(top_srcdir)/m4/getdelim.m4 $(top_srcdir)/m4/getdtablesize.m4 \ + $(top_srcdir)/m4/getgroups.m4 $(top_srcdir)/m4/getline.m4 \ + $(top_srcdir)/m4/getopt.m4 $(top_srcdir)/m4/getpagesize.m4 \ + $(top_srcdir)/m4/gettext.m4 $(top_srcdir)/m4/gettime.m4 \ + $(top_srcdir)/m4/gettimeofday.m4 $(top_srcdir)/m4/glibc21.m4 \ + $(top_srcdir)/m4/gnulib-common.m4 \ + $(top_srcdir)/m4/gnulib-comp.m4 \ + $(top_srcdir)/m4/group-member.m4 $(top_srcdir)/m4/human.m4 \ + $(top_srcdir)/m4/iconv.m4 $(top_srcdir)/m4/include_next.m4 \ + $(top_srcdir)/m4/intlmacosx.m4 $(top_srcdir)/m4/intmax_t.m4 \ + $(top_srcdir)/m4/inttostr.m4 $(top_srcdir)/m4/inttypes-pri.m4 \ + $(top_srcdir)/m4/inttypes.m4 $(top_srcdir)/m4/inttypes_h.m4 \ + $(top_srcdir)/m4/iswblank.m4 $(top_srcdir)/m4/langinfo_h.m4 \ + $(top_srcdir)/m4/largefile.m4 $(top_srcdir)/m4/lchown.m4 \ + $(top_srcdir)/m4/lib-ld.m4 $(top_srcdir)/m4/lib-link.m4 \ + $(top_srcdir)/m4/lib-prefix.m4 \ + $(top_srcdir)/m4/libunistring-base.m4 \ + $(top_srcdir)/m4/link-follow.m4 $(top_srcdir)/m4/link.m4 \ + $(top_srcdir)/m4/linkat.m4 $(top_srcdir)/m4/localcharset.m4 \ + $(top_srcdir)/m4/locale-fr.m4 $(top_srcdir)/m4/locale-ja.m4 \ + $(top_srcdir)/m4/locale-zh.m4 $(top_srcdir)/m4/locale_h.m4 \ + $(top_srcdir)/m4/localeconv.m4 $(top_srcdir)/m4/longlong.m4 \ + $(top_srcdir)/m4/lseek.m4 $(top_srcdir)/m4/lstat.m4 \ + $(top_srcdir)/m4/malloc.m4 $(top_srcdir)/m4/malloca.m4 \ + $(top_srcdir)/m4/manywarnings.m4 $(top_srcdir)/m4/mbchar.m4 \ + $(top_srcdir)/m4/mbiter.m4 $(top_srcdir)/m4/mbrtowc.m4 \ + $(top_srcdir)/m4/mbsinit.m4 $(top_srcdir)/m4/mbsrtowcs.m4 \ + $(top_srcdir)/m4/mbstate_t.m4 $(top_srcdir)/m4/mbtowc.m4 \ + $(top_srcdir)/m4/memchr.m4 $(top_srcdir)/m4/mempcpy.m4 \ + $(top_srcdir)/m4/memrchr.m4 $(top_srcdir)/m4/mkdir.m4 \ + $(top_srcdir)/m4/mkdirat.m4 $(top_srcdir)/m4/mkdtemp.m4 \ + $(top_srcdir)/m4/mkfifo.m4 $(top_srcdir)/m4/mkfifoat.m4 \ + $(top_srcdir)/m4/mknod.m4 $(top_srcdir)/m4/mktime.m4 \ + $(top_srcdir)/m4/mmap-anon.m4 $(top_srcdir)/m4/mode_t.m4 \ + $(top_srcdir)/m4/modechange.m4 $(top_srcdir)/m4/msvc-inval.m4 \ + $(top_srcdir)/m4/msvc-nothrow.m4 $(top_srcdir)/m4/multiarch.m4 \ + $(top_srcdir)/m4/nl_langinfo.m4 $(top_srcdir)/m4/nls.m4 \ + $(top_srcdir)/m4/nocrash.m4 $(top_srcdir)/m4/obstack.m4 \ + $(top_srcdir)/m4/off_t.m4 $(top_srcdir)/m4/open.m4 \ + $(top_srcdir)/m4/openat.m4 $(top_srcdir)/m4/opendir.m4 \ + $(top_srcdir)/m4/parse-datetime.m4 $(top_srcdir)/m4/pathmax.m4 \ + $(top_srcdir)/m4/paxutils.m4 $(top_srcdir)/m4/po.m4 \ + $(top_srcdir)/m4/printf.m4 $(top_srcdir)/m4/priv-set.m4 \ + $(top_srcdir)/m4/progtest.m4 $(top_srcdir)/m4/quote.m4 \ + $(top_srcdir)/m4/quotearg.m4 $(top_srcdir)/m4/raise.m4 \ + $(top_srcdir)/m4/rawmemchr.m4 $(top_srcdir)/m4/read.m4 \ + $(top_srcdir)/m4/readdir.m4 $(top_srcdir)/m4/readlink.m4 \ + $(top_srcdir)/m4/readlinkat.m4 $(top_srcdir)/m4/realloc.m4 \ + $(top_srcdir)/m4/regex.m4 $(top_srcdir)/m4/rename.m4 \ + $(top_srcdir)/m4/renameat.m4 $(top_srcdir)/m4/rewinddir.m4 \ + $(top_srcdir)/m4/rmdir.m4 $(top_srcdir)/m4/rmt.m4 \ + $(top_srcdir)/m4/rpmatch.m4 $(top_srcdir)/m4/rtapelib.m4 \ + $(top_srcdir)/m4/safe-read.m4 $(top_srcdir)/m4/safe-write.m4 \ + $(top_srcdir)/m4/save-cwd.m4 $(top_srcdir)/m4/savedir.m4 \ + $(top_srcdir)/m4/secure_getenv.m4 \ + $(top_srcdir)/m4/selinux-context-h.m4 \ + $(top_srcdir)/m4/selinux-selinux-h.m4 \ + $(top_srcdir)/m4/setenv.m4 $(top_srcdir)/m4/signal_h.m4 \ + $(top_srcdir)/m4/size_max.m4 $(top_srcdir)/m4/sleep.m4 \ + $(top_srcdir)/m4/snprintf.m4 $(top_srcdir)/m4/ssize_t.m4 \ + $(top_srcdir)/m4/stat-time.m4 $(top_srcdir)/m4/stat.m4 \ + $(top_srcdir)/m4/stdalign.m4 $(top_srcdir)/m4/stdarg.m4 \ + $(top_srcdir)/m4/stdbool.m4 $(top_srcdir)/m4/stddef_h.m4 \ + $(top_srcdir)/m4/stdint.m4 $(top_srcdir)/m4/stdint_h.m4 \ + $(top_srcdir)/m4/stdio_h.m4 $(top_srcdir)/m4/stdlib_h.m4 \ + $(top_srcdir)/m4/stpcpy.m4 $(top_srcdir)/m4/strcase.m4 \ + $(top_srcdir)/m4/strchrnul.m4 $(top_srcdir)/m4/strdup.m4 \ + $(top_srcdir)/m4/strerror.m4 $(top_srcdir)/m4/strftime.m4 \ + $(top_srcdir)/m4/string_h.m4 $(top_srcdir)/m4/strings_h.m4 \ + $(top_srcdir)/m4/strndup.m4 $(top_srcdir)/m4/strnlen.m4 \ + $(top_srcdir)/m4/strtoimax.m4 $(top_srcdir)/m4/strtol.m4 \ + $(top_srcdir)/m4/strtoll.m4 $(top_srcdir)/m4/strtoul.m4 \ + $(top_srcdir)/m4/strtoull.m4 $(top_srcdir)/m4/strtoumax.m4 \ + $(top_srcdir)/m4/symlink.m4 $(top_srcdir)/m4/symlinkat.m4 \ + $(top_srcdir)/m4/sys_socket_h.m4 \ + $(top_srcdir)/m4/sys_stat_h.m4 $(top_srcdir)/m4/sys_time_h.m4 \ + $(top_srcdir)/m4/sys_types_h.m4 $(top_srcdir)/m4/sysexits.m4 \ + $(top_srcdir)/m4/system.m4 $(top_srcdir)/m4/tempname.m4 \ + $(top_srcdir)/m4/time_h.m4 $(top_srcdir)/m4/time_r.m4 \ + $(top_srcdir)/m4/time_rz.m4 $(top_srcdir)/m4/timegm.m4 \ + $(top_srcdir)/m4/timespec.m4 $(top_srcdir)/m4/tm_gmtoff.m4 \ + $(top_srcdir)/m4/ulonglong.m4 $(top_srcdir)/m4/unistd-safer.m4 \ + $(top_srcdir)/m4/unistd_h.m4 $(top_srcdir)/m4/unlink.m4 \ + $(top_srcdir)/m4/unlinkat.m4 $(top_srcdir)/m4/unlinkdir.m4 \ + $(top_srcdir)/m4/unlocked-io.m4 $(top_srcdir)/m4/utimbuf.m4 \ + $(top_srcdir)/m4/utimens.m4 $(top_srcdir)/m4/utimensat.m4 \ + $(top_srcdir)/m4/utimes.m4 $(top_srcdir)/m4/vasnprintf.m4 \ + $(top_srcdir)/m4/vasprintf.m4 $(top_srcdir)/m4/version-etc.m4 \ + $(top_srcdir)/m4/vsnprintf.m4 $(top_srcdir)/m4/warn-on-use.m4 \ + $(top_srcdir)/m4/warnings.m4 $(top_srcdir)/m4/wchar_h.m4 \ + $(top_srcdir)/m4/wchar_t.m4 $(top_srcdir)/m4/wcrtomb.m4 \ + $(top_srcdir)/m4/wctype_h.m4 $(top_srcdir)/m4/wcwidth.m4 \ + $(top_srcdir)/m4/wint_t.m4 $(top_srcdir)/m4/write.m4 \ + $(top_srcdir)/m4/xalloc.m4 $(top_srcdir)/m4/xgetcwd.m4 \ + $(top_srcdir)/m4/xsize.m4 $(top_srcdir)/m4/xstrndup.m4 \ + $(top_srcdir)/m4/xstrtol.m4 $(top_srcdir)/m4/xvasprintf.m4 \ + $(top_srcdir)/acinclude.m4 $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +LIBRARIES = $(noinst_LIBRARIES) +AM_V_AR = $(am__v_AR_@AM_V@) +am__v_AR_ = $(am__v_AR_@AM_DEFAULT_V@) +am__v_AR_0 = @echo " AR " $@; +am__v_AR_1 = +libtar_a_AR = $(AR) $(ARFLAGS) +libtar_a_LIBADD = +am_libtar_a_OBJECTS = paxerror.$(OBJEXT) paxexit-status.$(OBJEXT) \ + paxnames.$(OBJEXT) rtapelib.$(OBJEXT) stdopen.$(OBJEXT) \ + wordsplit.$(OBJEXT) xattr-at.$(OBJEXT) +libtar_a_OBJECTS = $(am_libtar_a_OBJECTS) +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) +depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp +am__depfiles_maybe = depfiles +am__mv = mv -f +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +AM_V_CC = $(am__v_CC_@AM_V@) +am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) +am__v_CC_0 = @echo " CC " $@; +am__v_CC_1 = +CCLD = $(CC) +LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_CCLD = $(am__v_CCLD_@AM_V@) +am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) +am__v_CCLD_0 = @echo " CCLD " $@; +am__v_CCLD_1 = +SOURCES = $(libtar_a_SOURCES) +DIST_SOURCES = $(libtar_a_SOURCES) +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +HEADERS = $(noinst_HEADERS) +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` +ETAGS = etags +CTAGS = ctags +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +pkglibexecdir = @pkglibexecdir@ +ACLOCAL = @ACLOCAL@ +ALLOCA = @ALLOCA@ +ALLOCA_H = @ALLOCA_H@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +APPLE_UNIVERSAL_BUILD = @APPLE_UNIVERSAL_BUILD@ +AR = @AR@ +ARFLAGS = @ARFLAGS@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOM4TE = @AUTOM4TE@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +BACKUP_LIBEXEC_SCRIPTS = @BACKUP_LIBEXEC_SCRIPTS@ +BACKUP_SBIN_SCRIPTS = @BACKUP_SBIN_SCRIPTS@ +BACKUP_SED_COND = @BACKUP_SED_COND@ +BITSIZEOF_PTRDIFF_T = @BITSIZEOF_PTRDIFF_T@ +BITSIZEOF_SIG_ATOMIC_T = @BITSIZEOF_SIG_ATOMIC_T@ +BITSIZEOF_SIZE_T = @BITSIZEOF_SIZE_T@ +BITSIZEOF_WCHAR_T = @BITSIZEOF_WCHAR_T@ +BITSIZEOF_WINT_T = @BITSIZEOF_WINT_T@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFAULT_ARCHIVE = @DEFAULT_ARCHIVE@ +DEFAULT_ARCHIVE_FORMAT = @DEFAULT_ARCHIVE_FORMAT@ +DEFAULT_BLOCKING = @DEFAULT_BLOCKING@ +DEFAULT_QUOTING_STYLE = @DEFAULT_QUOTING_STYLE@ +DEFAULT_RMT_COMMAND = @DEFAULT_RMT_COMMAND@ +DEFAULT_RMT_DIR = @DEFAULT_RMT_DIR@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EMULTIHOP_HIDDEN = @EMULTIHOP_HIDDEN@ +EMULTIHOP_VALUE = @EMULTIHOP_VALUE@ +ENOLINK_HIDDEN = @ENOLINK_HIDDEN@ +ENOLINK_VALUE = @ENOLINK_VALUE@ +EOVERFLOW_HIDDEN = @EOVERFLOW_HIDDEN@ +EOVERFLOW_VALUE = @EOVERFLOW_VALUE@ +ERRNO_H = @ERRNO_H@ +EXEEXT = @EXEEXT@ +FLOAT_H = @FLOAT_H@ +FNMATCH_H = @FNMATCH_H@ +GETOPT_H = @GETOPT_H@ +GETTEXT_MACRO_VERSION = @GETTEXT_MACRO_VERSION@ +GLIBC21 = @GLIBC21@ +GMSGFMT = @GMSGFMT@ +GMSGFMT_015 = @GMSGFMT_015@ +GNULIB_ALPHASORT = @GNULIB_ALPHASORT@ +GNULIB_ATOLL = @GNULIB_ATOLL@ +GNULIB_BTOWC = @GNULIB_BTOWC@ +GNULIB_CALLOC_POSIX = @GNULIB_CALLOC_POSIX@ +GNULIB_CANONICALIZE_FILE_NAME = @GNULIB_CANONICALIZE_FILE_NAME@ +GNULIB_CHDIR = @GNULIB_CHDIR@ +GNULIB_CHOWN = @GNULIB_CHOWN@ +GNULIB_CLOSE = @GNULIB_CLOSE@ +GNULIB_CLOSEDIR = @GNULIB_CLOSEDIR@ +GNULIB_DIRFD = @GNULIB_DIRFD@ +GNULIB_DPRINTF = @GNULIB_DPRINTF@ +GNULIB_DUP = @GNULIB_DUP@ +GNULIB_DUP2 = @GNULIB_DUP2@ +GNULIB_DUP3 = @GNULIB_DUP3@ +GNULIB_DUPLOCALE = @GNULIB_DUPLOCALE@ +GNULIB_ENVIRON = @GNULIB_ENVIRON@ +GNULIB_EUIDACCESS = @GNULIB_EUIDACCESS@ +GNULIB_FACCESSAT = @GNULIB_FACCESSAT@ +GNULIB_FCHDIR = @GNULIB_FCHDIR@ +GNULIB_FCHMODAT = @GNULIB_FCHMODAT@ +GNULIB_FCHOWNAT = @GNULIB_FCHOWNAT@ +GNULIB_FCLOSE = @GNULIB_FCLOSE@ +GNULIB_FCNTL = @GNULIB_FCNTL@ +GNULIB_FDATASYNC = @GNULIB_FDATASYNC@ +GNULIB_FDOPEN = @GNULIB_FDOPEN@ +GNULIB_FDOPENDIR = @GNULIB_FDOPENDIR@ +GNULIB_FFLUSH = @GNULIB_FFLUSH@ +GNULIB_FFS = @GNULIB_FFS@ +GNULIB_FFSL = @GNULIB_FFSL@ +GNULIB_FFSLL = @GNULIB_FFSLL@ +GNULIB_FGETC = @GNULIB_FGETC@ +GNULIB_FGETS = @GNULIB_FGETS@ +GNULIB_FOPEN = @GNULIB_FOPEN@ +GNULIB_FPRINTF = @GNULIB_FPRINTF@ +GNULIB_FPRINTF_POSIX = @GNULIB_FPRINTF_POSIX@ +GNULIB_FPURGE = @GNULIB_FPURGE@ +GNULIB_FPUTC = @GNULIB_FPUTC@ +GNULIB_FPUTS = @GNULIB_FPUTS@ +GNULIB_FREAD = @GNULIB_FREAD@ +GNULIB_FREOPEN = @GNULIB_FREOPEN@ +GNULIB_FSCANF = @GNULIB_FSCANF@ +GNULIB_FSEEK = @GNULIB_FSEEK@ +GNULIB_FSEEKO = @GNULIB_FSEEKO@ +GNULIB_FSTAT = @GNULIB_FSTAT@ +GNULIB_FSTATAT = @GNULIB_FSTATAT@ +GNULIB_FSYNC = @GNULIB_FSYNC@ +GNULIB_FTELL = @GNULIB_FTELL@ +GNULIB_FTELLO = @GNULIB_FTELLO@ +GNULIB_FTRUNCATE = @GNULIB_FTRUNCATE@ +GNULIB_FUTIMENS = @GNULIB_FUTIMENS@ +GNULIB_FWRITE = @GNULIB_FWRITE@ +GNULIB_GETC = @GNULIB_GETC@ +GNULIB_GETCHAR = @GNULIB_GETCHAR@ +GNULIB_GETCWD = @GNULIB_GETCWD@ +GNULIB_GETDELIM = @GNULIB_GETDELIM@ +GNULIB_GETDOMAINNAME = @GNULIB_GETDOMAINNAME@ +GNULIB_GETDTABLESIZE = @GNULIB_GETDTABLESIZE@ +GNULIB_GETGROUPS = @GNULIB_GETGROUPS@ +GNULIB_GETHOSTNAME = @GNULIB_GETHOSTNAME@ +GNULIB_GETLINE = @GNULIB_GETLINE@ +GNULIB_GETLOADAVG = @GNULIB_GETLOADAVG@ +GNULIB_GETLOGIN = @GNULIB_GETLOGIN@ +GNULIB_GETLOGIN_R = @GNULIB_GETLOGIN_R@ +GNULIB_GETPAGESIZE = @GNULIB_GETPAGESIZE@ +GNULIB_GETSUBOPT = @GNULIB_GETSUBOPT@ +GNULIB_GETTIMEOFDAY = @GNULIB_GETTIMEOFDAY@ +GNULIB_GETUSERSHELL = @GNULIB_GETUSERSHELL@ +GNULIB_GL_UNISTD_H_GETOPT = @GNULIB_GL_UNISTD_H_GETOPT@ +GNULIB_GRANTPT = @GNULIB_GRANTPT@ +GNULIB_GROUP_MEMBER = @GNULIB_GROUP_MEMBER@ +GNULIB_IMAXABS = @GNULIB_IMAXABS@ +GNULIB_IMAXDIV = @GNULIB_IMAXDIV@ +GNULIB_ISATTY = @GNULIB_ISATTY@ +GNULIB_ISWBLANK = @GNULIB_ISWBLANK@ +GNULIB_ISWCTYPE = @GNULIB_ISWCTYPE@ +GNULIB_LCHMOD = @GNULIB_LCHMOD@ +GNULIB_LCHOWN = @GNULIB_LCHOWN@ +GNULIB_LINK = @GNULIB_LINK@ +GNULIB_LINKAT = @GNULIB_LINKAT@ +GNULIB_LOCALECONV = @GNULIB_LOCALECONV@ +GNULIB_LSEEK = @GNULIB_LSEEK@ +GNULIB_LSTAT = @GNULIB_LSTAT@ +GNULIB_MALLOC_POSIX = @GNULIB_MALLOC_POSIX@ +GNULIB_MBRLEN = @GNULIB_MBRLEN@ +GNULIB_MBRTOWC = @GNULIB_MBRTOWC@ +GNULIB_MBSCASECMP = @GNULIB_MBSCASECMP@ +GNULIB_MBSCASESTR = @GNULIB_MBSCASESTR@ +GNULIB_MBSCHR = @GNULIB_MBSCHR@ +GNULIB_MBSCSPN = @GNULIB_MBSCSPN@ +GNULIB_MBSINIT = @GNULIB_MBSINIT@ +GNULIB_MBSLEN = @GNULIB_MBSLEN@ +GNULIB_MBSNCASECMP = @GNULIB_MBSNCASECMP@ +GNULIB_MBSNLEN = @GNULIB_MBSNLEN@ +GNULIB_MBSNRTOWCS = @GNULIB_MBSNRTOWCS@ +GNULIB_MBSPBRK = @GNULIB_MBSPBRK@ +GNULIB_MBSPCASECMP = @GNULIB_MBSPCASECMP@ +GNULIB_MBSRCHR = @GNULIB_MBSRCHR@ +GNULIB_MBSRTOWCS = @GNULIB_MBSRTOWCS@ +GNULIB_MBSSEP = @GNULIB_MBSSEP@ +GNULIB_MBSSPN = @GNULIB_MBSSPN@ +GNULIB_MBSSTR = @GNULIB_MBSSTR@ +GNULIB_MBSTOK_R = @GNULIB_MBSTOK_R@ +GNULIB_MBTOWC = @GNULIB_MBTOWC@ +GNULIB_MEMCHR = @GNULIB_MEMCHR@ +GNULIB_MEMMEM = @GNULIB_MEMMEM@ +GNULIB_MEMPCPY = @GNULIB_MEMPCPY@ +GNULIB_MEMRCHR = @GNULIB_MEMRCHR@ +GNULIB_MKDIRAT = @GNULIB_MKDIRAT@ +GNULIB_MKDTEMP = @GNULIB_MKDTEMP@ +GNULIB_MKFIFO = @GNULIB_MKFIFO@ +GNULIB_MKFIFOAT = @GNULIB_MKFIFOAT@ +GNULIB_MKNOD = @GNULIB_MKNOD@ +GNULIB_MKNODAT = @GNULIB_MKNODAT@ +GNULIB_MKOSTEMP = @GNULIB_MKOSTEMP@ +GNULIB_MKOSTEMPS = @GNULIB_MKOSTEMPS@ +GNULIB_MKSTEMP = @GNULIB_MKSTEMP@ +GNULIB_MKSTEMPS = @GNULIB_MKSTEMPS@ +GNULIB_MKTIME = @GNULIB_MKTIME@ +GNULIB_NANOSLEEP = @GNULIB_NANOSLEEP@ +GNULIB_NL_LANGINFO = @GNULIB_NL_LANGINFO@ +GNULIB_NONBLOCKING = @GNULIB_NONBLOCKING@ +GNULIB_OBSTACK_PRINTF = @GNULIB_OBSTACK_PRINTF@ +GNULIB_OBSTACK_PRINTF_POSIX = @GNULIB_OBSTACK_PRINTF_POSIX@ +GNULIB_OPEN = @GNULIB_OPEN@ +GNULIB_OPENAT = @GNULIB_OPENAT@ +GNULIB_OPENDIR = @GNULIB_OPENDIR@ +GNULIB_PCLOSE = @GNULIB_PCLOSE@ +GNULIB_PERROR = @GNULIB_PERROR@ +GNULIB_PIPE = @GNULIB_PIPE@ +GNULIB_PIPE2 = @GNULIB_PIPE2@ +GNULIB_POPEN = @GNULIB_POPEN@ +GNULIB_POSIX_OPENPT = @GNULIB_POSIX_OPENPT@ +GNULIB_PREAD = @GNULIB_PREAD@ +GNULIB_PRINTF = @GNULIB_PRINTF@ +GNULIB_PRINTF_POSIX = @GNULIB_PRINTF_POSIX@ +GNULIB_PTHREAD_SIGMASK = @GNULIB_PTHREAD_SIGMASK@ +GNULIB_PTSNAME = @GNULIB_PTSNAME@ +GNULIB_PTSNAME_R = @GNULIB_PTSNAME_R@ +GNULIB_PUTC = @GNULIB_PUTC@ +GNULIB_PUTCHAR = @GNULIB_PUTCHAR@ +GNULIB_PUTENV = @GNULIB_PUTENV@ +GNULIB_PUTS = @GNULIB_PUTS@ +GNULIB_PWRITE = @GNULIB_PWRITE@ +GNULIB_QSORT_R = @GNULIB_QSORT_R@ +GNULIB_RAISE = @GNULIB_RAISE@ +GNULIB_RANDOM = @GNULIB_RANDOM@ +GNULIB_RANDOM_R = @GNULIB_RANDOM_R@ +GNULIB_RAWMEMCHR = @GNULIB_RAWMEMCHR@ +GNULIB_READ = @GNULIB_READ@ +GNULIB_READDIR = @GNULIB_READDIR@ +GNULIB_READLINK = @GNULIB_READLINK@ +GNULIB_READLINKAT = @GNULIB_READLINKAT@ +GNULIB_REALLOC_POSIX = @GNULIB_REALLOC_POSIX@ +GNULIB_REALPATH = @GNULIB_REALPATH@ +GNULIB_REMOVE = @GNULIB_REMOVE@ +GNULIB_RENAME = @GNULIB_RENAME@ +GNULIB_RENAMEAT = @GNULIB_RENAMEAT@ +GNULIB_REWINDDIR = @GNULIB_REWINDDIR@ +GNULIB_RMDIR = @GNULIB_RMDIR@ +GNULIB_RPMATCH = @GNULIB_RPMATCH@ +GNULIB_SCANDIR = @GNULIB_SCANDIR@ +GNULIB_SCANF = @GNULIB_SCANF@ +GNULIB_SECURE_GETENV = @GNULIB_SECURE_GETENV@ +GNULIB_SETENV = @GNULIB_SETENV@ +GNULIB_SETHOSTNAME = @GNULIB_SETHOSTNAME@ +GNULIB_SETLOCALE = @GNULIB_SETLOCALE@ +GNULIB_SIGACTION = @GNULIB_SIGACTION@ +GNULIB_SIGNAL_H_SIGPIPE = @GNULIB_SIGNAL_H_SIGPIPE@ +GNULIB_SIGPROCMASK = @GNULIB_SIGPROCMASK@ +GNULIB_SLEEP = @GNULIB_SLEEP@ +GNULIB_SNPRINTF = @GNULIB_SNPRINTF@ +GNULIB_SPRINTF_POSIX = @GNULIB_SPRINTF_POSIX@ +GNULIB_STAT = @GNULIB_STAT@ +GNULIB_STDIO_H_NONBLOCKING = @GNULIB_STDIO_H_NONBLOCKING@ +GNULIB_STDIO_H_SIGPIPE = @GNULIB_STDIO_H_SIGPIPE@ +GNULIB_STPCPY = @GNULIB_STPCPY@ +GNULIB_STPNCPY = @GNULIB_STPNCPY@ +GNULIB_STRCASESTR = @GNULIB_STRCASESTR@ +GNULIB_STRCHRNUL = @GNULIB_STRCHRNUL@ +GNULIB_STRDUP = @GNULIB_STRDUP@ +GNULIB_STRERROR = @GNULIB_STRERROR@ +GNULIB_STRERROR_R = @GNULIB_STRERROR_R@ +GNULIB_STRNCAT = @GNULIB_STRNCAT@ +GNULIB_STRNDUP = @GNULIB_STRNDUP@ +GNULIB_STRNLEN = @GNULIB_STRNLEN@ +GNULIB_STRPBRK = @GNULIB_STRPBRK@ +GNULIB_STRPTIME = @GNULIB_STRPTIME@ +GNULIB_STRSEP = @GNULIB_STRSEP@ +GNULIB_STRSIGNAL = @GNULIB_STRSIGNAL@ +GNULIB_STRSTR = @GNULIB_STRSTR@ +GNULIB_STRTOD = @GNULIB_STRTOD@ +GNULIB_STRTOIMAX = @GNULIB_STRTOIMAX@ +GNULIB_STRTOK_R = @GNULIB_STRTOK_R@ +GNULIB_STRTOLL = @GNULIB_STRTOLL@ +GNULIB_STRTOULL = @GNULIB_STRTOULL@ +GNULIB_STRTOUMAX = @GNULIB_STRTOUMAX@ +GNULIB_STRVERSCMP = @GNULIB_STRVERSCMP@ +GNULIB_SYMLINK = @GNULIB_SYMLINK@ +GNULIB_SYMLINKAT = @GNULIB_SYMLINKAT@ +GNULIB_SYSTEM_POSIX = @GNULIB_SYSTEM_POSIX@ +GNULIB_TEST_WARN_CFLAGS = @GNULIB_TEST_WARN_CFLAGS@ +GNULIB_TIMEGM = @GNULIB_TIMEGM@ +GNULIB_TIME_R = @GNULIB_TIME_R@ +GNULIB_TIME_RZ = @GNULIB_TIME_RZ@ +GNULIB_TMPFILE = @GNULIB_TMPFILE@ +GNULIB_TOWCTRANS = @GNULIB_TOWCTRANS@ +GNULIB_TTYNAME_R = @GNULIB_TTYNAME_R@ +GNULIB_UNISTD_H_NONBLOCKING = @GNULIB_UNISTD_H_NONBLOCKING@ +GNULIB_UNISTD_H_SIGPIPE = @GNULIB_UNISTD_H_SIGPIPE@ +GNULIB_UNLINK = @GNULIB_UNLINK@ +GNULIB_UNLINKAT = @GNULIB_UNLINKAT@ +GNULIB_UNLOCKPT = @GNULIB_UNLOCKPT@ +GNULIB_UNSETENV = @GNULIB_UNSETENV@ +GNULIB_USLEEP = @GNULIB_USLEEP@ +GNULIB_UTIMENSAT = @GNULIB_UTIMENSAT@ +GNULIB_VASPRINTF = @GNULIB_VASPRINTF@ +GNULIB_VDPRINTF = @GNULIB_VDPRINTF@ +GNULIB_VFPRINTF = @GNULIB_VFPRINTF@ +GNULIB_VFPRINTF_POSIX = @GNULIB_VFPRINTF_POSIX@ +GNULIB_VFSCANF = @GNULIB_VFSCANF@ +GNULIB_VPRINTF = @GNULIB_VPRINTF@ +GNULIB_VPRINTF_POSIX = @GNULIB_VPRINTF_POSIX@ +GNULIB_VSCANF = @GNULIB_VSCANF@ +GNULIB_VSNPRINTF = @GNULIB_VSNPRINTF@ +GNULIB_VSPRINTF_POSIX = @GNULIB_VSPRINTF_POSIX@ +GNULIB_WARN_CFLAGS = @GNULIB_WARN_CFLAGS@ +GNULIB_WCPCPY = @GNULIB_WCPCPY@ +GNULIB_WCPNCPY = @GNULIB_WCPNCPY@ +GNULIB_WCRTOMB = @GNULIB_WCRTOMB@ +GNULIB_WCSCASECMP = @GNULIB_WCSCASECMP@ +GNULIB_WCSCAT = @GNULIB_WCSCAT@ +GNULIB_WCSCHR = @GNULIB_WCSCHR@ +GNULIB_WCSCMP = @GNULIB_WCSCMP@ +GNULIB_WCSCOLL = @GNULIB_WCSCOLL@ +GNULIB_WCSCPY = @GNULIB_WCSCPY@ +GNULIB_WCSCSPN = @GNULIB_WCSCSPN@ +GNULIB_WCSDUP = @GNULIB_WCSDUP@ +GNULIB_WCSLEN = @GNULIB_WCSLEN@ +GNULIB_WCSNCASECMP = @GNULIB_WCSNCASECMP@ +GNULIB_WCSNCAT = @GNULIB_WCSNCAT@ +GNULIB_WCSNCMP = @GNULIB_WCSNCMP@ +GNULIB_WCSNCPY = @GNULIB_WCSNCPY@ +GNULIB_WCSNLEN = @GNULIB_WCSNLEN@ +GNULIB_WCSNRTOMBS = @GNULIB_WCSNRTOMBS@ +GNULIB_WCSPBRK = @GNULIB_WCSPBRK@ +GNULIB_WCSRCHR = @GNULIB_WCSRCHR@ +GNULIB_WCSRTOMBS = @GNULIB_WCSRTOMBS@ +GNULIB_WCSSPN = @GNULIB_WCSSPN@ +GNULIB_WCSSTR = @GNULIB_WCSSTR@ +GNULIB_WCSTOK = @GNULIB_WCSTOK@ +GNULIB_WCSWIDTH = @GNULIB_WCSWIDTH@ +GNULIB_WCSXFRM = @GNULIB_WCSXFRM@ +GNULIB_WCTOB = @GNULIB_WCTOB@ +GNULIB_WCTOMB = @GNULIB_WCTOMB@ +GNULIB_WCTRANS = @GNULIB_WCTRANS@ +GNULIB_WCTYPE = @GNULIB_WCTYPE@ +GNULIB_WCWIDTH = @GNULIB_WCWIDTH@ +GNULIB_WMEMCHR = @GNULIB_WMEMCHR@ +GNULIB_WMEMCMP = @GNULIB_WMEMCMP@ +GNULIB_WMEMCPY = @GNULIB_WMEMCPY@ +GNULIB_WMEMMOVE = @GNULIB_WMEMMOVE@ +GNULIB_WMEMSET = @GNULIB_WMEMSET@ +GNULIB_WRITE = @GNULIB_WRITE@ +GNULIB__EXIT = @GNULIB__EXIT@ +GREP = @GREP@ +HAVE_ALPHASORT = @HAVE_ALPHASORT@ +HAVE_ATOLL = @HAVE_ATOLL@ +HAVE_BTOWC = @HAVE_BTOWC@ +HAVE_CANONICALIZE_FILE_NAME = @HAVE_CANONICALIZE_FILE_NAME@ +HAVE_CHOWN = @HAVE_CHOWN@ +HAVE_CLOSEDIR = @HAVE_CLOSEDIR@ +HAVE_DECL_DIRFD = @HAVE_DECL_DIRFD@ +HAVE_DECL_ENVIRON = @HAVE_DECL_ENVIRON@ +HAVE_DECL_FCHDIR = @HAVE_DECL_FCHDIR@ +HAVE_DECL_FDATASYNC = @HAVE_DECL_FDATASYNC@ +HAVE_DECL_FDOPENDIR = @HAVE_DECL_FDOPENDIR@ +HAVE_DECL_FPURGE = @HAVE_DECL_FPURGE@ +HAVE_DECL_FSEEKO = @HAVE_DECL_FSEEKO@ +HAVE_DECL_FTELLO = @HAVE_DECL_FTELLO@ +HAVE_DECL_GETDELIM = @HAVE_DECL_GETDELIM@ +HAVE_DECL_GETDOMAINNAME = @HAVE_DECL_GETDOMAINNAME@ +HAVE_DECL_GETLINE = @HAVE_DECL_GETLINE@ +HAVE_DECL_GETLOADAVG = @HAVE_DECL_GETLOADAVG@ +HAVE_DECL_GETLOGIN_R = @HAVE_DECL_GETLOGIN_R@ +HAVE_DECL_GETPAGESIZE = @HAVE_DECL_GETPAGESIZE@ +HAVE_DECL_GETUSERSHELL = @HAVE_DECL_GETUSERSHELL@ +HAVE_DECL_IMAXABS = @HAVE_DECL_IMAXABS@ +HAVE_DECL_IMAXDIV = @HAVE_DECL_IMAXDIV@ +HAVE_DECL_LOCALTIME_R = @HAVE_DECL_LOCALTIME_R@ +HAVE_DECL_MEMMEM = @HAVE_DECL_MEMMEM@ +HAVE_DECL_MEMRCHR = @HAVE_DECL_MEMRCHR@ +HAVE_DECL_OBSTACK_PRINTF = @HAVE_DECL_OBSTACK_PRINTF@ +HAVE_DECL_SETENV = @HAVE_DECL_SETENV@ +HAVE_DECL_SETHOSTNAME = @HAVE_DECL_SETHOSTNAME@ +HAVE_DECL_SNPRINTF = @HAVE_DECL_SNPRINTF@ +HAVE_DECL_STRDUP = @HAVE_DECL_STRDUP@ +HAVE_DECL_STRERROR_R = @HAVE_DECL_STRERROR_R@ +HAVE_DECL_STRNCASECMP = @HAVE_DECL_STRNCASECMP@ +HAVE_DECL_STRNDUP = @HAVE_DECL_STRNDUP@ +HAVE_DECL_STRNLEN = @HAVE_DECL_STRNLEN@ +HAVE_DECL_STRSIGNAL = @HAVE_DECL_STRSIGNAL@ +HAVE_DECL_STRTOIMAX = @HAVE_DECL_STRTOIMAX@ +HAVE_DECL_STRTOK_R = @HAVE_DECL_STRTOK_R@ +HAVE_DECL_STRTOUMAX = @HAVE_DECL_STRTOUMAX@ +HAVE_DECL_TTYNAME_R = @HAVE_DECL_TTYNAME_R@ +HAVE_DECL_UNSETENV = @HAVE_DECL_UNSETENV@ +HAVE_DECL_VSNPRINTF = @HAVE_DECL_VSNPRINTF@ +HAVE_DECL_WCTOB = @HAVE_DECL_WCTOB@ +HAVE_DECL_WCWIDTH = @HAVE_DECL_WCWIDTH@ +HAVE_DIRENT_H = @HAVE_DIRENT_H@ +HAVE_DPRINTF = @HAVE_DPRINTF@ +HAVE_DUP2 = @HAVE_DUP2@ +HAVE_DUP3 = @HAVE_DUP3@ +HAVE_DUPLOCALE = @HAVE_DUPLOCALE@ +HAVE_EUIDACCESS = @HAVE_EUIDACCESS@ +HAVE_FACCESSAT = @HAVE_FACCESSAT@ +HAVE_FCHDIR = @HAVE_FCHDIR@ +HAVE_FCHMODAT = @HAVE_FCHMODAT@ +HAVE_FCHOWNAT = @HAVE_FCHOWNAT@ +HAVE_FCNTL = @HAVE_FCNTL@ +HAVE_FDATASYNC = @HAVE_FDATASYNC@ +HAVE_FDOPENDIR = @HAVE_FDOPENDIR@ +HAVE_FEATURES_H = @HAVE_FEATURES_H@ +HAVE_FFS = @HAVE_FFS@ +HAVE_FFSL = @HAVE_FFSL@ +HAVE_FFSLL = @HAVE_FFSLL@ +HAVE_FSEEKO = @HAVE_FSEEKO@ +HAVE_FSTATAT = @HAVE_FSTATAT@ +HAVE_FSYNC = @HAVE_FSYNC@ +HAVE_FTELLO = @HAVE_FTELLO@ +HAVE_FTRUNCATE = @HAVE_FTRUNCATE@ +HAVE_FUTIMENS = @HAVE_FUTIMENS@ +HAVE_GETDTABLESIZE = @HAVE_GETDTABLESIZE@ +HAVE_GETGROUPS = @HAVE_GETGROUPS@ +HAVE_GETHOSTNAME = @HAVE_GETHOSTNAME@ +HAVE_GETLOGIN = @HAVE_GETLOGIN@ +HAVE_GETOPT_H = @HAVE_GETOPT_H@ +HAVE_GETPAGESIZE = @HAVE_GETPAGESIZE@ +HAVE_GETSUBOPT = @HAVE_GETSUBOPT@ +HAVE_GETTIMEOFDAY = @HAVE_GETTIMEOFDAY@ +HAVE_GRANTPT = @HAVE_GRANTPT@ +HAVE_GROUP_MEMBER = @HAVE_GROUP_MEMBER@ +HAVE_INTTYPES_H = @HAVE_INTTYPES_H@ +HAVE_ISWBLANK = @HAVE_ISWBLANK@ +HAVE_ISWCNTRL = @HAVE_ISWCNTRL@ +HAVE_LANGINFO_CODESET = @HAVE_LANGINFO_CODESET@ +HAVE_LANGINFO_ERA = @HAVE_LANGINFO_ERA@ +HAVE_LANGINFO_H = @HAVE_LANGINFO_H@ +HAVE_LANGINFO_T_FMT_AMPM = @HAVE_LANGINFO_T_FMT_AMPM@ +HAVE_LANGINFO_YESEXPR = @HAVE_LANGINFO_YESEXPR@ +HAVE_LCHMOD = @HAVE_LCHMOD@ +HAVE_LCHOWN = @HAVE_LCHOWN@ +HAVE_LINK = @HAVE_LINK@ +HAVE_LINKAT = @HAVE_LINKAT@ +HAVE_LONG_LONG_INT = @HAVE_LONG_LONG_INT@ +HAVE_LSTAT = @HAVE_LSTAT@ +HAVE_MAX_ALIGN_T = @HAVE_MAX_ALIGN_T@ +HAVE_MBRLEN = @HAVE_MBRLEN@ +HAVE_MBRTOWC = @HAVE_MBRTOWC@ +HAVE_MBSINIT = @HAVE_MBSINIT@ +HAVE_MBSLEN = @HAVE_MBSLEN@ +HAVE_MBSNRTOWCS = @HAVE_MBSNRTOWCS@ +HAVE_MBSRTOWCS = @HAVE_MBSRTOWCS@ +HAVE_MEMCHR = @HAVE_MEMCHR@ +HAVE_MEMPCPY = @HAVE_MEMPCPY@ +HAVE_MKDIRAT = @HAVE_MKDIRAT@ +HAVE_MKDTEMP = @HAVE_MKDTEMP@ +HAVE_MKFIFO = @HAVE_MKFIFO@ +HAVE_MKFIFOAT = @HAVE_MKFIFOAT@ +HAVE_MKNOD = @HAVE_MKNOD@ +HAVE_MKNODAT = @HAVE_MKNODAT@ +HAVE_MKOSTEMP = @HAVE_MKOSTEMP@ +HAVE_MKOSTEMPS = @HAVE_MKOSTEMPS@ +HAVE_MKSTEMP = @HAVE_MKSTEMP@ +HAVE_MKSTEMPS = @HAVE_MKSTEMPS@ +HAVE_MSVC_INVALID_PARAMETER_HANDLER = @HAVE_MSVC_INVALID_PARAMETER_HANDLER@ +HAVE_NANOSLEEP = @HAVE_NANOSLEEP@ +HAVE_NL_LANGINFO = @HAVE_NL_LANGINFO@ +HAVE_OPENAT = @HAVE_OPENAT@ +HAVE_OPENDIR = @HAVE_OPENDIR@ +HAVE_OS_H = @HAVE_OS_H@ +HAVE_PCLOSE = @HAVE_PCLOSE@ +HAVE_PIPE = @HAVE_PIPE@ +HAVE_PIPE2 = @HAVE_PIPE2@ +HAVE_POPEN = @HAVE_POPEN@ +HAVE_POSIX_OPENPT = @HAVE_POSIX_OPENPT@ +HAVE_POSIX_SIGNALBLOCKING = @HAVE_POSIX_SIGNALBLOCKING@ +HAVE_PREAD = @HAVE_PREAD@ +HAVE_PTHREAD_SIGMASK = @HAVE_PTHREAD_SIGMASK@ +HAVE_PTSNAME = @HAVE_PTSNAME@ +HAVE_PTSNAME_R = @HAVE_PTSNAME_R@ +HAVE_PWRITE = @HAVE_PWRITE@ +HAVE_RAISE = @HAVE_RAISE@ +HAVE_RANDOM = @HAVE_RANDOM@ +HAVE_RANDOM_H = @HAVE_RANDOM_H@ +HAVE_RANDOM_R = @HAVE_RANDOM_R@ +HAVE_RAWMEMCHR = @HAVE_RAWMEMCHR@ +HAVE_READDIR = @HAVE_READDIR@ +HAVE_READLINK = @HAVE_READLINK@ +HAVE_READLINKAT = @HAVE_READLINKAT@ +HAVE_REALPATH = @HAVE_REALPATH@ +HAVE_RENAMEAT = @HAVE_RENAMEAT@ +HAVE_REWINDDIR = @HAVE_REWINDDIR@ +HAVE_RPMATCH = @HAVE_RPMATCH@ +HAVE_SCANDIR = @HAVE_SCANDIR@ +HAVE_SECURE_GETENV = @HAVE_SECURE_GETENV@ +HAVE_SETENV = @HAVE_SETENV@ +HAVE_SETHOSTNAME = @HAVE_SETHOSTNAME@ +HAVE_SIGACTION = @HAVE_SIGACTION@ +HAVE_SIGHANDLER_T = @HAVE_SIGHANDLER_T@ +HAVE_SIGINFO_T = @HAVE_SIGINFO_T@ +HAVE_SIGNED_SIG_ATOMIC_T = @HAVE_SIGNED_SIG_ATOMIC_T@ +HAVE_SIGNED_WCHAR_T = @HAVE_SIGNED_WCHAR_T@ +HAVE_SIGNED_WINT_T = @HAVE_SIGNED_WINT_T@ +HAVE_SIGSET_T = @HAVE_SIGSET_T@ +HAVE_SLEEP = @HAVE_SLEEP@ +HAVE_STDINT_H = @HAVE_STDINT_H@ +HAVE_STPCPY = @HAVE_STPCPY@ +HAVE_STPNCPY = @HAVE_STPNCPY@ +HAVE_STRCASECMP = @HAVE_STRCASECMP@ +HAVE_STRCASESTR = @HAVE_STRCASESTR@ +HAVE_STRCHRNUL = @HAVE_STRCHRNUL@ +HAVE_STRINGS_H = @HAVE_STRINGS_H@ +HAVE_STRPBRK = @HAVE_STRPBRK@ +HAVE_STRPTIME = @HAVE_STRPTIME@ +HAVE_STRSEP = @HAVE_STRSEP@ +HAVE_STRTOD = @HAVE_STRTOD@ +HAVE_STRTOLL = @HAVE_STRTOLL@ +HAVE_STRTOULL = @HAVE_STRTOULL@ +HAVE_STRUCT_RANDOM_DATA = @HAVE_STRUCT_RANDOM_DATA@ +HAVE_STRUCT_SIGACTION_SA_SIGACTION = @HAVE_STRUCT_SIGACTION_SA_SIGACTION@ +HAVE_STRUCT_TIMEVAL = @HAVE_STRUCT_TIMEVAL@ +HAVE_STRVERSCMP = @HAVE_STRVERSCMP@ +HAVE_SYMLINK = @HAVE_SYMLINK@ +HAVE_SYMLINKAT = @HAVE_SYMLINKAT@ +HAVE_SYSEXITS_H = @HAVE_SYSEXITS_H@ +HAVE_SYS_BITYPES_H = @HAVE_SYS_BITYPES_H@ +HAVE_SYS_INTTYPES_H = @HAVE_SYS_INTTYPES_H@ +HAVE_SYS_LOADAVG_H = @HAVE_SYS_LOADAVG_H@ +HAVE_SYS_PARAM_H = @HAVE_SYS_PARAM_H@ +HAVE_SYS_TIME_H = @HAVE_SYS_TIME_H@ +HAVE_SYS_TYPES_H = @HAVE_SYS_TYPES_H@ +HAVE_TIMEGM = @HAVE_TIMEGM@ +HAVE_TIMEZONE_T = @HAVE_TIMEZONE_T@ +HAVE_TYPE_VOLATILE_SIG_ATOMIC_T = @HAVE_TYPE_VOLATILE_SIG_ATOMIC_T@ +HAVE_UNISTD_H = @HAVE_UNISTD_H@ +HAVE_UNLINKAT = @HAVE_UNLINKAT@ +HAVE_UNLOCKPT = @HAVE_UNLOCKPT@ +HAVE_UNSIGNED_LONG_LONG_INT = @HAVE_UNSIGNED_LONG_LONG_INT@ +HAVE_USLEEP = @HAVE_USLEEP@ +HAVE_UTIMENSAT = @HAVE_UTIMENSAT@ +HAVE_VASPRINTF = @HAVE_VASPRINTF@ +HAVE_VDPRINTF = @HAVE_VDPRINTF@ +HAVE_WCHAR_H = @HAVE_WCHAR_H@ +HAVE_WCHAR_T = @HAVE_WCHAR_T@ +HAVE_WCPCPY = @HAVE_WCPCPY@ +HAVE_WCPNCPY = @HAVE_WCPNCPY@ +HAVE_WCRTOMB = @HAVE_WCRTOMB@ +HAVE_WCSCASECMP = @HAVE_WCSCASECMP@ +HAVE_WCSCAT = @HAVE_WCSCAT@ +HAVE_WCSCHR = @HAVE_WCSCHR@ +HAVE_WCSCMP = @HAVE_WCSCMP@ +HAVE_WCSCOLL = @HAVE_WCSCOLL@ +HAVE_WCSCPY = @HAVE_WCSCPY@ +HAVE_WCSCSPN = @HAVE_WCSCSPN@ +HAVE_WCSDUP = @HAVE_WCSDUP@ +HAVE_WCSLEN = @HAVE_WCSLEN@ +HAVE_WCSNCASECMP = @HAVE_WCSNCASECMP@ +HAVE_WCSNCAT = @HAVE_WCSNCAT@ +HAVE_WCSNCMP = @HAVE_WCSNCMP@ +HAVE_WCSNCPY = @HAVE_WCSNCPY@ +HAVE_WCSNLEN = @HAVE_WCSNLEN@ +HAVE_WCSNRTOMBS = @HAVE_WCSNRTOMBS@ +HAVE_WCSPBRK = @HAVE_WCSPBRK@ +HAVE_WCSRCHR = @HAVE_WCSRCHR@ +HAVE_WCSRTOMBS = @HAVE_WCSRTOMBS@ +HAVE_WCSSPN = @HAVE_WCSSPN@ +HAVE_WCSSTR = @HAVE_WCSSTR@ +HAVE_WCSTOK = @HAVE_WCSTOK@ +HAVE_WCSWIDTH = @HAVE_WCSWIDTH@ +HAVE_WCSXFRM = @HAVE_WCSXFRM@ +HAVE_WCTRANS_T = @HAVE_WCTRANS_T@ +HAVE_WCTYPE_H = @HAVE_WCTYPE_H@ +HAVE_WCTYPE_T = @HAVE_WCTYPE_T@ +HAVE_WINSOCK2_H = @HAVE_WINSOCK2_H@ +HAVE_WINT_T = @HAVE_WINT_T@ +HAVE_WMEMCHR = @HAVE_WMEMCHR@ +HAVE_WMEMCMP = @HAVE_WMEMCMP@ +HAVE_WMEMCPY = @HAVE_WMEMCPY@ +HAVE_WMEMMOVE = @HAVE_WMEMMOVE@ +HAVE_WMEMSET = @HAVE_WMEMSET@ +HAVE_XLOCALE_H = @HAVE_XLOCALE_H@ +HAVE__BOOL = @HAVE__BOOL@ +HAVE__EXIT = @HAVE__EXIT@ +INCLUDE_NEXT = @INCLUDE_NEXT@ +INCLUDE_NEXT_AS_FIRST_DIRECTIVE = @INCLUDE_NEXT_AS_FIRST_DIRECTIVE@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +INT32_MAX_LT_INTMAX_MAX = @INT32_MAX_LT_INTMAX_MAX@ +INT64_MAX_EQ_LONG_MAX = @INT64_MAX_EQ_LONG_MAX@ +INTLLIBS = @INTLLIBS@ +INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@ +LDFLAGS = @LDFLAGS@ +LIBGNU_LIBDEPS = @LIBGNU_LIBDEPS@ +LIBGNU_LTLIBDEPS = @LIBGNU_LTLIBDEPS@ +LIBICONV = @LIBICONV@ +LIBINTL = @LIBINTL@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBUNISTRING_UNITYPES_H = @LIBUNISTRING_UNITYPES_H@ +LIBUNISTRING_UNIWIDTH_H = @LIBUNISTRING_UNIWIDTH_H@ +LIB_ACL = @LIB_ACL@ +LIB_CLOCK_GETTIME = @LIB_CLOCK_GETTIME@ +LIB_EACCESS = @LIB_EACCESS@ +LIB_HAS_ACL = @LIB_HAS_ACL@ +LIB_SELINUX = @LIB_SELINUX@ +LIB_SETSOCKOPT = @LIB_SETSOCKOPT@ +LOCALCHARSET_TESTS_ENVIRONMENT = @LOCALCHARSET_TESTS_ENVIRONMENT@ +LOCALE_FR = @LOCALE_FR@ +LOCALE_FR_UTF8 = @LOCALE_FR_UTF8@ +LOCALE_JA = @LOCALE_JA@ +LOCALE_ZH_CN = @LOCALE_ZH_CN@ +LTLIBICONV = @LTLIBICONV@ +LTLIBINTL = @LTLIBINTL@ +LTLIBOBJS = @LTLIBOBJS@ +MAKEINFO = @MAKEINFO@ +MKDIR_P = @MKDIR_P@ +MSGFMT = @MSGFMT@ +MSGFMT_015 = @MSGFMT_015@ +MSGMERGE = @MSGMERGE@ +NEXT_AS_FIRST_DIRECTIVE_DIRENT_H = @NEXT_AS_FIRST_DIRECTIVE_DIRENT_H@ +NEXT_AS_FIRST_DIRECTIVE_ERRNO_H = @NEXT_AS_FIRST_DIRECTIVE_ERRNO_H@ +NEXT_AS_FIRST_DIRECTIVE_FCNTL_H = @NEXT_AS_FIRST_DIRECTIVE_FCNTL_H@ +NEXT_AS_FIRST_DIRECTIVE_FLOAT_H = @NEXT_AS_FIRST_DIRECTIVE_FLOAT_H@ +NEXT_AS_FIRST_DIRECTIVE_GETOPT_H = @NEXT_AS_FIRST_DIRECTIVE_GETOPT_H@ +NEXT_AS_FIRST_DIRECTIVE_INTTYPES_H = @NEXT_AS_FIRST_DIRECTIVE_INTTYPES_H@ +NEXT_AS_FIRST_DIRECTIVE_LANGINFO_H = @NEXT_AS_FIRST_DIRECTIVE_LANGINFO_H@ +NEXT_AS_FIRST_DIRECTIVE_LOCALE_H = @NEXT_AS_FIRST_DIRECTIVE_LOCALE_H@ +NEXT_AS_FIRST_DIRECTIVE_SELINUX_SELINUX_H = @NEXT_AS_FIRST_DIRECTIVE_SELINUX_SELINUX_H@ +NEXT_AS_FIRST_DIRECTIVE_SIGNAL_H = @NEXT_AS_FIRST_DIRECTIVE_SIGNAL_H@ +NEXT_AS_FIRST_DIRECTIVE_STDARG_H = @NEXT_AS_FIRST_DIRECTIVE_STDARG_H@ +NEXT_AS_FIRST_DIRECTIVE_STDDEF_H = @NEXT_AS_FIRST_DIRECTIVE_STDDEF_H@ +NEXT_AS_FIRST_DIRECTIVE_STDINT_H = @NEXT_AS_FIRST_DIRECTIVE_STDINT_H@ +NEXT_AS_FIRST_DIRECTIVE_STDIO_H = @NEXT_AS_FIRST_DIRECTIVE_STDIO_H@ +NEXT_AS_FIRST_DIRECTIVE_STDLIB_H = @NEXT_AS_FIRST_DIRECTIVE_STDLIB_H@ +NEXT_AS_FIRST_DIRECTIVE_STRINGS_H = @NEXT_AS_FIRST_DIRECTIVE_STRINGS_H@ +NEXT_AS_FIRST_DIRECTIVE_STRING_H = @NEXT_AS_FIRST_DIRECTIVE_STRING_H@ +NEXT_AS_FIRST_DIRECTIVE_SYSEXITS_H = @NEXT_AS_FIRST_DIRECTIVE_SYSEXITS_H@ +NEXT_AS_FIRST_DIRECTIVE_SYS_STAT_H = @NEXT_AS_FIRST_DIRECTIVE_SYS_STAT_H@ +NEXT_AS_FIRST_DIRECTIVE_SYS_TIME_H = @NEXT_AS_FIRST_DIRECTIVE_SYS_TIME_H@ +NEXT_AS_FIRST_DIRECTIVE_SYS_TYPES_H = @NEXT_AS_FIRST_DIRECTIVE_SYS_TYPES_H@ +NEXT_AS_FIRST_DIRECTIVE_TIME_H = @NEXT_AS_FIRST_DIRECTIVE_TIME_H@ +NEXT_AS_FIRST_DIRECTIVE_UNISTD_H = @NEXT_AS_FIRST_DIRECTIVE_UNISTD_H@ +NEXT_AS_FIRST_DIRECTIVE_WCHAR_H = @NEXT_AS_FIRST_DIRECTIVE_WCHAR_H@ +NEXT_AS_FIRST_DIRECTIVE_WCTYPE_H = @NEXT_AS_FIRST_DIRECTIVE_WCTYPE_H@ +NEXT_DIRENT_H = @NEXT_DIRENT_H@ +NEXT_ERRNO_H = @NEXT_ERRNO_H@ +NEXT_FCNTL_H = @NEXT_FCNTL_H@ +NEXT_FLOAT_H = @NEXT_FLOAT_H@ +NEXT_GETOPT_H = @NEXT_GETOPT_H@ +NEXT_INTTYPES_H = @NEXT_INTTYPES_H@ +NEXT_LANGINFO_H = @NEXT_LANGINFO_H@ +NEXT_LOCALE_H = @NEXT_LOCALE_H@ +NEXT_SELINUX_SELINUX_H = @NEXT_SELINUX_SELINUX_H@ +NEXT_SIGNAL_H = @NEXT_SIGNAL_H@ +NEXT_STDARG_H = @NEXT_STDARG_H@ +NEXT_STDDEF_H = @NEXT_STDDEF_H@ +NEXT_STDINT_H = @NEXT_STDINT_H@ +NEXT_STDIO_H = @NEXT_STDIO_H@ +NEXT_STDLIB_H = @NEXT_STDLIB_H@ +NEXT_STRINGS_H = @NEXT_STRINGS_H@ +NEXT_STRING_H = @NEXT_STRING_H@ +NEXT_SYSEXITS_H = @NEXT_SYSEXITS_H@ +NEXT_SYS_STAT_H = @NEXT_SYS_STAT_H@ +NEXT_SYS_TIME_H = @NEXT_SYS_TIME_H@ +NEXT_SYS_TYPES_H = @NEXT_SYS_TYPES_H@ +NEXT_TIME_H = @NEXT_TIME_H@ +NEXT_UNISTD_H = @NEXT_UNISTD_H@ +NEXT_WCHAR_H = @NEXT_WCHAR_H@ +NEXT_WCTYPE_H = @NEXT_WCTYPE_H@ +OBJEXT = @OBJEXT@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +POSUB = @POSUB@ +PRAGMA_COLUMNS = @PRAGMA_COLUMNS@ +PRAGMA_SYSTEM_HEADER = @PRAGMA_SYSTEM_HEADER@ +PRIPTR_PREFIX = @PRIPTR_PREFIX@ +PRI_MACROS_BROKEN = @PRI_MACROS_BROKEN@ +PTHREAD_H_DEFINES_STRUCT_TIMESPEC = @PTHREAD_H_DEFINES_STRUCT_TIMESPEC@ +PTRDIFF_T_SUFFIX = @PTRDIFF_T_SUFFIX@ +PU_RMT_PROG = @PU_RMT_PROG@ +RANLIB = @RANLIB@ +REPLACE_BTOWC = @REPLACE_BTOWC@ +REPLACE_CALLOC = @REPLACE_CALLOC@ +REPLACE_CANONICALIZE_FILE_NAME = @REPLACE_CANONICALIZE_FILE_NAME@ +REPLACE_CHOWN = @REPLACE_CHOWN@ +REPLACE_CLOSE = @REPLACE_CLOSE@ +REPLACE_CLOSEDIR = @REPLACE_CLOSEDIR@ +REPLACE_DIRFD = @REPLACE_DIRFD@ +REPLACE_DPRINTF = @REPLACE_DPRINTF@ +REPLACE_DUP = @REPLACE_DUP@ +REPLACE_DUP2 = @REPLACE_DUP2@ +REPLACE_DUPLOCALE = @REPLACE_DUPLOCALE@ +REPLACE_FCHOWNAT = @REPLACE_FCHOWNAT@ +REPLACE_FCLOSE = @REPLACE_FCLOSE@ +REPLACE_FCNTL = @REPLACE_FCNTL@ +REPLACE_FDOPEN = @REPLACE_FDOPEN@ +REPLACE_FDOPENDIR = @REPLACE_FDOPENDIR@ +REPLACE_FFLUSH = @REPLACE_FFLUSH@ +REPLACE_FOPEN = @REPLACE_FOPEN@ +REPLACE_FPRINTF = @REPLACE_FPRINTF@ +REPLACE_FPURGE = @REPLACE_FPURGE@ +REPLACE_FREOPEN = @REPLACE_FREOPEN@ +REPLACE_FSEEK = @REPLACE_FSEEK@ +REPLACE_FSEEKO = @REPLACE_FSEEKO@ +REPLACE_FSTAT = @REPLACE_FSTAT@ +REPLACE_FSTATAT = @REPLACE_FSTATAT@ +REPLACE_FTELL = @REPLACE_FTELL@ +REPLACE_FTELLO = @REPLACE_FTELLO@ +REPLACE_FTRUNCATE = @REPLACE_FTRUNCATE@ +REPLACE_FUTIMENS = @REPLACE_FUTIMENS@ +REPLACE_GETCWD = @REPLACE_GETCWD@ +REPLACE_GETDELIM = @REPLACE_GETDELIM@ +REPLACE_GETDOMAINNAME = @REPLACE_GETDOMAINNAME@ +REPLACE_GETDTABLESIZE = @REPLACE_GETDTABLESIZE@ +REPLACE_GETGROUPS = @REPLACE_GETGROUPS@ +REPLACE_GETLINE = @REPLACE_GETLINE@ +REPLACE_GETLOGIN_R = @REPLACE_GETLOGIN_R@ +REPLACE_GETPAGESIZE = @REPLACE_GETPAGESIZE@ +REPLACE_GETTIMEOFDAY = @REPLACE_GETTIMEOFDAY@ +REPLACE_GMTIME = @REPLACE_GMTIME@ +REPLACE_ISATTY = @REPLACE_ISATTY@ +REPLACE_ISWBLANK = @REPLACE_ISWBLANK@ +REPLACE_ISWCNTRL = @REPLACE_ISWCNTRL@ +REPLACE_ITOLD = @REPLACE_ITOLD@ +REPLACE_LCHOWN = @REPLACE_LCHOWN@ +REPLACE_LINK = @REPLACE_LINK@ +REPLACE_LINKAT = @REPLACE_LINKAT@ +REPLACE_LOCALECONV = @REPLACE_LOCALECONV@ +REPLACE_LOCALTIME = @REPLACE_LOCALTIME@ +REPLACE_LOCALTIME_R = @REPLACE_LOCALTIME_R@ +REPLACE_LSEEK = @REPLACE_LSEEK@ +REPLACE_LSTAT = @REPLACE_LSTAT@ +REPLACE_MALLOC = @REPLACE_MALLOC@ +REPLACE_MBRLEN = @REPLACE_MBRLEN@ +REPLACE_MBRTOWC = @REPLACE_MBRTOWC@ +REPLACE_MBSINIT = @REPLACE_MBSINIT@ +REPLACE_MBSNRTOWCS = @REPLACE_MBSNRTOWCS@ +REPLACE_MBSRTOWCS = @REPLACE_MBSRTOWCS@ +REPLACE_MBSTATE_T = @REPLACE_MBSTATE_T@ +REPLACE_MBTOWC = @REPLACE_MBTOWC@ +REPLACE_MEMCHR = @REPLACE_MEMCHR@ +REPLACE_MEMMEM = @REPLACE_MEMMEM@ +REPLACE_MKDIR = @REPLACE_MKDIR@ +REPLACE_MKFIFO = @REPLACE_MKFIFO@ +REPLACE_MKNOD = @REPLACE_MKNOD@ +REPLACE_MKSTEMP = @REPLACE_MKSTEMP@ +REPLACE_MKTIME = @REPLACE_MKTIME@ +REPLACE_NANOSLEEP = @REPLACE_NANOSLEEP@ +REPLACE_NL_LANGINFO = @REPLACE_NL_LANGINFO@ +REPLACE_NULL = @REPLACE_NULL@ +REPLACE_OBSTACK_PRINTF = @REPLACE_OBSTACK_PRINTF@ +REPLACE_OPEN = @REPLACE_OPEN@ +REPLACE_OPENAT = @REPLACE_OPENAT@ +REPLACE_OPENDIR = @REPLACE_OPENDIR@ +REPLACE_PERROR = @REPLACE_PERROR@ +REPLACE_POPEN = @REPLACE_POPEN@ +REPLACE_PREAD = @REPLACE_PREAD@ +REPLACE_PRINTF = @REPLACE_PRINTF@ +REPLACE_PTHREAD_SIGMASK = @REPLACE_PTHREAD_SIGMASK@ +REPLACE_PTSNAME = @REPLACE_PTSNAME@ +REPLACE_PTSNAME_R = @REPLACE_PTSNAME_R@ +REPLACE_PUTENV = @REPLACE_PUTENV@ +REPLACE_PWRITE = @REPLACE_PWRITE@ +REPLACE_QSORT_R = @REPLACE_QSORT_R@ +REPLACE_RAISE = @REPLACE_RAISE@ +REPLACE_RANDOM_R = @REPLACE_RANDOM_R@ +REPLACE_READ = @REPLACE_READ@ +REPLACE_READLINK = @REPLACE_READLINK@ +REPLACE_READLINKAT = @REPLACE_READLINKAT@ +REPLACE_REALLOC = @REPLACE_REALLOC@ +REPLACE_REALPATH = @REPLACE_REALPATH@ +REPLACE_REMOVE = @REPLACE_REMOVE@ +REPLACE_RENAME = @REPLACE_RENAME@ +REPLACE_RENAMEAT = @REPLACE_RENAMEAT@ +REPLACE_RMDIR = @REPLACE_RMDIR@ +REPLACE_SETENV = @REPLACE_SETENV@ +REPLACE_SETLOCALE = @REPLACE_SETLOCALE@ +REPLACE_SLEEP = @REPLACE_SLEEP@ +REPLACE_SNPRINTF = @REPLACE_SNPRINTF@ +REPLACE_SPRINTF = @REPLACE_SPRINTF@ +REPLACE_STAT = @REPLACE_STAT@ +REPLACE_STDIO_READ_FUNCS = @REPLACE_STDIO_READ_FUNCS@ +REPLACE_STDIO_WRITE_FUNCS = @REPLACE_STDIO_WRITE_FUNCS@ +REPLACE_STPNCPY = @REPLACE_STPNCPY@ +REPLACE_STRCASESTR = @REPLACE_STRCASESTR@ +REPLACE_STRCHRNUL = @REPLACE_STRCHRNUL@ +REPLACE_STRDUP = @REPLACE_STRDUP@ +REPLACE_STRERROR = @REPLACE_STRERROR@ +REPLACE_STRERROR_R = @REPLACE_STRERROR_R@ +REPLACE_STRNCAT = @REPLACE_STRNCAT@ +REPLACE_STRNDUP = @REPLACE_STRNDUP@ +REPLACE_STRNLEN = @REPLACE_STRNLEN@ +REPLACE_STRSIGNAL = @REPLACE_STRSIGNAL@ +REPLACE_STRSTR = @REPLACE_STRSTR@ +REPLACE_STRTOD = @REPLACE_STRTOD@ +REPLACE_STRTOIMAX = @REPLACE_STRTOIMAX@ +REPLACE_STRTOK_R = @REPLACE_STRTOK_R@ +REPLACE_STRTOUMAX = @REPLACE_STRTOUMAX@ +REPLACE_STRUCT_LCONV = @REPLACE_STRUCT_LCONV@ +REPLACE_STRUCT_TIMEVAL = @REPLACE_STRUCT_TIMEVAL@ +REPLACE_SYMLINK = @REPLACE_SYMLINK@ +REPLACE_SYMLINKAT = @REPLACE_SYMLINKAT@ +REPLACE_TIMEGM = @REPLACE_TIMEGM@ +REPLACE_TMPFILE = @REPLACE_TMPFILE@ +REPLACE_TOWLOWER = @REPLACE_TOWLOWER@ +REPLACE_TTYNAME_R = @REPLACE_TTYNAME_R@ +REPLACE_UNLINK = @REPLACE_UNLINK@ +REPLACE_UNLINKAT = @REPLACE_UNLINKAT@ +REPLACE_UNSETENV = @REPLACE_UNSETENV@ +REPLACE_USLEEP = @REPLACE_USLEEP@ +REPLACE_UTIMENSAT = @REPLACE_UTIMENSAT@ +REPLACE_VASPRINTF = @REPLACE_VASPRINTF@ +REPLACE_VDPRINTF = @REPLACE_VDPRINTF@ +REPLACE_VFPRINTF = @REPLACE_VFPRINTF@ +REPLACE_VPRINTF = @REPLACE_VPRINTF@ +REPLACE_VSNPRINTF = @REPLACE_VSNPRINTF@ +REPLACE_VSPRINTF = @REPLACE_VSPRINTF@ +REPLACE_WCRTOMB = @REPLACE_WCRTOMB@ +REPLACE_WCSNRTOMBS = @REPLACE_WCSNRTOMBS@ +REPLACE_WCSRTOMBS = @REPLACE_WCSRTOMBS@ +REPLACE_WCSWIDTH = @REPLACE_WCSWIDTH@ +REPLACE_WCTOB = @REPLACE_WCTOB@ +REPLACE_WCTOMB = @REPLACE_WCTOMB@ +REPLACE_WCWIDTH = @REPLACE_WCWIDTH@ +REPLACE_WRITE = @REPLACE_WRITE@ +RSH = @RSH@ +SED = @SED@ +SELINUX_CONTEXT_H = @SELINUX_CONTEXT_H@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +SIG_ATOMIC_T_SUFFIX = @SIG_ATOMIC_T_SUFFIX@ +SIZE_T_SUFFIX = @SIZE_T_SUFFIX@ +STDALIGN_H = @STDALIGN_H@ +STDARG_H = @STDARG_H@ +STDBOOL_H = @STDBOOL_H@ +STDDEF_H = @STDDEF_H@ +STDINT_H = @STDINT_H@ +STRIP = @STRIP@ +SYSEXITS_H = @SYSEXITS_H@ +SYS_TIME_H_DEFINES_STRUCT_TIMESPEC = @SYS_TIME_H_DEFINES_STRUCT_TIMESPEC@ +TIME_H_DEFINES_STRUCT_TIMESPEC = @TIME_H_DEFINES_STRUCT_TIMESPEC@ +UINT32_MAX_LT_UINTMAX_MAX = @UINT32_MAX_LT_UINTMAX_MAX@ +UINT64_MAX_EQ_ULONG_MAX = @UINT64_MAX_EQ_ULONG_MAX@ +UNDEFINE_STRTOK_R = @UNDEFINE_STRTOK_R@ +UNISTD_H_DEFINES_STRUCT_TIMESPEC = @UNISTD_H_DEFINES_STRUCT_TIMESPEC@ +UNISTD_H_HAVE_WINSOCK2_H = @UNISTD_H_HAVE_WINSOCK2_H@ +UNISTD_H_HAVE_WINSOCK2_H_AND_USE_SOCKETS = @UNISTD_H_HAVE_WINSOCK2_H_AND_USE_SOCKETS@ +USE_ACL = @USE_ACL@ +USE_NLS = @USE_NLS@ +VERSION = @VERSION@ +WARN_CFLAGS = @WARN_CFLAGS@ +WCHAR_T_SUFFIX = @WCHAR_T_SUFFIX@ +WERROR_CFLAGS = @WERROR_CFLAGS@ +WINDOWS_64_BIT_OFF_T = @WINDOWS_64_BIT_OFF_T@ +WINDOWS_64_BIT_ST_SIZE = @WINDOWS_64_BIT_ST_SIZE@ +WINT_T_SUFFIX = @WINT_T_SUFFIX@ +XGETTEXT = @XGETTEXT@ +XGETTEXT_015 = @XGETTEXT_015@ +XGETTEXT_EXTRA_OPTIONS = @XGETTEXT_EXTRA_OPTIONS@ +YACC = @YACC@ +YFLAGS = @YFLAGS@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +gl_LIBOBJS = @gl_LIBOBJS@ +gl_LTLIBOBJS = @gl_LTLIBOBJS@ +gltests_LIBOBJS = @gltests_LIBOBJS@ +gltests_LTLIBOBJS = @gltests_LTLIBOBJS@ +gltests_WITNESS = @gltests_WITNESS@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +lispdir = @lispdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +runstatedir = @runstatedir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +noinst_LIBRARIES = libtar.a +BUILT_SOURCES = rmt-command.h $(am__append_1) +CLEANFILES = rmt-command.h rmt-command.h-t +AM_CPPFLAGS = -I$(top_srcdir)/gnu -I../ -I../gnu +AM_CFLAGS = $(GNULIB_WARN_CFLAGS) $(WERROR_CFLAGS) +noinst_HEADERS = \ + paxlib.h\ + rmt.h\ + stdopen.h\ + system.h\ + system-ioctl.h\ + wordsplit.h\ + xattr-at.h + +libtar_a_SOURCES = \ + paxerror.c paxexit-status.c paxlib.h paxnames.c \ + rtapelib.c \ + rmt.h \ + stdopen.c stdopen.h \ + system.h system-ioctl.h \ + wordsplit.c\ + xattr-at.c + +MOSTLYCLEANFILES = attr/xattr.h +EXTRA_DIST = attr-xattr.in.h +all: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) all-am + +.SUFFIXES: +.SUFFIXES: .c .o .obj +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnits lib/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnits lib/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +clean-noinstLIBRARIES: + -test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES) + +libtar.a: $(libtar_a_OBJECTS) $(libtar_a_DEPENDENCIES) $(EXTRA_libtar_a_DEPENDENCIES) + $(AM_V_at)-rm -f libtar.a + $(AM_V_AR)$(libtar_a_AR) libtar.a $(libtar_a_OBJECTS) $(libtar_a_LIBADD) + $(AM_V_at)$(RANLIB) libtar.a + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/paxerror.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/paxexit-status.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/paxnames.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rtapelib.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stdopen.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/wordsplit.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xattr-at.Po@am__quote@ + +.c.o: +@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< + +.c.obj: +@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-am +TAGS: tags + +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + set x; \ + here=`pwd`; \ + $(am__define_uniq_tagged_files); \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: ctags-am + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" +cscopelist: cscopelist-am + +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) check-am +all-am: Makefile $(LIBRARIES) $(HEADERS) +installdirs: +install: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + -test -z "$(MOSTLYCLEANFILES)" || rm -f $(MOSTLYCLEANFILES) + +clean-generic: + -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." + -test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES) +clean: clean-am + +clean-am: clean-generic clean-noinstLIBRARIES mostlyclean-am + +distclean: distclean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: + +.MAKE: all check install install-am install-strip + +.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \ + clean-noinstLIBRARIES cscopelist-am ctags ctags-am distclean \ + distclean-compile distclean-generic distclean-tags distdir dvi \ + dvi-am html html-am info info-am install install-am \ + install-data install-data-am install-dvi install-dvi-am \ + install-exec install-exec-am install-html install-html-am \ + install-info install-info-am install-man install-pdf \ + install-pdf-am install-ps install-ps-am install-strip \ + installcheck installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-compile \ + mostlyclean-generic pdf pdf-am ps ps-am tags tags-am uninstall \ + uninstall-am + +rmt-command.h : Makefile + $(AM_V_GEN)rm -f $@-t $@ + $(AM_V_at)echo "#ifndef DEFAULT_RMT_COMMAND" >> $@-t + $(AM_V_at)echo "# define DEFAULT_RMT_COMMAND \"$(DEFAULT_RMT_DIR)/`echo rmt | sed '$(transform)'`$(EXEEXT)\"" >> $@-t + $(AM_V_at)echo "#endif" >> $@-t + $(AM_V_at)mv $@-t $@ +@TAR_COND_XATTR_H_FALSE@attr/xattr.h: attr-xattr.in.h $(top_builddir)/config.status +@TAR_COND_XATTR_H_FALSE@ $(AM_V_at)$(MKDIR_P) attr +@TAR_COND_XATTR_H_FALSE@ $(AM_V_GEN)rm -f $@-t $@ && \ +@TAR_COND_XATTR_H_FALSE@ cp $(srcdir)/attr-xattr.in.h attr/xattr.h + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/lib/attr-xattr.in.h b/lib/attr-xattr.in.h new file mode 100644 index 0000000..679000b --- /dev/null +++ b/lib/attr-xattr.in.h @@ -0,0 +1,60 @@ +/* Replacement <attr/xattr.h> for platforms that lack it. + Copyright 2012-2014, 2016 Free Software Foundation, Inc. + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +#ifndef TAR_ATTR_XATTR_H +#define TAR_ATTR_XATTR_H +#include <errno.h> +#ifndef ENOATTR +# define ENOATTR ENODATA /* No such attribute */ +#endif + +/* setting */ +static inline int setxattr (const char *path, const char *name, const void + *value, size_t size, int flags) +{ errno = ENOTSUP; return -1; } + +static inline int lsetxattr (const char *path, const char *name, const void + *value, size_t size, int flags) +{ errno = ENOTSUP; return -1; } + +static inline int fsetxattr (int filedes, const char *name, const void *value, + size_t size, int flags) +{ errno = ENOTSUP; return -1; } + + +/* getting */ +static inline ssize_t getxattr (const char *path, const char *name, void *value, + size_t size) +{ errno = ENOTSUP; return -1; } +static inline ssize_t lgetxattr (const char *path, const char *name, void + *value, size_t size) +{ errno = ENOTSUP; return -1; } +static inline ssize_t fgetxattr (int filedes, const char *name, void *value, + size_t size) +{ errno = ENOTSUP; return -1; } + + +/* listing */ +static inline ssize_t listxattr (const char *path, char *list, size_t size) +{ errno = ENOTSUP; return -1; } + +static inline ssize_t llistxattr (const char *path, char *list, size_t size) +{ errno = ENOTSUP; return -1; } + +static inline ssize_t flistxattr (int filedes, char *list, size_t size) +{ errno = ENOTSUP; return -1; } + +#endif diff --git a/lib/paxerror.c b/lib/paxerror.c new file mode 100644 index 0000000..134cef3 --- /dev/null +++ b/lib/paxerror.c @@ -0,0 +1,361 @@ +/* Miscellaneous error functions + + Copyright (C) 2005, 2007 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by the + Free Software Foundation; either version 3, or (at your option) any later + version. + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General + Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#include <system.h> +#include <paxlib.h> +#include <quote.h> +#include <quotearg.h> + +void (*error_hook) (void); + +/* Decode MODE from its binary form in a stat structure, and encode it + into a 9-byte string STRING, terminated with a NUL. */ + +void +pax_decode_mode (mode_t mode, char *string) +{ + *string++ = mode & S_IRUSR ? 'r' : '-'; + *string++ = mode & S_IWUSR ? 'w' : '-'; + *string++ = (mode & S_ISUID + ? (mode & S_IXUSR ? 's' : 'S') + : (mode & S_IXUSR ? 'x' : '-')); + *string++ = mode & S_IRGRP ? 'r' : '-'; + *string++ = mode & S_IWGRP ? 'w' : '-'; + *string++ = (mode & S_ISGID + ? (mode & S_IXGRP ? 's' : 'S') + : (mode & S_IXGRP ? 'x' : '-')); + *string++ = mode & S_IROTH ? 'r' : '-'; + *string++ = mode & S_IWOTH ? 'w' : '-'; + *string++ = (mode & S_ISVTX + ? (mode & S_IXOTH ? 't' : 'T') + : (mode & S_IXOTH ? 'x' : '-')); + *string = '\0'; +} + +/* Report an error associated with the system call CALL and the + optional name NAME. */ +void +call_arg_error (char const *call, char const *name) +{ + int e = errno; + /* TRANSLATORS: %s after `Cannot' is a function name, e.g. `Cannot open'. + Directly translating this to another language will not work, first because + %s itself is not translated. + Translate it as `%s: Function %s failed'. */ + ERROR ((0, e, _("%s: Cannot %s"), quotearg_colon (name), call)); +} + +/* Report a fatal error associated with the system call CALL and + the optional file name NAME. */ +void +call_arg_fatal (char const *call, char const *name) +{ + int e = errno; + /* TRANSLATORS: %s after `Cannot' is a function name, e.g. `Cannot open'. + Directly translating this to another language will not work, first because + %s itself is not translated. + Translate it as `%s: Function %s failed'. */ + FATAL_ERROR ((0, e, _("%s: Cannot %s"), quotearg_colon (name), call)); +} + +/* Report a warning associated with the system call CALL and + the optional file name NAME. */ +void +call_arg_warn (char const *call, char const *name) +{ + int e = errno; + /* TRANSLATORS: %s after `Cannot' is a function name, e.g. `Cannot open'. + Directly translating this to another language will not work, first because + %s itself is not translated. + Translate it as `%s: Function %s failed'. */ + WARN ((0, e, _("%s: Warning: Cannot %s"), quotearg_colon (name), call)); +} + +void +chmod_error_details (char const *name, mode_t mode) +{ + int e = errno; + char buf[10]; + pax_decode_mode (mode, buf); + ERROR ((0, e, _("%s: Cannot change mode to %s"), + quotearg_colon (name), buf)); +} + +void +chown_error_details (char const *name, uid_t uid, gid_t gid) +{ + int e = errno; + ERROR ((0, e, _("%s: Cannot change ownership to uid %lu, gid %lu"), + quotearg_colon (name), (unsigned long) uid, (unsigned long) gid)); +} + +void +close_error (char const *name) +{ + call_arg_error ("close", name); +} + +void +close_warn (char const *name) +{ + call_arg_warn ("close", name); +} + +void +exec_fatal (char const *name) +{ + call_arg_fatal ("exec", name); +} + +void +link_error (char const *target, char const *source) +{ + int e = errno; + ERROR ((0, e, _("%s: Cannot hard link to %s"), + quotearg_colon (source), quote_n (1, target))); +} + +void +mkdir_error (char const *name) +{ + call_arg_error ("mkdir", name); +} + +void +mkfifo_error (char const *name) +{ + call_arg_error ("mkfifo", name); +} + +void +mknod_error (char const *name) +{ + call_arg_error ("mknod", name); +} + +void +open_error (char const *name) +{ + call_arg_error ("open", name); +} + +void +open_fatal (char const *name) +{ + call_arg_fatal ("open", name); +} + +void +open_warn (char const *name) +{ + call_arg_warn ("open", name); +} + +void +read_error (char const *name) +{ + call_arg_error ("read", name); +} + +void +read_error_details (char const *name, off_t offset, size_t size) +{ + char buf[UINTMAX_STRSIZE_BOUND]; + int e = errno; + ERROR ((0, e, + ngettext ("%s: Read error at byte %s, while reading %lu byte", + "%s: Read error at byte %s, while reading %lu bytes", + size), + quotearg_colon (name), STRINGIFY_BIGINT (offset, buf), + (unsigned long) size)); +} + +void +read_warn_details (char const *name, off_t offset, size_t size) +{ + char buf[UINTMAX_STRSIZE_BOUND]; + int e = errno; + WARN ((0, e, + ngettext ("%s: Warning: Read error at byte %s, while reading %lu byte", + "%s: Warning: Read error at byte %s, while reading %lu bytes", + size), + quotearg_colon (name), STRINGIFY_BIGINT (offset, buf), + (unsigned long) size)); +} + +void +read_fatal (char const *name) +{ + call_arg_fatal ("read", name); +} + +void +read_fatal_details (char const *name, off_t offset, size_t size) +{ + char buf[UINTMAX_STRSIZE_BOUND]; + int e = errno; + FATAL_ERROR ((0, e, + ngettext ("%s: Read error at byte %s, while reading %lu byte", + "%s: Read error at byte %s, while reading %lu bytes", + size), + quotearg_colon (name), STRINGIFY_BIGINT (offset, buf), + (unsigned long) size)); +} + +void +readlink_error (char const *name) +{ + call_arg_error ("readlink", name); +} + +void +readlink_warn (char const *name) +{ + call_arg_warn ("readlink", name); +} + +void +rmdir_error (char const *name) +{ + call_arg_error ("rmdir", name); +} + +void +savedir_error (char const *name) +{ + call_arg_error ("savedir", name); +} + +void +savedir_warn (char const *name) +{ + call_arg_warn ("savedir", name); +} + +void +seek_error (char const *name) +{ + call_arg_error ("seek", name); +} + +void +seek_error_details (char const *name, off_t offset) +{ + char buf[UINTMAX_STRSIZE_BOUND]; + int e = errno; + ERROR ((0, e, _("%s: Cannot seek to %s"), + quotearg_colon (name), + STRINGIFY_BIGINT (offset, buf))); +} + +void +seek_warn (char const *name) +{ + call_arg_warn ("seek", name); +} + +void +seek_warn_details (char const *name, off_t offset) +{ + char buf[UINTMAX_STRSIZE_BOUND]; + int e = errno; + WARN ((0, e, _("%s: Warning: Cannot seek to %s"), + quotearg_colon (name), + STRINGIFY_BIGINT (offset, buf))); +} + +void +symlink_error (char const *contents, char const *name) +{ + int e = errno; + ERROR ((0, e, _("%s: Cannot create symlink to %s"), + quotearg_colon (name), quote_n (1, contents))); +} + +void +stat_fatal (char const *name) +{ + call_arg_fatal ("stat", name); +} + +void +stat_error (char const *name) +{ + call_arg_error ("stat", name); +} + +void +stat_warn (char const *name) +{ + call_arg_warn ("stat", name); +} + +void +truncate_error (char const *name) +{ + call_arg_error ("truncate", name); +} + +void +truncate_warn (char const *name) +{ + call_arg_warn ("truncate", name); +} + +void +unlink_error (char const *name) +{ + call_arg_error ("unlink", name); +} + +void +utime_error (char const *name) +{ + call_arg_error ("utime", name); +} + +void +waitpid_error (char const *name) +{ + call_arg_error ("waitpid", name); +} + +void +write_error (char const *name) +{ + call_arg_error ("write", name); +} + +void +write_error_details (char const *name, size_t status, size_t size) +{ + if (status == 0) + write_error (name); + else + ERROR ((0, 0, + ngettext ("%s: Wrote only %lu of %lu byte", + "%s: Wrote only %lu of %lu bytes", + size), + name, (unsigned long int) status, (unsigned long int) size)); +} + +void +chdir_fatal (char const *name) +{ + call_arg_fatal ("chdir", name); +} diff --git a/lib/paxexit-status.c b/lib/paxexit-status.c new file mode 100644 index 0000000..3c244ab --- /dev/null +++ b/lib/paxexit-status.c @@ -0,0 +1,3 @@ +#include <system.h> +#include <paxlib.h> +int exit_status = PAXEXIT_SUCCESS; diff --git a/lib/paxlib.h b/lib/paxlib.h new file mode 100644 index 0000000..d4251d1 --- /dev/null +++ b/lib/paxlib.h @@ -0,0 +1,132 @@ +/* This file is part of GNU paxutils + + Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2003, + 2005, 2007 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +#ifndef _paxlib_h_ +#define _paxlib_h_ + +#include <inttostr.h> + +/* Error reporting functions and definitions */ + +/* Exit status for paxutils app. Let's try to keep this list as simple as + possible. tar -d option strongly invites a status different for unequal + comparison and other errors. */ +#define PAXEXIT_SUCCESS 0 +#define PAXEXIT_DIFFERS 1 +#define PAXEXIT_FAILURE 2 + +extern void (*error_hook) (void); + +/* Both WARN and ERROR write a message on stderr and continue processing, + however ERROR manages so tar will exit unsuccessfully. FATAL_ERROR + writes a message on stderr and aborts immediately, with another message + line telling so. USAGE_ERROR works like FATAL_ERROR except that the + other message line suggests trying --help. All four macros accept a + single argument of the form ((0, errno, _("FORMAT"), Args...)). errno + is zero when the error is not being detected by the system. */ + +#define WARN(Args) \ + do { if (error_hook) error_hook (); error Args; } while (0) +#define ERROR(Args) \ + do \ + { \ + if (error_hook) error_hook (); \ + error Args; \ + exit_status = PAXEXIT_FAILURE; \ + } \ + while (0) +#define FATAL_ERROR(Args) \ + do \ + { \ + if (error_hook) error_hook (); \ + error Args; \ + fatal_exit (); \ + } \ + while (0) +#define USAGE_ERROR(Args) \ + do \ + { \ + if (error_hook) error_hook (); \ + error Args; \ + usage (PAXEXIT_FAILURE); \ + } \ + while (0) + +extern int exit_status; + +void pax_decode_mode (mode_t mode, char *string); +void call_arg_error (char const *call, char const *name); +void call_arg_fatal (char const *call, char const *name) __attribute__ ((noreturn)); +void call_arg_warn (char const *call, char const *name); +void chmod_error_details (char const *name, mode_t mode); +void chown_error_details (char const *name, uid_t uid, gid_t gid); + +void decode_mode (mode_t, char *); + +void chdir_fatal (char const *) __attribute__ ((noreturn)); +void chmod_error_details (char const *, mode_t); +void chown_error_details (char const *, uid_t, gid_t); +void close_error (char const *); +void close_warn (char const *); +void exec_fatal (char const *) __attribute__ ((noreturn)); +void link_error (char const *, char const *); +void mkdir_error (char const *); +void mkfifo_error (char const *); +void mknod_error (char const *); +void open_error (char const *); +void open_fatal (char const *) __attribute__ ((noreturn)); +void open_warn (char const *); +void read_error (char const *); +void read_error_details (char const *, off_t, size_t); +void read_fatal (char const *) __attribute__ ((noreturn)); +void read_fatal_details (char const *, off_t, size_t) __attribute__ ((noreturn)); +void read_warn_details (char const *, off_t, size_t); +void readlink_error (char const *); +void readlink_warn (char const *); +void rmdir_error (char const *); +void savedir_error (char const *); +void savedir_warn (char const *); +void seek_error (char const *); +void seek_error_details (char const *, off_t); +void seek_warn (char const *); +void seek_warn_details (char const *, off_t); +void stat_fatal (char const *) __attribute__ ((noreturn)); +void stat_error (char const *); +void stat_warn (char const *); +void symlink_error (char const *, char const *); +void truncate_error (char const *); +void truncate_warn (char const *); +void unlink_error (char const *); +void utime_error (char const *); +void waitpid_error (char const *); +void write_error (char const *); +void write_error_details (char const *, size_t, size_t); + +void pax_exit (void) __attribute__ ((noreturn)); +void fatal_exit (void) __attribute__ ((noreturn)); + +#define STRINGIFY_BIGINT(i, b) umaxtostr (i, b) + + +/* Name-related functions */ +bool removed_prefixes_p (void); +char *safer_name_suffix (char const *file_name, bool link_target, bool absolute_names); + +#endif diff --git a/lib/paxnames.c b/lib/paxnames.c new file mode 100644 index 0000000..5766d4c --- /dev/null +++ b/lib/paxnames.c @@ -0,0 +1,164 @@ +/* This file is part of GNU paxutils + Copyright (C) 2005, 2007, 2010 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by the + Free Software Foundation; either version 3, or (at your option) any later + version. + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General + Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#include <system.h> +#include <hash.h> +#include <paxlib.h> + + +/* Hash tables of strings. */ + +/* Calculate the hash of a string. */ +static size_t +hash_string_hasher (void const *name, size_t n_buckets) +{ + return hash_string (name, n_buckets); +} + +/* Compare two strings for equality. */ +static bool +hash_string_compare (void const *name1, void const *name2) +{ + return strcmp (name1, name2) == 0; +} + +/* Return zero if TABLE contains a LEN-character long prefix of STRING, + otherwise, insert a newly allocated copy of this prefix to TABLE and + return 1. If RETURN_PREFIX is not NULL, point it to the allocated + copy. */ +static bool +hash_string_insert_prefix (Hash_table **table, char const *string, size_t len, + const char **return_prefix) +{ + Hash_table *t = *table; + char *s; + char *e; + + if (len) + { + s = xmalloc (len + 1); + memcpy (s, string, len); + s[len] = 0; + } + else + s = xstrdup (string); + + if (! ((t + || (*table = t = hash_initialize (0, 0, hash_string_hasher, + hash_string_compare, 0))) + && (e = hash_insert (t, s)))) + xalloc_die (); + + if (e == s) + { + if (return_prefix) + *return_prefix = s; + return 1; + } + else + { + free (s); + return 0; + } +} + + +static Hash_table *prefix_table[2]; + +/* Return true if file names of some members in the archive were stripped off + their leading components. We could have used + return prefix_table[0] || prefix_table[1] + but the following seems to be safer: */ +bool +removed_prefixes_p (void) +{ + return (prefix_table[0] && hash_get_n_entries (prefix_table[0]) != 0) + || (prefix_table[1] && hash_get_n_entries (prefix_table[1]) != 0); +} + +/* Return a safer suffix of FILE_NAME, or "." if it has no safer + suffix. Check for fully specified file names and other atrocities. + Warn the user if we do not return NAME. If LINK_TARGET is 1, + FILE_NAME is the target of a hard link, not a member name. + If ABSOLUTE_NAMES is 0, strip filesystem prefix from the file name. */ + +char * +safer_name_suffix (char const *file_name, bool link_target, + bool absolute_names) +{ + char const *p; + + if (absolute_names) + p = file_name; + else + { + /* Skip file system prefixes, leading file name components that contain + "..", and leading slashes. */ + + size_t prefix_len = FILE_SYSTEM_PREFIX_LEN (file_name); + + for (p = file_name + prefix_len; *p; ) + { + if (p[0] == '.' && p[1] == '.' && (ISSLASH (p[2]) || !p[2])) + prefix_len = p + 2 - file_name; + + do + { + char c = *p++; + if (ISSLASH (c)) + break; + } + while (*p); + } + + for (p = file_name + prefix_len; ISSLASH (*p); p++) + continue; + prefix_len = p - file_name; + + if (prefix_len) + { + const char *prefix; + if (hash_string_insert_prefix (&prefix_table[link_target], file_name, + prefix_len, &prefix)) + { + static char const *const diagnostic[] = + { + N_("Removing leading `%s' from member names"), + N_("Removing leading `%s' from hard link targets") + }; + WARN ((0, 0, _(diagnostic[link_target]), prefix)); + } + } + } + + if (! *p) + { + if (p == file_name) + { + static char const *const diagnostic[] = + { + N_("Substituting `.' for empty member name"), + N_("Substituting `.' for empty hard link target") + }; + WARN ((0, 0, "%s", _(diagnostic[link_target]))); + } + + p = "."; + } + + return (char *) p; +} diff --git a/lib/rmt.h b/lib/rmt.h new file mode 100644 index 0000000..ff10e7c --- /dev/null +++ b/lib/rmt.h @@ -0,0 +1,99 @@ +/* Definitions for communicating with a remote tape drive. + + Copyright (C) 1988, 1992, 1996, 1997, 2001, 2003, 2004, 2007 Free + Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + +extern char const *rmt_command; +extern char const *rmt_dev_name__; + +int rmt_open__ (const char *, int, int, const char *); +int rmt_close__ (int); +size_t rmt_read__ (int, char *, size_t); +size_t rmt_write__ (int, char *, size_t); +off_t rmt_lseek__ (int, off_t, int); +int rmt_ioctl__ (int, int, char *); + +extern bool force_local_option; + +/* A filename is remote if it contains a colon not preceded by a slash, + to take care of `/:/' which is a shorthand for `/.../<CELL-NAME>/fs' + on machines running OSF's Distributing Computing Environment (DCE) and + Distributed File System (DFS). However, when --force-local, a + filename is never remote. */ + +#define _remdev(dev_name) \ + (!force_local_option && (rmt_dev_name__ = strchr (dev_name, ':')) \ + && rmt_dev_name__ > (dev_name) \ + && ! memchr (dev_name, '/', rmt_dev_name__ - (dev_name))) + +#define _isrmt(fd) \ + ((fd) >= __REM_BIAS) + +#define __REM_BIAS (1 << 30) + +#ifndef O_CREAT +# define O_CREAT 01000 +#endif + +#define rmtopen(dev_name, oflag, mode, command) \ + (_remdev (dev_name) ? rmt_open__ (dev_name, oflag, __REM_BIAS, command) \ + : open (dev_name, oflag, mode)) + +#define rmtaccess(dev_name, amode) \ + (_remdev (dev_name) ? 0 : access (dev_name, amode)) + +#define rmtstat(dev_name, buffer) \ + (_remdev (dev_name) ? (errno = EOPNOTSUPP), -1 : stat (dev_name, buffer)) + +#define rmtcreat(dev_name, mode, command) \ + (_remdev (dev_name) \ + ? rmt_open__ (dev_name, O_CREAT | O_WRONLY, __REM_BIAS, command) \ + : creat (dev_name, mode)) + +#define rmtlstat(dev_name, muffer) \ + (_remdev (dev_name) ? (errno = EOPNOTSUPP), -1 : lstat (dev_name, buffer)) + +#define rmtread(fd, buffer, length) \ + (_isrmt (fd) ? rmt_read__ (fd - __REM_BIAS, buffer, length) \ + : safe_read (fd, buffer, length)) + +#define rmtwrite(fd, buffer, length) \ + (_isrmt (fd) ? rmt_write__ (fd - __REM_BIAS, buffer, length) \ + : full_write (fd, buffer, length)) + +#define rmtlseek(fd, offset, where) \ + (_isrmt (fd) ? rmt_lseek__ (fd - __REM_BIAS, offset, where) \ + : lseek (fd, offset, where)) + +#define rmtclose(fd) \ + (_isrmt (fd) ? rmt_close__ (fd - __REM_BIAS) : close (fd)) + +#define rmtioctl(fd, request, argument) \ + (_isrmt (fd) ? rmt_ioctl__ (fd - __REM_BIAS, request, argument) \ + : ioctl (fd, request, argument)) + +#define rmtdup(fd) \ + (_isrmt (fd) ? (errno = EOPNOTSUPP), -1 : dup (fd)) + +#define rmtfstat(fd, buffer) \ + (_isrmt (fd) ? (errno = EOPNOTSUPP), -1 : fstat (fd, buffer)) + +#define rmtfcntl(cd, command, argument) \ + (_isrmt (fd) ? (errno = EOPNOTSUPP), -1 : fcntl (fd, command, argument)) + +#define rmtisatty(fd) \ + (_isrmt (fd) ? 0 : isatty (fd)) diff --git a/lib/rtapelib.c b/lib/rtapelib.c new file mode 100644 index 0000000..7213031 --- /dev/null +++ b/lib/rtapelib.c @@ -0,0 +1,751 @@ +/* Functions for communicating with a remote tape drive. + + Copyright (C) 1988, 1992, 1994, 1996, 1997, 1999, 2000, 2001, 2004, + 2005, 2006, 2007 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + +/* The man page rmt(8) for /etc/rmt documents the remote mag tape protocol + which rdump and rrestore use. Unfortunately, the man page is *WRONG*. + The author of the routines I'm including originally wrote his code just + based on the man page, and it didn't work, so he went to the rdump source + to figure out why. The only thing he had to change was to check for the + 'F' return code in addition to the 'E', and to separate the various + arguments with \n instead of a space. I personally don't think that this + is much of a problem, but I wanted to point it out. -- Arnold Robbins + + Originally written by Jeff Lee, modified some by Arnold Robbins. Redone + as a library that can replace open, read, write, etc., by Fred Fish, with + some additional work by Arnold Robbins. Modified to make all rmt* calls + into macros for speed by Jay Fenlason. Use -DWITH_REXEC for rexec + code, courtesy of Dan Kegel. */ + +#include "system.h" +#include "system-ioctl.h" + +#include <safe-read.h> +#include <full-write.h> + +/* Try hard to get EOPNOTSUPP defined. 486/ISC has it in net/errno.h, + 3B2/SVR3 has it in sys/inet.h. Otherwise, like on MSDOS, use EINVAL. */ + +#ifndef EOPNOTSUPP +# if HAVE_NET_ERRNO_H +# include <net/errno.h> +# endif +# if HAVE_SYS_INET_H +# include <sys/inet.h> +# endif +# ifndef EOPNOTSUPP +# define EOPNOTSUPP EINVAL +# endif +#endif + +#include <signal.h> + +#if HAVE_NETDB_H +# include <netdb.h> +#endif + +#include <rmt.h> +#include <rmt-command.h> + +/* Exit status if exec errors. */ +#define EXIT_ON_EXEC_ERROR 128 + +/* FIXME: Size of buffers for reading and writing commands to rmt. */ +#define COMMAND_BUFFER_SIZE 64 + +#ifndef RETSIGTYPE +# define RETSIGTYPE void +#endif + +/* FIXME: Maximum number of simultaneous remote tape connections. */ +#define MAXUNIT 4 + +#define PREAD 0 /* read file descriptor from pipe() */ +#define PWRITE 1 /* write file descriptor from pipe() */ + +/* Return the parent's read side of remote tape connection Fd. */ +#define READ_SIDE(Fd) (from_remote[Fd][PREAD]) + +/* Return the parent's write side of remote tape connection Fd. */ +#define WRITE_SIDE(Fd) (to_remote[Fd][PWRITE]) + +/* The pipes for receiving data from remote tape drives. */ +static int from_remote[MAXUNIT][2] = {{-1, -1}, {-1, -1}, {-1, -1}, {-1, -1}}; + +/* The pipes for sending data to remote tape drives. */ +static int to_remote[MAXUNIT][2] = {{-1, -1}, {-1, -1}, {-1, -1}, {-1, -1}}; + +char const *rmt_command = DEFAULT_RMT_COMMAND; + +/* Temporary variable used by macros in rmt.h. */ +char const *rmt_dev_name__; + +/* If true, always consider file names to be local, even if they contain + colons */ +bool force_local_option; + + + +/* Close remote tape connection HANDLE, and reset errno to ERRNO_VALUE. */ +static void +_rmt_shutdown (int handle, int errno_value) +{ + close (READ_SIDE (handle)); + close (WRITE_SIDE (handle)); + READ_SIDE (handle) = -1; + WRITE_SIDE (handle) = -1; + errno = errno_value; +} + +/* Attempt to perform the remote tape command specified in BUFFER on + remote tape connection HANDLE. Return 0 if successful, -1 on + error. */ +static int +do_command (int handle, const char *buffer) +{ + /* Save the current pipe handler and try to make the request. */ + + size_t length = strlen (buffer); + RETSIGTYPE (*pipe_handler) (int) = signal (SIGPIPE, SIG_IGN); + ssize_t written = full_write (WRITE_SIDE (handle), buffer, length); + signal (SIGPIPE, pipe_handler); + + if (written == length) + return 0; + + /* Something went wrong. Close down and go home. */ + + _rmt_shutdown (handle, EIO); + return -1; +} + +static char * +get_status_string (int handle, char *command_buffer) +{ + char *cursor; + int counter; + + /* Read the reply command line. */ + + for (counter = 0, cursor = command_buffer; + counter < COMMAND_BUFFER_SIZE; + counter++, cursor++) + { + if (safe_read (READ_SIDE (handle), cursor, 1) != 1) + { + _rmt_shutdown (handle, EIO); + return 0; + } + if (*cursor == '\n') + { + *cursor = '\0'; + break; + } + } + + if (counter == COMMAND_BUFFER_SIZE) + { + _rmt_shutdown (handle, EIO); + return 0; + } + + /* Check the return status. */ + + for (cursor = command_buffer; *cursor; cursor++) + if (*cursor != ' ') + break; + + if (*cursor == 'E' || *cursor == 'F') + { + /* Skip the error message line. */ + + /* FIXME: there is better to do than merely ignoring error messages + coming from the remote end. Translate them, too... */ + + { + char character; + + while (safe_read (READ_SIDE (handle), &character, 1) == 1) + if (character == '\n') + break; + } + + errno = atoi (cursor + 1); + + if (*cursor == 'F') + _rmt_shutdown (handle, errno); + + return 0; + } + + /* Check for mis-synced pipes. */ + + if (*cursor != 'A') + { + _rmt_shutdown (handle, EIO); + return 0; + } + + /* Got an `A' (success) response. */ + + return cursor + 1; +} + +/* Read and return the status from remote tape connection HANDLE. If + an error occurred, return -1 and set errno. */ +static long int +get_status (int handle) +{ + char command_buffer[COMMAND_BUFFER_SIZE]; + const char *status = get_status_string (handle, command_buffer); + if (status) + { + long int result = atol (status); + if (0 <= result) + return result; + errno = EIO; + } + return -1; +} + +static off_t +get_status_off (int handle) +{ + char command_buffer[COMMAND_BUFFER_SIZE]; + const char *status = get_status_string (handle, command_buffer); + + if (! status) + return -1; + else + { + /* Parse status, taking care to check for overflow. + We can't use standard functions, + since off_t might be longer than long. */ + + off_t count = 0; + int negative; + + for (; *status == ' ' || *status == '\t'; status++) + continue; + + negative = *status == '-'; + status += negative || *status == '+'; + + for (;;) + { + int digit = *status++ - '0'; + if (9 < (unsigned) digit) + break; + else + { + off_t c10 = 10 * count; + off_t nc = negative ? c10 - digit : c10 + digit; + if (c10 / 10 != count || (negative ? c10 < nc : nc < c10)) + return -1; + count = nc; + } + } + + return count; + } +} + +#if WITH_REXEC + +/* Execute /etc/rmt as user USER on remote system HOST using rexec. + Return a file descriptor of a bidirectional socket for stdin and + stdout. If USER is zero, use the current username. + + By default, this code is not used, since it requires that the user + have a .netrc file in his/her home directory, or that the + application designer be willing to have rexec prompt for login and + password info. This may be unacceptable, and .rhosts files for use + with rsh are much more common on BSD systems. */ +static int +_rmt_rexec (char *host, char *user) +{ + int saved_stdin = dup (STDIN_FILENO); + int saved_stdout = dup (STDOUT_FILENO); + struct servent *rexecserv; + int result; + + /* When using cpio -o < filename, stdin is no longer the tty. But the + rexec subroutine reads the login and the passwd on stdin, to allow + remote execution of the command. So, reopen stdin and stdout on + /dev/tty before the rexec and give them back their original value + after. */ + + if (! freopen ("/dev/tty", "r", stdin)) + freopen ("/dev/null", "r", stdin); + if (! freopen ("/dev/tty", "w", stdout)) + freopen ("/dev/null", "w", stdout); + + if (rexecserv = getservbyname ("exec", "tcp"), !rexecserv) + error (EXIT_ON_EXEC_ERROR, 0, _("exec/tcp: Service not available")); + + result = rexec (&host, rexecserv->s_port, user, 0, rmt_command, 0); + if (fclose (stdin) == EOF) + error (0, errno, _("stdin")); + fdopen (saved_stdin, "r"); + if (fclose (stdout) == EOF) + error (0, errno, _("stdout")); + fdopen (saved_stdout, "w"); + + return result; +} + +#endif /* WITH_REXEC */ + +/* Place into BUF a string representing OFLAG, which must be suitable + as argument 2 of `open'. BUF must be large enough to hold the + result. This function should generate a string that decode_oflag + can parse. */ +static void +encode_oflag (char *buf, int oflag) +{ + sprintf (buf, "%d ", oflag); + + switch (oflag & O_ACCMODE) + { + case O_RDONLY: strcat (buf, "O_RDONLY"); break; + case O_RDWR: strcat (buf, "O_RDWR"); break; + case O_WRONLY: strcat (buf, "O_WRONLY"); break; + default: abort (); + } + +#ifdef O_APPEND + if (oflag & O_APPEND) strcat (buf, "|O_APPEND"); +#endif + if (oflag & O_CREAT) strcat (buf, "|O_CREAT"); +#ifdef O_DSYNC + if (oflag & O_DSYNC) strcat (buf, "|O_DSYNC"); +#endif + if (oflag & O_EXCL) strcat (buf, "|O_EXCL"); +#ifdef O_LARGEFILE + if (oflag & O_LARGEFILE) strcat (buf, "|O_LARGEFILE"); +#endif +#ifdef O_NOCTTY + if (oflag & O_NOCTTY) strcat (buf, "|O_NOCTTY"); +#endif + if (oflag & O_NONBLOCK) strcat (buf, "|O_NONBLOCK"); +#ifdef O_RSYNC + if (oflag & O_RSYNC) strcat (buf, "|O_RSYNC"); +#endif +#ifdef O_SYNC + if (oflag & O_SYNC) strcat (buf, "|O_SYNC"); +#endif + if (oflag & O_TRUNC) strcat (buf, "|O_TRUNC"); +} + +/* Open a file (a magnetic tape device?) on the system specified in + FILE_NAME, as the given user. FILE_NAME has the form `[USER@]HOST:FILE'. + OPEN_MODE is O_RDONLY, O_WRONLY, etc. If successful, return the + remote pipe number plus BIAS. REMOTE_SHELL may be overridden. On + error, return -1. */ +int +rmt_open__ (const char *file_name, int open_mode, int bias, + const char *remote_shell) +{ + int remote_pipe_number; /* pseudo, biased file descriptor */ + char *file_name_copy; /* copy of file_name string */ + char *remote_host; /* remote host name */ + char *remote_file; /* remote file name (often a device) */ + char *remote_user; /* remote user name */ + + /* Find an unused pair of file descriptors. */ + + for (remote_pipe_number = 0; + remote_pipe_number < MAXUNIT; + remote_pipe_number++) + if (READ_SIDE (remote_pipe_number) == -1 + && WRITE_SIDE (remote_pipe_number) == -1) + break; + + if (remote_pipe_number == MAXUNIT) + { + errno = EMFILE; + return -1; + } + + /* Pull apart the system and device, and optional user. */ + + { + char *cursor; + + file_name_copy = xstrdup (file_name); + remote_host = file_name_copy; + remote_user = 0; + remote_file = 0; + + for (cursor = file_name_copy; *cursor; cursor++) + switch (*cursor) + { + default: + break; + + case '\n': + /* Do not allow newlines in the file_name, since the protocol + uses newline delimiters. */ + free (file_name_copy); + errno = ENOENT; + return -1; + + case '@': + if (!remote_user) + { + remote_user = remote_host; + *cursor = '\0'; + remote_host = cursor + 1; + } + break; + + case ':': + if (!remote_file) + { + *cursor = '\0'; + remote_file = cursor + 1; + } + break; + } + } + + /* FIXME: Should somewhat validate the decoding, here. */ + if (gethostbyname (remote_host) == NULL) + error (EXIT_ON_EXEC_ERROR, 0, _("Cannot connect to %s: resolve failed"), + remote_host); + + if (remote_user && *remote_user == '\0') + remote_user = 0; + +#if WITH_REXEC + + /* Execute the remote command using rexec. */ + + READ_SIDE (remote_pipe_number) = _rmt_rexec (remote_host, remote_user); + if (READ_SIDE (remote_pipe_number) < 0) + { + int e = errno; + free (file_name_copy); + errno = e; + return -1; + } + + WRITE_SIDE (remote_pipe_number) = READ_SIDE (remote_pipe_number); + +#else /* not WITH_REXEC */ + { + const char *remote_shell_basename; + pid_t status; + + /* Identify the remote command to be executed. */ + + if (!remote_shell) + { +#ifdef REMOTE_SHELL + remote_shell = REMOTE_SHELL; +#else + free (file_name_copy); + errno = EIO; + return -1; +#endif + } + remote_shell_basename = last_component (remote_shell); + + /* Set up the pipes for the `rsh' command, and fork. */ + + if (pipe (to_remote[remote_pipe_number]) == -1 + || pipe (from_remote[remote_pipe_number]) == -1) + { + int e = errno; + free (file_name_copy); + errno = e; + return -1; + } + + status = fork (); + if (status == -1) + { + int e = errno; + free (file_name_copy); + errno = e; + return -1; + } + + if (status == 0) + { + /* Child. */ + + if (dup2 (to_remote[remote_pipe_number][PREAD], STDIN_FILENO) < 0 + || (to_remote[remote_pipe_number][PREAD] != STDIN_FILENO + && close (to_remote[remote_pipe_number][PREAD]) != 0) + || (to_remote[remote_pipe_number][PWRITE] != STDIN_FILENO + && close (to_remote[remote_pipe_number][PWRITE]) != 0) + || dup2 (from_remote[remote_pipe_number][PWRITE], STDOUT_FILENO) < 0 + || close (from_remote[remote_pipe_number][PREAD]) != 0 + || close (from_remote[remote_pipe_number][PWRITE]) != 0) + error (EXIT_ON_EXEC_ERROR, errno, + _("Cannot redirect files for remote shell")); + + sys_reset_uid_gid (); + + if (remote_user) + execl (remote_shell, remote_shell_basename, remote_host, + "-l", remote_user, rmt_command, (char *) 0); + else + execl (remote_shell, remote_shell_basename, remote_host, + rmt_command, (char *) 0); + + /* Bad problems if we get here. */ + + /* In a previous version, _exit was used here instead of exit. */ + error (EXIT_ON_EXEC_ERROR, errno, _("Cannot execute remote shell")); + } + + /* Parent. */ + + close (from_remote[remote_pipe_number][PWRITE]); + close (to_remote[remote_pipe_number][PREAD]); + } +#endif /* not WITH_REXEC */ + + /* Attempt to open the tape device. */ + + { + size_t remote_file_len = strlen (remote_file); + char *command_buffer = xmalloc (remote_file_len + 1000); + sprintf (command_buffer, "O%s\n", remote_file); + encode_oflag (command_buffer + remote_file_len + 2, open_mode); + strcat (command_buffer, "\n"); + if (do_command (remote_pipe_number, command_buffer) == -1 + || get_status (remote_pipe_number) == -1) + { + int e = errno; + free (command_buffer); + free (file_name_copy); + _rmt_shutdown (remote_pipe_number, e); + return -1; + } + free (command_buffer); + } + + free (file_name_copy); + return remote_pipe_number + bias; +} + +/* Close remote tape connection HANDLE and shut down. Return 0 if + successful, -1 on error. */ +int +rmt_close__ (int handle) +{ + long int status; + + if (do_command (handle, "C\n") == -1) + return -1; + + status = get_status (handle); + _rmt_shutdown (handle, errno); + return status; +} + +/* Read up to LENGTH bytes into BUFFER from remote tape connection HANDLE. + Return the number of bytes read on success, SAFE_READ_ERROR on error. */ +size_t +rmt_read__ (int handle, char *buffer, size_t length) +{ + char command_buffer[COMMAND_BUFFER_SIZE]; + size_t status; + size_t rlen; + size_t counter; + + sprintf (command_buffer, "R%lu\n", (unsigned long) length); + if (do_command (handle, command_buffer) == -1 + || (status = get_status (handle)) == SAFE_READ_ERROR + || status > length) + return SAFE_READ_ERROR; + + for (counter = 0; counter < status; counter += rlen, buffer += rlen) + { + rlen = safe_read (READ_SIDE (handle), buffer, status - counter); + if (rlen == SAFE_READ_ERROR || rlen == 0) + { + _rmt_shutdown (handle, EIO); + return SAFE_READ_ERROR; + } + } + + return status; +} + +/* Write LENGTH bytes from BUFFER to remote tape connection HANDLE. + Return the number of bytes written. */ +size_t +rmt_write__ (int handle, char *buffer, size_t length) +{ + char command_buffer[COMMAND_BUFFER_SIZE]; + RETSIGTYPE (*pipe_handler) (int); + size_t written; + + sprintf (command_buffer, "W%lu\n", (unsigned long) length); + if (do_command (handle, command_buffer) == -1) + return 0; + + pipe_handler = signal (SIGPIPE, SIG_IGN); + written = full_write (WRITE_SIDE (handle), buffer, length); + signal (SIGPIPE, pipe_handler); + if (written == length) + { + long int r = get_status (handle); + if (r < 0) + return 0; + if (r == length) + return length; + written = r; + } + + /* Write error. */ + + _rmt_shutdown (handle, EIO); + return written; +} + +/* Perform an imitation lseek operation on remote tape connection + HANDLE. Return the new file offset if successful, -1 if on error. */ +off_t +rmt_lseek__ (int handle, off_t offset, int whence) +{ + char command_buffer[COMMAND_BUFFER_SIZE]; + char operand_buffer[UINTMAX_STRSIZE_BOUND]; + uintmax_t u = offset < 0 ? - (uintmax_t) offset : (uintmax_t) offset; + char *p = operand_buffer + sizeof operand_buffer; + + *--p = 0; + do + *--p = '0' + (int) (u % 10); + while ((u /= 10) != 0); + if (offset < 0) + *--p = '-'; + + switch (whence) + { + case SEEK_SET: whence = 0; break; + case SEEK_CUR: whence = 1; break; + case SEEK_END: whence = 2; break; + default: abort (); + } + + sprintf (command_buffer, "L%s\n%d\n", p, whence); + + if (do_command (handle, command_buffer) == -1) + return -1; + + return get_status_off (handle); +} + +/* Perform a raw tape operation on remote tape connection HANDLE. + Return the results of the ioctl, or -1 on error. */ +int +rmt_ioctl__ (int handle, int operation, char *argument) +{ + switch (operation) + { + default: + errno = EOPNOTSUPP; + return -1; + +#ifdef MTIOCTOP + case MTIOCTOP: + { + char command_buffer[COMMAND_BUFFER_SIZE]; + char operand_buffer[UINTMAX_STRSIZE_BOUND]; + uintmax_t u = (((struct mtop *) argument)->mt_count < 0 + ? - (uintmax_t) ((struct mtop *) argument)->mt_count + : (uintmax_t) ((struct mtop *) argument)->mt_count); + char *p = operand_buffer + sizeof operand_buffer; + + *--p = 0; + do + *--p = '0' + (int) (u % 10); + while ((u /= 10) != 0); + if (((struct mtop *) argument)->mt_count < 0) + *--p = '-'; + + /* MTIOCTOP is the easy one. Nothing is transferred in binary. */ + + sprintf (command_buffer, "I%d\n%s\n", + ((struct mtop *) argument)->mt_op, p); + if (do_command (handle, command_buffer) == -1) + return -1; + + return get_status (handle); + } +#endif /* MTIOCTOP */ + +#ifdef MTIOCGET + case MTIOCGET: + { + ssize_t status; + size_t counter; + + /* Grab the status and read it directly into the structure. This + assumes that the status buffer is not padded and that 2 shorts + fit in a long without any word alignment problems; i.e., the + whole struct is contiguous. NOTE - this is probably NOT a good + assumption. */ + + if (do_command (handle, "S") == -1 + || (status = get_status (handle), status == -1)) + return -1; + + if (status > sizeof (struct mtop)) + { + errno = EOVERFLOW; + return -1; + } + + for (; status > 0; status -= counter, argument += counter) + { + counter = safe_read (READ_SIDE (handle), argument, status); + if (counter == SAFE_READ_ERROR || counter == 0) + { + _rmt_shutdown (handle, EIO); + return -1; + } + } + + /* Check for byte position. mt_type (or mt_model) is a small integer + field (normally) so we will check its magnitude. If it is larger + than 256, we will assume that the bytes are swapped and go through + and reverse all the bytes. */ + + if (((struct mtget *) argument)->MTIO_CHECK_FIELD < 256) + return 0; + + for (counter = 0; counter < status; counter += 2) + { + char copy = argument[counter]; + + argument[counter] = argument[counter + 1]; + argument[counter + 1] = copy; + } + + return 0; + } +#endif /* MTIOCGET */ + + } +} diff --git a/lib/stdopen.c b/lib/stdopen.c new file mode 100644 index 0000000..24ac8e4 --- /dev/null +++ b/lib/stdopen.c @@ -0,0 +1,76 @@ +/* stdopen.c - ensure that the three standard file descriptors are in use + + Copyright 2005, 2007, 2013-2014, 2016 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +/* Written by Paul Eggert and Jim Meyering. */ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#include "stdopen.h" + +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <unistd.h> +#include <errno.h> + +/* Try to ensure that all of the standard file numbers (0, 1, 2) + are in use. Without this, each application would have to guard + every call to open, dup, fopen, etc. with tests to ensure they + don't use one of the special file numbers when opening a file. + Return false if at least one of the file descriptors is initially + closed and an attempt to reopen it fails. Otherwise, return true. */ +bool +stdopen (void) +{ + int fd; + bool ok = true; + + for (fd = 0; fd <= 2; fd++) + { + if (fcntl (fd, F_GETFD) < 0) + { + if (errno != EBADF) + ok = false; + else + { + static const int contrary_mode[] + = { O_WRONLY, O_RDONLY, O_RDONLY }; + int mode = contrary_mode[fd]; + int new_fd; + /* Open /dev/null with the contrary mode so that the typical + read (stdin) or write (stdout, stderr) operation will fail. + With descriptor 0, we can do even better on systems that + have /dev/full, by opening that write-only instead of + /dev/null. The only drawback is that a write-provoked + failure comes with a misleading errno value, ENOSPC. */ + if (mode == O_RDONLY + || (new_fd = open ("/dev/full", mode) != fd)) + new_fd = open ("/dev/null", mode); + if (new_fd != fd) + { + if (0 <= new_fd) + close (new_fd); + ok = false; + } + } + } + } + + return ok; +} diff --git a/lib/stdopen.h b/lib/stdopen.h new file mode 100644 index 0000000..d54e5f1 --- /dev/null +++ b/lib/stdopen.h @@ -0,0 +1,16 @@ +#ifndef STDOPEN_H +# define STDOPEN_H 1 + +# include <stdbool.h> + +# ifdef __cplusplus +extern "C" { +# endif + +bool stdopen (void); + +# ifdef __cplusplus +} +# endif + +#endif diff --git a/lib/system-ioctl.h b/lib/system-ioctl.h new file mode 100644 index 0000000..f3276cf --- /dev/null +++ b/lib/system-ioctl.h @@ -0,0 +1,55 @@ +/* System dependent definitions for GNU tar's use of ioctl macros. + + Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2003, + 2004, 2005, 2006, 2007 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + +/* This is a real challenge to properly get MTIO* symbols :-(. ISC uses + <sys/gentape.h>. SCO and BSDi uses <sys/tape.h>; BSDi also requires + <sys/tprintf.h> and <sys/device.h> for defining tp_dev and tpr_t. It + seems that the rest use <sys/mtio.h>, which itself requires other files, + depending on systems. Pyramid defines _IOW in <sgtty.h>, for example. */ + +#if HAVE_SYS_GENTAPE_H +# include <sys/gentape.h> +#else +# if HAVE_SYS_TAPE_H +# if HAVE_SYS_DEVICE_H +# include <sys/device.h> +# endif +# if HAVE_SYS_PARAM_H +# include <sys/param.h> +# endif +# if HAVE_SYS_BUF_H +# include <sys/buf.h> +# endif +# if HAVE_SYS_TPRINTF_H +# include <sys/tprintf.h> +# endif +# include <sys/tape.h> +# else +# if HAVE_SYS_MTIO_H +# include <sys/ioctl.h> +# if HAVE_SGTTY_H +# include <sgtty.h> +# endif +# if HAVE_SYS_IO_TRIOCTL_H +# include <sys/io/trioctl.h> +# endif +# include <sys/mtio.h> +# endif +# endif +#endif diff --git a/lib/system.h b/lib/system.h new file mode 100644 index 0000000..e7f531c --- /dev/null +++ b/lib/system.h @@ -0,0 +1,490 @@ +/* System dependent definitions for GNU tar. + + Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2003, + 2004, 2005, 2006, 2007 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#if HAVE_CONFIG_H +# include <config.h> +#endif + +#include <alloca.h> + +#ifndef __attribute__ +/* This feature is available in gcc versions 2.5 and later. */ +# if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 5) || __STRICT_ANSI__ +# define __attribute__(spec) /* empty */ +# endif +#endif + +#include <sys/types.h> +#include <ctype.h> + +/* IN_CTYPE_DOMAIN (C) is nonzero if the unsigned char C can safely be given + as an argument to <ctype.h> macros like `isspace'. */ +#if STDC_HEADERS +# define IN_CTYPE_DOMAIN(c) 1 +#else +# define IN_CTYPE_DOMAIN(c) ((unsigned) (c) <= 0177) +#endif + +#define ISDIGIT(c) ((unsigned) (c) - '0' <= 9) +#define ISODIGIT(c) ((unsigned) (c) - '0' <= 7) +#define ISPRINT(c) (IN_CTYPE_DOMAIN (c) && isprint (c)) +#define ISSPACE(c) (IN_CTYPE_DOMAIN (c) && isspace (c)) + +/* Declare string and memory handling routines. Take care that an ANSI + string.h and pre-ANSI memory.h might conflict, and that memory.h and + strings.h conflict on some systems. */ + +#if STDC_HEADERS || HAVE_STRING_H +# include <string.h> +# if !STDC_HEADERS && HAVE_MEMORY_H +# include <memory.h> +# endif +#else +# include <strings.h> +# ifndef strchr +# define strchr index +# endif +# ifndef strrchr +# define strrchr rindex +# endif +# ifndef memcpy +# define memcpy(d, s, n) bcopy ((char const *) (s), (char *) (d), n) +# endif +# ifndef memcmp +# define memcmp(a, b, n) bcmp ((char const *) (a), (char const *) (b), n) +# endif +#endif + +/* Declare errno. */ + +#include <errno.h> +#ifndef errno +extern int errno; +#endif + +/* Declare open parameters. */ + +#if HAVE_FCNTL_H +# include <fcntl.h> +#else +# include <sys/file.h> +#endif + /* Pick only one of the next three: */ +#ifndef O_RDONLY +# define O_RDONLY 0 /* only allow read */ +#endif +#ifndef O_WRONLY +# define O_WRONLY 1 /* only allow write */ +#endif +#ifndef O_RDWR +# define O_RDWR 2 /* both are allowed */ +#endif +#ifndef O_ACCMODE +# define O_ACCMODE (O_RDONLY | O_RDWR | O_WRONLY) +#endif + /* The rest can be OR-ed in to the above: */ +#ifndef O_CREAT +# define O_CREAT 8 /* create file if needed */ +#endif +#ifndef O_EXCL +# define O_EXCL 16 /* file cannot already exist */ +#endif +#ifndef O_TRUNC +# define O_TRUNC 32 /* truncate file on open */ +#endif + +#ifndef O_BINARY +# define O_BINARY 0 +#endif +#ifndef O_DIRECTORY +# define O_DIRECTORY 0 +#endif +#ifndef O_NOATIME +# define O_NOATIME 0 +#endif +#ifndef O_NONBLOCK +# define O_NONBLOCK 0 +#endif + +/* Declare file status routines and bits. */ + +#include <sys/stat.h> + +#if !HAVE_LSTAT && !defined lstat +# define lstat stat +#endif + +#if STX_HIDDEN && !_LARGE_FILES /* AIX */ +# ifdef stat +# undef stat +# endif +# define stat(file_name, buf) statx (file_name, buf, STATSIZE, STX_HIDDEN) +# ifdef lstat +# undef lstat +# endif +# define lstat(file_name, buf) statx (file_name, buf, STATSIZE, STX_HIDDEN | STX_LINK) +#endif + +#if STAT_MACROS_BROKEN +# undef S_ISBLK +# undef S_ISCHR +# undef S_ISCTG +# undef S_ISDIR +# undef S_ISFIFO +# undef S_ISLNK +# undef S_ISREG +# undef S_ISSOCK +#endif + +/* On MSDOS, there are missing things from <sys/stat.h>. */ +#if MSDOS +# define S_ISUID 0 +# define S_ISGID 0 +# define S_ISVTX 0 +#endif + +#ifndef S_ISDIR +# define S_ISDIR(mode) (((mode) & S_IFMT) == S_IFDIR) +#endif +#ifndef S_ISREG +# define S_ISREG(mode) (((mode) & S_IFMT) == S_IFREG) +#endif + +#ifndef S_ISBLK +# ifdef S_IFBLK +# define S_ISBLK(mode) (((mode) & S_IFMT) == S_IFBLK) +# else +# define S_ISBLK(mode) 0 +# endif +#endif +#ifndef S_ISCHR +# ifdef S_IFCHR +# define S_ISCHR(mode) (((mode) & S_IFMT) == S_IFCHR) +# else +# define S_ISCHR(mode) 0 +# endif +#endif +#ifndef S_ISCTG +# ifdef S_IFCTG +# define S_ISCTG(mode) (((mode) & S_IFMT) == S_IFCTG) +# else +# define S_ISCTG(mode) 0 +# endif +#endif +#ifndef S_ISDOOR +# define S_ISDOOR(mode) 0 +#endif +#ifndef S_ISFIFO +# ifdef S_IFIFO +# define S_ISFIFO(mode) (((mode) & S_IFMT) == S_IFIFO) +# else +# define S_ISFIFO(mode) 0 +# endif +#endif +#ifndef S_ISLNK +# ifdef S_IFLNK +# define S_ISLNK(mode) (((mode) & S_IFMT) == S_IFLNK) +# else +# define S_ISLNK(mode) 0 +# endif +#endif +#ifndef S_ISSOCK +# ifdef S_IFSOCK +# define S_ISSOCK(mode) (((mode) & S_IFMT) == S_IFSOCK) +# else +# define S_ISSOCK(mode) 0 +# endif +#endif + +#if !HAVE_MKFIFO && !defined mkfifo && defined S_IFIFO +# define mkfifo(file_name, mode) (mknod (file_name, (mode) | S_IFIFO, 0)) +#endif + +#ifndef S_ISUID +# define S_ISUID 0004000 +#endif +#ifndef S_ISGID +# define S_ISGID 0002000 +#endif +#ifndef S_ISVTX +# define S_ISVTX 0001000 +#endif +#ifndef S_IRUSR +# define S_IRUSR 0000400 +#endif +#ifndef S_IWUSR +# define S_IWUSR 0000200 +#endif +#ifndef S_IXUSR +# define S_IXUSR 0000100 +#endif +#ifndef S_IRGRP +# define S_IRGRP 0000040 +#endif +#ifndef S_IWGRP +# define S_IWGRP 0000020 +#endif +#ifndef S_IXGRP +# define S_IXGRP 0000010 +#endif +#ifndef S_IROTH +# define S_IROTH 0000004 +#endif +#ifndef S_IWOTH +# define S_IWOTH 0000002 +#endif +#ifndef S_IXOTH +# define S_IXOTH 0000001 +#endif + +#define MODE_WXUSR (S_IWUSR | S_IXUSR) +#define MODE_R (S_IRUSR | S_IRGRP | S_IROTH) +#define MODE_RW (S_IWUSR | S_IWGRP | S_IWOTH | MODE_R) +#define MODE_RWX (S_IXUSR | S_IXGRP | S_IXOTH | MODE_RW) +#define MODE_ALL (S_ISUID | S_ISGID | S_ISVTX | MODE_RWX) + +/* Include <unistd.h> before any preprocessor test of _POSIX_VERSION. */ +#include <unistd.h> + +#ifndef SEEK_SET +# define SEEK_SET 0 +#endif +#ifndef SEEK_CUR +# define SEEK_CUR 1 +#endif +#ifndef SEEK_END +# define SEEK_END 2 +#endif + +#ifndef STDIN_FILENO +# define STDIN_FILENO 0 +#endif +#ifndef STDOUT_FILENO +# define STDOUT_FILENO 1 +#endif +#ifndef STDERR_FILENO +# define STDERR_FILENO 2 +#endif + +/* Declare make device, major and minor. Since major is a function on + SVR4, we have to resort to GOT_MAJOR instead of just testing if + major is #define'd. */ + +#if MAJOR_IN_MKDEV +# include <sys/mkdev.h> +# if !defined(makedev) && defined(mkdev) +# define makedev(a,b) mkdev((a),(b)) +# endif +# define GOT_MAJOR +#endif + +#if MAJOR_IN_SYSMACROS +# include <sys/sysmacros.h> +# define GOT_MAJOR +#endif + +/* Some <sys/types.h> defines the macros. */ +#ifdef major +# define GOT_MAJOR +#endif + +#ifndef GOT_MAJOR +# if MSDOS +# define major(device) (device) +# define minor(device) (device) +# define makedev(major, minor) (((major) << 8) | (minor)) +# define GOT_MAJOR +# endif +#endif + +/* For HP-UX before HP-UX 8, major/minor are not in <sys/sysmacros.h>. */ +#ifndef GOT_MAJOR +# if defined(hpux) || defined(__hpux__) || defined(__hpux) +# include <sys/mknod.h> +# define GOT_MAJOR +# endif +#endif + +#ifndef GOT_MAJOR +# define major(device) (((device) >> 8) & 0xff) +# define minor(device) ((device) & 0xff) +# define makedev(major, minor) (((major) << 8) | (minor)) +#endif + +#undef GOT_MAJOR + +/* Declare wait status. */ + +#if HAVE_SYS_WAIT_H +# include <sys/wait.h> +#endif +#ifndef WEXITSTATUS +# define WEXITSTATUS(s) (((s) >> 8) & 0xff) +#endif +#ifndef WIFSIGNALED +# define WIFSIGNALED(s) (((s) & 0xffff) - 1 < (unsigned) 0xff) +#endif +#ifndef WTERMSIG +# define WTERMSIG(s) ((s) & 0x7f) +#endif + +/* FIXME: It is wrong to use BLOCKSIZE for buffers when the logical block + size is greater than 512 bytes; so ST_BLKSIZE code below, in preparation + for some cleanup in this area, later. */ + +/* Extract or fake data from a `struct stat'. ST_BLKSIZE gives the + optimal I/O blocksize for the file, in bytes. Some systems, like + Sequents, return st_blksize of 0 on pipes. */ + +#define DEFAULT_ST_BLKSIZE 512 + +#if !HAVE_ST_BLKSIZE +# define ST_BLKSIZE(statbuf) DEFAULT_ST_BLKSIZE +#else +# define ST_BLKSIZE(statbuf) \ + ((statbuf).st_blksize > 0 ? (statbuf).st_blksize : DEFAULT_ST_BLKSIZE) +#endif + +/* Extract or fake data from a `struct stat'. ST_NBLOCKS gives the + number of ST_NBLOCKSIZE-byte blocks in the file (including indirect blocks). + HP-UX counts st_blocks in 1024-byte units, + this loses when mixing HP-UX and BSD filesystems with NFS. AIX PS/2 + counts st_blocks in 4K units. */ + +#if !HAVE_ST_BLOCKS +# if defined(_POSIX_SOURCE) || !defined(BSIZE) +# define ST_NBLOCKS(statbuf) ((statbuf).st_size / ST_NBLOCKSIZE + ((statbuf).st_size % ST_NBLOCKSIZE != 0)) +# else + off_t st_blocks (); +# define ST_NBLOCKS(statbuf) (st_blocks ((statbuf).st_size)) +# endif +#else +# define ST_NBLOCKS(statbuf) ((statbuf).st_blocks) +# if defined(hpux) || defined(__hpux__) || defined(__hpux) +# define ST_NBLOCKSIZE 1024 +# else +# if defined(_AIX) && defined(_I386) +# define ST_NBLOCKSIZE (4 * 1024) +# endif +# endif +#endif + +#ifndef ST_NBLOCKSIZE +# define ST_NBLOCKSIZE 512 +#endif + +/* Network Appliance file systems store small files directly in the + inode if st_size <= 64; in this case the number of blocks can be + zero. Perhaps other file systems have similar problems; so, + somewhat arbitrarily, do not consider a file to be sparse if + it has no blocks but st_size < ST_NBLOCKSIZE. */ +#define ST_IS_SPARSE(st) \ + (ST_NBLOCKS (st) \ + < ((st).st_size / ST_NBLOCKSIZE \ + + ((st).st_size % ST_NBLOCKSIZE != 0 \ + && (st).st_size / ST_NBLOCKSIZE != 0))) + +/* Declare standard functions. */ + +#if STDC_HEADERS +# include <stdlib.h> +#else +void *malloc (); +char *getenv (); +#endif + +#include <stdbool.h> +#include <stddef.h> + +#include <stdio.h> +#if !defined _POSIX_VERSION && MSDOS +# include <io.h> +#endif + +#if WITH_DMALLOC +# define DMALLOC_FUNC_CHECK +# include <dmalloc.h> +#endif + +#include <limits.h> + +#ifndef MB_LEN_MAX +# define MB_LEN_MAX 1 +#endif + +#include <inttypes.h> + +#include <intprops.h> + +#define UINTMAX_STRSIZE_BOUND INT_BUFSIZE_BOUND (uintmax_t) + +/* Prototypes for external functions. */ + +#if HAVE_LOCALE_H +# include <locale.h> +#endif +#if !HAVE_SETLOCALE +# define setlocale(category, locale) /* empty */ +#endif + +#include <time.h> +#ifdef TIME_WITH_SYS_TIME +# include <sys/time.h> +#endif + +/* Library modules. */ + +#include <dirname.h> +#include <error.h> +#include <savedir.h> +#include <unlocked-io.h> +#include <xalloc.h> + +#include <gettext.h> +#define _(msgid) gettext (msgid) +#define N_(msgid) msgid + +#ifdef HAVE_PWD_H +# include <pwd.h> +#endif +#ifdef HAVE_GRP_H +# include <grp.h> +#endif + +#if MSDOS +# include <process.h> +# define SET_BINARY_MODE(arc) setmode(arc, O_BINARY) +# define ERRNO_IS_EACCES errno == EACCES +# define mkdir(file, mode) (mkdir) (file) +# define TTY_NAME "con" +# define sys_reset_uid_gid() +#else +# define SET_BINARY_MODE(arc) +# define ERRNO_IS_EACCES 0 +# define TTY_NAME "/dev/tty" +# define sys_reset_uid_gid() \ + do { \ + if (! (setuid (getuid ()) == 0 && setgid (getgid ()) == 0)) \ + abort (); \ + } while (0) +#endif + +#if XENIX +# include <sys/inode.h> +#endif diff --git a/lib/wordsplit.c b/lib/wordsplit.c new file mode 100644 index 0000000..0653785 --- /dev/null +++ b/lib/wordsplit.c @@ -0,0 +1,1628 @@ +/* wordsplit - a word splitter + Copyright (C) 2009-2014, 2016 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by the + Free Software Foundation; either version 3 of the License, or (at your + option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program. If not, see <http://www.gnu.org/licenses/>. + + Written by Sergey Poznyakoff +*/ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#include <errno.h> +#include <ctype.h> +#include <unistd.h> +#include <stdlib.h> +#include <string.h> +#include <stdio.h> +#include <stdarg.h> + +#if ENABLE_NLS +# include <gettext.h> +#else +# define gettext(msgid) msgid +#endif +#define _(msgid) gettext (msgid) +#define N_(msgid) msgid + +#include <wordsplit.h> + +#define ISWS(c) ((c)==' '||(c)=='\t'||(c)=='\n') +#define ISDELIM(ws,c) \ + (strchr ((ws)->ws_delim, (c)) != NULL) +#define ISPUNCT(c) (strchr("!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~",(c))!=NULL) +#define ISUPPER(c) ('A' <= ((unsigned) (c)) && ((unsigned) (c)) <= 'Z') +#define ISLOWER(c) ('a' <= ((unsigned) (c)) && ((unsigned) (c)) <= 'z') +#define ISALPHA(c) (ISUPPER(c) || ISLOWER(c)) +#define ISDIGIT(c) ('0' <= ((unsigned) (c)) && ((unsigned) (c)) <= '9') +#define ISXDIGIT(c) (strchr("abcdefABCDEF", c)!=NULL) +#define ISALNUM(c) (ISALPHA(c) || ISDIGIT(c)) +#define ISPRINT(c) (' ' <= ((unsigned) (c)) && ((unsigned) (c)) <= 127) + +#define ALLOC_INIT 128 +#define ALLOC_INCR 128 + +static void +_wsplt_alloc_die (struct wordsplit *wsp) +{ + wsp->ws_error (_("memory exhausted")); + abort (); +} + +static void __WORDSPLIT_ATTRIBUTE_FORMAT ((__printf__, 1, 2)) +_wsplt_error (const char *fmt, ...) +{ + va_list ap; + + va_start (ap, fmt); + vfprintf (stderr, fmt, ap); + va_end (ap); + fputc ('\n', stderr); +} + +static void wordsplit_free_nodes (struct wordsplit *); + +static int +_wsplt_nomem (struct wordsplit *wsp) +{ + errno = ENOMEM; + wsp->ws_errno = WRDSE_NOSPACE; + if (wsp->ws_flags & WRDSF_ENOMEMABRT) + wsp->ws_alloc_die (wsp); + if (wsp->ws_flags & WRDSF_SHOWERR) + wordsplit_perror (wsp); + if (!(wsp->ws_flags & WRDSF_REUSE)) + wordsplit_free (wsp); + wordsplit_free_nodes (wsp); + return wsp->ws_errno; +} + +static void +wordsplit_init0 (struct wordsplit *wsp) +{ + if (wsp->ws_flags & WRDSF_REUSE) + { + if (!(wsp->ws_flags & WRDSF_APPEND)) + wordsplit_free_words (wsp); + } + else + { + wsp->ws_wordv = NULL; + wsp->ws_wordc = 0; + wsp->ws_wordn = 0; + } + + wsp->ws_errno = 0; + wsp->ws_head = wsp->ws_tail = NULL; +} + +static int +wordsplit_init (struct wordsplit *wsp, const char *input, size_t len, + int flags) +{ + wsp->ws_flags = flags; + + if (!(wsp->ws_flags & WRDSF_ALLOC_DIE)) + wsp->ws_alloc_die = _wsplt_alloc_die; + if (!(wsp->ws_flags & WRDSF_ERROR)) + wsp->ws_error = _wsplt_error; + + if (!(wsp->ws_flags & WRDSF_NOVAR) + && !(wsp->ws_flags & (WRDSF_ENV | WRDSF_GETVAR))) + { + errno = EINVAL; + wsp->ws_errno = WRDSE_USAGE; + if (wsp->ws_flags & WRDSF_SHOWERR) + wordsplit_perror (wsp); + return wsp->ws_errno; + } + + if (!(wsp->ws_flags & WRDSF_NOCMD)) + { + errno = EINVAL; + wsp->ws_errno = WRDSE_NOSUPP; + if (wsp->ws_flags & WRDSF_SHOWERR) + wordsplit_perror (wsp); + return wsp->ws_errno; + } + + if (wsp->ws_flags & WRDSF_SHOWDBG) + { + if (!(wsp->ws_flags & WRDSF_DEBUG)) + { + if (wsp->ws_flags & WRDSF_ERROR) + wsp->ws_debug = wsp->ws_error; + else if (wsp->ws_flags & WRDSF_SHOWERR) + wsp->ws_debug = _wsplt_error; + else + wsp->ws_flags &= ~WRDSF_SHOWDBG; + } + } + + wsp->ws_input = input; + wsp->ws_len = len; + + if (!(wsp->ws_flags & WRDSF_DOOFFS)) + wsp->ws_offs = 0; + + if (!(wsp->ws_flags & WRDSF_DELIM)) + wsp->ws_delim = " \t\n"; + + if (!(wsp->ws_flags & WRDSF_COMMENT)) + wsp->ws_comment = NULL; + + if (!(wsp->ws_flags & WRDSF_CLOSURE)) + wsp->ws_closure = NULL; + + wsp->ws_endp = 0; + + wordsplit_init0 (wsp); + + return 0; +} + +static int +alloc_space (struct wordsplit *wsp, size_t count) +{ + size_t offs = (wsp->ws_flags & WRDSF_DOOFFS) ? wsp->ws_offs : 0; + char **ptr; + size_t newalloc; + + if (wsp->ws_wordv == NULL) + { + newalloc = offs + count > ALLOC_INIT ? count : ALLOC_INIT; + ptr = calloc (newalloc, sizeof (ptr[0])); + } + else if (wsp->ws_wordn < offs + wsp->ws_wordc + count) + { + newalloc = offs + wsp->ws_wordc + + (count > ALLOC_INCR ? count : ALLOC_INCR); + ptr = realloc (wsp->ws_wordv, newalloc * sizeof (ptr[0])); + } + else + return 0; + + if (ptr) + { + wsp->ws_wordn = newalloc; + wsp->ws_wordv = ptr; + } + else + return _wsplt_nomem (wsp); + return 0; +} + + +/* Node state flags */ +#define _WSNF_NULL 0x01 /* null node (a noop) */ +#define _WSNF_WORD 0x02 /* node contains word in v.word */ +#define _WSNF_QUOTE 0x04 /* text is quoted */ +#define _WSNF_NOEXPAND 0x08 /* text is not subject to expansion */ +#define _WSNF_JOIN 0x10 /* node must be joined with the next node */ +#define _WSNF_SEXP 0x20 /* is a sed expression */ + +#define _WSNF_EMPTYOK 0x0100 /* special flag indicating that + wordsplit_add_segm must add the + segment even if it is empty */ + +struct wordsplit_node +{ + struct wordsplit_node *prev; /* Previous element */ + struct wordsplit_node *next; /* Next element */ + unsigned flags; /* Node flags */ + union + { + struct + { + size_t beg; /* Start of word in ws_input */ + size_t end; /* End of word in ws_input */ + } segm; + char *word; + } v; +}; + +static const char * +wsnode_flagstr (int flags) +{ + static char retbuf[6]; + char *p = retbuf; + + if (flags & _WSNF_WORD) + *p++ = 'w'; + else if (flags & _WSNF_NULL) + *p++ = 'n'; + else + *p++ = '-'; + if (flags & _WSNF_QUOTE) + *p++ = 'q'; + else + *p++ = '-'; + if (flags & _WSNF_NOEXPAND) + *p++ = 'E'; + else + *p++ = '-'; + if (flags & _WSNF_JOIN) + *p++ = 'j'; + else + *p++ = '-'; + if (flags & _WSNF_SEXP) + *p++ = 's'; + else + *p++ = '-'; + *p = 0; + return retbuf; +} + +static const char * +wsnode_ptr (struct wordsplit *wsp, struct wordsplit_node *p) +{ + if (p->flags & _WSNF_NULL) + return ""; + else if (p->flags & _WSNF_WORD) + return p->v.word; + else + return wsp->ws_input + p->v.segm.beg; +} + +static size_t +wsnode_len (struct wordsplit_node *p) +{ + if (p->flags & _WSNF_NULL) + return 0; + else if (p->flags & _WSNF_WORD) + return strlen (p->v.word); + else + return p->v.segm.end - p->v.segm.beg; +} + +static int +wsnode_new (struct wordsplit *wsp, struct wordsplit_node **pnode) +{ + struct wordsplit_node *node = calloc (1, sizeof (*node)); + if (!node) + return _wsplt_nomem (wsp); + *pnode = node; + return 0; +} + +static void +wsnode_free (struct wordsplit_node *p) +{ + if (p->flags & _WSNF_WORD) + free (p->v.word); + free (p); +} + +static void +wsnode_append (struct wordsplit *wsp, struct wordsplit_node *node) +{ + node->next = NULL; + node->prev = wsp->ws_tail; + if (wsp->ws_tail) + wsp->ws_tail->next = node; + else + wsp->ws_head = node; + wsp->ws_tail = node; +} + +static void +wsnode_remove (struct wordsplit *wsp, struct wordsplit_node *node) +{ + struct wordsplit_node *p; + + p = node->prev; + if (p) + { + p->next = node->next; + if (!node->next) + p->flags &= ~_WSNF_JOIN; + } + else + wsp->ws_head = node->next; + + p = node->next; + if (p) + p->prev = node->prev; + else + wsp->ws_tail = node->prev; + + node->next = node->prev = NULL; +} + +static void +wsnode_insert (struct wordsplit *wsp, struct wordsplit_node *node, + struct wordsplit_node *anchor, int before) +{ + if (!wsp->ws_head) + { + node->next = node->prev = NULL; + wsp->ws_head = wsp->ws_tail = node; + } + else if (before) + { + if (anchor->prev) + wsnode_insert (wsp, node, anchor->prev, 0); + else + { + node->prev = NULL; + node->next = anchor; + anchor->prev = node; + wsp->ws_head = node; + } + } + else + { + struct wordsplit_node *p; + + p = anchor->next; + if (p) + p->prev = node; + else + wsp->ws_tail = node; + node->next = p; + node->prev = anchor; + anchor->next = node; + } +} + +static int +wordsplit_add_segm (struct wordsplit *wsp, size_t beg, size_t end, int flg) +{ + struct wordsplit_node *node; + int rc; + + if (end == beg && !(flg & _WSNF_EMPTYOK)) + return 0; + rc = wsnode_new (wsp, &node); + if (rc) + return rc; + node->flags = flg & ~(_WSNF_WORD | _WSNF_EMPTYOK); + node->v.segm.beg = beg; + node->v.segm.end = end; + wsnode_append (wsp, node); + return 0; +} + +static void +wordsplit_free_nodes (struct wordsplit *wsp) +{ + struct wordsplit_node *p; + + for (p = wsp->ws_head; p;) + { + struct wordsplit_node *next = p->next; + wsnode_free (p); + p = next; + } + wsp->ws_head = wsp->ws_tail = NULL; +} + +static void +wordsplit_dump_nodes (struct wordsplit *wsp) +{ + struct wordsplit_node *p; + int n = 0; + + for (p = wsp->ws_head, n = 0; p; p = p->next, n++) + { + if (p->flags & _WSNF_WORD) + wsp->ws_debug ("%4d: %p: %#04x (%s):%s;", + n, p, p->flags, wsnode_flagstr (p->flags), p->v.word); + else + wsp->ws_debug ("%4d: %p: %#04x (%s):%.*s;", + n, p, p->flags, wsnode_flagstr (p->flags), + (int) (p->v.segm.end - p->v.segm.beg), + wsp->ws_input + p->v.segm.beg); + } +} + +static int +coalesce_segment (struct wordsplit *wsp, struct wordsplit_node *node) +{ + struct wordsplit_node *p, *end; + size_t len = 0; + char *buf, *cur; + int stop; + + for (p = node; p && (p->flags & _WSNF_JOIN); p = p->next) + { + len += wsnode_len (p); + } + len += wsnode_len (p); + end = p; + + buf = malloc (len + 1); + if (!buf) + return _wsplt_nomem (wsp); + cur = buf; + + p = node; + for (stop = 0; !stop;) + { + struct wordsplit_node *next = p->next; + const char *str = wsnode_ptr (wsp, p); + size_t slen = wsnode_len (p); + + memcpy (cur, str, slen); + cur += slen; + if (p != node) + { + wsnode_remove (wsp, p); + stop = p == end; + wsnode_free (p); + } + p = next; + } + + *cur = 0; + + node->flags &= ~_WSNF_JOIN; + + if (node->flags & _WSNF_WORD) + free (node->v.word); + else + node->flags |= _WSNF_WORD; + node->v.word = buf; + return 0; +} + +static int +wsnode_quoteremoval (struct wordsplit *wsp) +{ + struct wordsplit_node *p; + void (*uqfn) (char *, const char *, size_t) = + (wsp->ws_flags & WRDSF_CESCAPES) ? + wordsplit_c_unquote_copy : wordsplit_sh_unquote_copy; + + for (p = wsp->ws_head; p; p = p->next) + { + const char *str = wsnode_ptr (wsp, p); + size_t slen = wsnode_len (p); + int unquote; + + if (wsp->ws_flags & WRDSF_QUOTE) + { + unquote = !(p->flags & _WSNF_NOEXPAND); + } + else + unquote = 0; + + if (unquote) + { + if (!(p->flags & _WSNF_WORD)) + { + char *newstr = malloc (slen + 1); + if (!newstr) + return _wsplt_nomem (wsp); + memcpy (newstr, str, slen); + newstr[slen] = 0; + p->v.word = newstr; + p->flags |= _WSNF_WORD; + } + + if (wsp->ws_flags & WRDSF_ESCAPE) + wordsplit_general_unquote_copy (p->v.word, str, slen, + wsp->ws_escape); + else + uqfn (p->v.word, str, slen); + } + } + return 0; +} + +static int +wsnode_coalesce (struct wordsplit *wsp) +{ + struct wordsplit_node *p; + + for (p = wsp->ws_head; p; p = p->next) + { + if (p->flags & _WSNF_JOIN) + if (coalesce_segment (wsp, p)) + return 1; + } + return 0; +} + +static int +wordsplit_finish (struct wordsplit *wsp) +{ + struct wordsplit_node *p; + size_t n; + + n = 0; + + for (p = wsp->ws_head; p; p = p->next) + n++; + + if (alloc_space (wsp, n + 1)) + return 1; + + for (p = wsp->ws_head; p; p = p->next) + { + const char *str = wsnode_ptr (wsp, p); + size_t slen = wsnode_len (p); + char *newstr = malloc (slen + 1); + + /* Assign newstr first, even if it is NULL. This way + wordsplit_free will work even if we return + nomem later. */ + wsp->ws_wordv[wsp->ws_offs + wsp->ws_wordc] = newstr; + if (!newstr) + return _wsplt_nomem (wsp); + memcpy (newstr, str, slen); + newstr[slen] = 0; + + wsp->ws_wordc++; + + } + wsp->ws_wordv[wsp->ws_offs + wsp->ws_wordc] = NULL; + return 0; +} + + +/* Variable expansion */ +static int +node_split_prefix (struct wordsplit *wsp, + struct wordsplit_node **ptail, + struct wordsplit_node *node, + size_t beg, size_t len, int flg) +{ + struct wordsplit_node *newnode; + + if (len == 0) + return 0; + if (wsnode_new (wsp, &newnode)) + return 1; + wsnode_insert (wsp, newnode, *ptail, 0); + if (node->flags & _WSNF_WORD) + { + const char *str = wsnode_ptr (wsp, node); + char *newstr = malloc (len + 1); + if (!newstr) + return _wsplt_nomem (wsp); + memcpy (newstr, str + beg, len); + newstr[len] = 0; + newnode->flags = _WSNF_WORD; + newnode->v.word = newstr; + } + else + { + newnode->v.segm.beg = node->v.segm.beg + beg; + newnode->v.segm.end = newnode->v.segm.beg + len; + } + newnode->flags |= flg; + *ptail = newnode; + return 0; +} + +static int +find_closing_cbrace (const char *str, size_t i, size_t len, size_t * poff) +{ + enum + { st_init, st_squote, st_dquote } state = st_init; + size_t level = 1; + + for (; i < len; i++) + { + switch (state) + { + case st_init: + switch (str[i]) + { + case '{': + level++; + break; + + case '}': + if (--level == 0) + { + *poff = i; + return 0; + } + break; + + case '"': + state = st_dquote; + break; + + case '\'': + state = st_squote; + break; + } + break; + + case st_squote: + if (str[i] == '\'') + state = st_init; + break; + + case st_dquote: + if (str[i] == '\\') + i++; + else if (str[i] == '"') + state = st_init; + break; + } + } + return 1; +} + +static const char * +wordsplit_find_env (struct wordsplit *wsp, const char *name, size_t len) +{ + size_t i; + + if (!(wsp->ws_flags & WRDSF_ENV)) + return NULL; + + if (wsp->ws_flags & WRDSF_ENV_KV) + { + /* A key-value pair environment */ + for (i = 0; wsp->ws_env[i]; i++) + { + size_t elen = strlen (wsp->ws_env[i]); + if (elen == len && memcmp (wsp->ws_env[i], name, elen) == 0) + return wsp->ws_env[i + 1]; + /* Skip the value. Break the loop if it is NULL. */ + i++; + if (wsp->ws_env[i] == NULL) + break; + } + } + else + { + /* Usual (A=B) environment. */ + for (i = 0; wsp->ws_env[i]; i++) + { + size_t j; + const char *var = wsp->ws_env[i]; + + for (j = 0; j < len; j++) + if (name[j] != var[j]) + break; + if (j == len && var[j] == '=') + return var + j + 1; + } + } + return NULL; +} + +static int +expvar (struct wordsplit *wsp, const char *str, size_t len, + struct wordsplit_node **ptail, const char **pend, int flg) +{ + size_t i = 0; + const char *defstr = NULL; + const char *value; + const char *vptr; + struct wordsplit_node *newnode; + const char *start = str - 1; + + if (ISALPHA (str[0]) || str[0] == '_') + { + for (i = 1; i < len; i++) + if (!(ISALNUM (str[i]) || str[i] == '_')) + break; + *pend = str + i - 1; + } + else if (str[0] == '{') + { + str++; + len--; + for (i = 1; i < len; i++) + if (str[i] == '}' || str[i] == ':') + break; + if (str[i] == ':') + { + size_t j; + + defstr = str + i + 1; + if (find_closing_cbrace (str, i + 1, len, &j)) + { + wsp->ws_errno = WRDSE_CBRACE; + return 1; + } + *pend = str + j; + } + else if (str[i] == '}') + { + defstr = NULL; + *pend = str + i; + } + else + { + wsp->ws_errno = WRDSE_CBRACE; + return 1; + } + } + else + { + if (wsnode_new (wsp, &newnode)) + return 1; + wsnode_insert (wsp, newnode, *ptail, 0); + *ptail = newnode; + newnode->flags = _WSNF_WORD | flg; + newnode->v.word = malloc (3); + if (!newnode->v.word) + return _wsplt_nomem (wsp); + newnode->v.word[0] = '$'; + newnode->v.word[1] = str[0]; + newnode->v.word[2] = 0; + *pend = str; + return 0; + } + + /* Actually expand the variable */ + /* str - start of the variable name + i - its length + defstr - default replacement str */ + + vptr = wordsplit_find_env (wsp, str, i); + if (vptr) + { + value = strdup (vptr); + if (!value) + return _wsplt_nomem (wsp); + } + else if (wsp->ws_flags & WRDSF_GETVAR) + value = wsp->ws_getvar (str, i, wsp->ws_closure); + else if (wsp->ws_flags & WRDSF_UNDEF) + { + wsp->ws_errno = WRDSE_UNDEF; + if (wsp->ws_flags & WRDSF_SHOWERR) + wordsplit_perror (wsp); + return 1; + } + else + { + if (wsp->ws_flags & WRDSF_WARNUNDEF) + wsp->ws_error (_("warning: undefined variable `%.*s'"), (int) i, str); + if (wsp->ws_flags & WRDSF_KEEPUNDEF) + value = NULL; + else + value = ""; + } + + /* FIXME: handle defstr */ + (void) defstr; + + if (value) + { + if (flg & _WSNF_QUOTE) + { + if (wsnode_new (wsp, &newnode)) + return 1; + wsnode_insert (wsp, newnode, *ptail, 0); + *ptail = newnode; + newnode->flags = _WSNF_WORD | _WSNF_NOEXPAND | flg; + newnode->v.word = strdup (value); + if (!newnode->v.word) + return _wsplt_nomem (wsp); + } + else if (*value == 0) + { + /* Empty string is a special case */ + if (wsnode_new (wsp, &newnode)) + return 1; + wsnode_insert (wsp, newnode, *ptail, 0); + *ptail = newnode; + newnode->flags = _WSNF_NULL; + } + else + { + struct wordsplit ws; + int i; + + ws.ws_delim = wsp->ws_delim; + if (wordsplit (value, &ws, + WRDSF_NOVAR | WRDSF_NOCMD | WRDSF_DELIM | WRDSF_WS)) + { + wordsplit_free (&ws); + return 1; + } + for (i = 0; i < ws.ws_wordc; i++) + { + if (wsnode_new (wsp, &newnode)) + return 1; + wsnode_insert (wsp, newnode, *ptail, 0); + *ptail = newnode; + newnode->flags = _WSNF_WORD | + _WSNF_NOEXPAND | + (i + 1 < ws.ws_wordc ? (flg & ~_WSNF_JOIN) : flg); + newnode->v.word = strdup (ws.ws_wordv[i]); + if (!newnode->v.word) + return _wsplt_nomem (wsp); + } + wordsplit_free (&ws); + } + } + else if (wsp->ws_flags & WRDSF_KEEPUNDEF) + { + size_t size = *pend - start + 1; + + if (wsnode_new (wsp, &newnode)) + return 1; + wsnode_insert (wsp, newnode, *ptail, 0); + *ptail = newnode; + newnode->flags = _WSNF_WORD | _WSNF_NOEXPAND | flg; + newnode->v.word = malloc (size + 1); + if (!newnode->v.word) + return _wsplt_nomem (wsp); + memcpy (newnode->v.word, start, size); + newnode->v.word[size] = 0; + } + else + { + if (wsnode_new (wsp, &newnode)) + return 1; + wsnode_insert (wsp, newnode, *ptail, 0); + *ptail = newnode; + newnode->flags = _WSNF_NULL; + } + return 0; +} + +static int +node_expand_vars (struct wordsplit *wsp, struct wordsplit_node *node) +{ + const char *str = wsnode_ptr (wsp, node); + size_t slen = wsnode_len (node); + const char *end = str + slen; + const char *p; + size_t off = 0; + struct wordsplit_node *tail = node; + + for (p = str; p < end; p++) + { + if (*p == '\\') + { + p++; + continue; + } + if (*p == '$') + { + size_t n = p - str; + + if (tail != node) + tail->flags |= _WSNF_JOIN; + if (node_split_prefix (wsp, &tail, node, off, n, _WSNF_JOIN)) + return 1; + p++; + if (expvar (wsp, p, slen - n, &tail, &p, + node->flags & (_WSNF_JOIN | _WSNF_QUOTE))) + return 1; + off += p - str + 1; + str = p + 1; + } + } + if (p > str) + { + if (tail != node) + tail->flags |= _WSNF_JOIN; + if (node_split_prefix (wsp, &tail, node, off, p - str, + node->flags & _WSNF_JOIN)) + return 1; + } + if (tail != node) + { + wsnode_remove (wsp, node); + wsnode_free (node); + } + return 0; +} + +/* Remove NULL lists */ +static void +wsnode_nullelim (struct wordsplit *wsp) +{ + struct wordsplit_node *p; + + for (p = wsp->ws_head; p;) + { + struct wordsplit_node *next = p->next; + if (p->flags & _WSNF_NULL) + { + wsnode_remove (wsp, p); + wsnode_free (p); + } + p = next; + } +} + +static int +wordsplit_varexp (struct wordsplit *wsp) +{ + struct wordsplit_node *p; + + for (p = wsp->ws_head; p;) + { + struct wordsplit_node *next = p->next; + if (!(p->flags & _WSNF_NOEXPAND)) + if (node_expand_vars (wsp, p)) + return 1; + p = next; + } + + wsnode_nullelim (wsp); + return 0; +} + +/* Strip off any leading and trailing whitespace. This function is called + right after the initial scanning, therefore it assumes that every + node in the list is a text reference node. */ +static void +wordsplit_trimws (struct wordsplit *wsp) +{ + struct wordsplit_node *p; + + for (p = wsp->ws_head; p; p = p->next) + { + size_t n; + + if (p->flags & _WSNF_QUOTE) + continue; + + /* Skip leading whitespace: */ + for (n = p->v.segm.beg; n < p->v.segm.end && ISWS (wsp->ws_input[n]); + n++) + ; + p->v.segm.beg = n; + /* Trim trailing whitespace */ + for (n = p->v.segm.end; + n > p->v.segm.beg && ISWS (wsp->ws_input[n - 1]); n--); + p->v.segm.end = n; + if (p->v.segm.beg == p->v.segm.end) + p->flags |= _WSNF_NULL; + } + + wsnode_nullelim (wsp); +} + +static int +skip_sed_expr (const char *command, size_t i, size_t len) +{ + int state; + + do + { + int delim; + + if (command[i] == ';') + i++; + if (!(command[i] == 's' && i + 3 < len && ISPUNCT (command[i + 1]))) + break; + + delim = command[++i]; + state = 1; + for (i++; i < len; i++) + { + if (state == 3) + { + if (command[i] == delim || !ISALNUM (command[i])) + break; + } + else if (command[i] == '\\') + i++; + else if (command[i] == delim) + state++; + } + } + while (state == 3 && i < len && command[i] == ';'); + return i; +} + +static size_t +skip_delim (struct wordsplit *wsp) +{ + size_t start = wsp->ws_endp; + if (wsp->ws_flags & WRDSF_SQUEEZE_DELIMS) + { + if ((wsp->ws_flags & WRDSF_RETURN_DELIMS) && + ISDELIM (wsp, wsp->ws_input[start])) + { + int delim = wsp->ws_input[start]; + do + start++; + while (start < wsp->ws_len && delim == wsp->ws_input[start]); + } + else + { + do + start++; + while (start < wsp->ws_len && ISDELIM (wsp, wsp->ws_input[start])); + } + start--; + } + + if (!(wsp->ws_flags & WRDSF_RETURN_DELIMS)) + start++; + + return start; +} + +#define _WRDS_EOF 0 +#define _WRDS_OK 1 +#define _WRDS_ERR 2 + +static int +scan_qstring (struct wordsplit *wsp, size_t start, size_t * end) +{ + size_t j; + const char *command = wsp->ws_input; + size_t len = wsp->ws_len; + char q = command[start]; + + for (j = start + 1; j < len && command[j] != q; j++) + if (q == '"' && command[j] == '\\') + j++; + if (j < len && command[j] == q) + { + int flags = _WSNF_QUOTE | _WSNF_EMPTYOK; + if (q == '\'') + flags |= _WSNF_NOEXPAND; + if (wordsplit_add_segm (wsp, start + 1, j, flags)) + return _WRDS_ERR; + *end = j; + } + else + { + wsp->ws_endp = start; + wsp->ws_errno = WRDSE_QUOTE; + if (wsp->ws_flags & WRDSF_SHOWERR) + wordsplit_perror (wsp); + return _WRDS_ERR; + } + return 0; +} + +static int +scan_word (struct wordsplit *wsp, size_t start) +{ + size_t len = wsp->ws_len; + const char *command = wsp->ws_input; + const char *comment = wsp->ws_comment; + int join = 0; + int flags = 0; + + size_t i = start; + + if (i >= len) + { + wsp->ws_errno = WRDSE_EOF; + return _WRDS_EOF; + } + + start = i; + + if (wsp->ws_flags & WRDSF_SED_EXPR + && command[i] == 's' && i + 3 < len && ISPUNCT (command[i + 1])) + { + flags = _WSNF_SEXP; + i = skip_sed_expr (command, i, len); + } + else if (!ISDELIM (wsp, command[i])) + { + while (i < len) + { + if (comment && strchr (comment, command[i]) != NULL) + { + size_t j; + for (j = i + 1; j < len && command[j] != '\n'; j++) + ; + if (wordsplit_add_segm (wsp, start, i, 0)) + return _WRDS_ERR; + wsp->ws_endp = j; + return _WRDS_OK; + } + + if (wsp->ws_flags & WRDSF_QUOTE) + { + if (command[i] == '\\') + { + if (++i == len) + break; + i++; + continue; + } + + if (((wsp->ws_flags & WRDSF_SQUOTE) && command[i] == '\'') || + ((wsp->ws_flags & WRDSF_DQUOTE) && command[i] == '"')) + { + if (join && wsp->ws_tail) + wsp->ws_tail->flags |= _WSNF_JOIN; + if (wordsplit_add_segm (wsp, start, i, _WSNF_JOIN)) + return _WRDS_ERR; + if (scan_qstring (wsp, i, &i)) + return _WRDS_ERR; + start = i + 1; + join = 1; + } + } + + if (ISDELIM (wsp, command[i])) + break; + else + i++; + } + } + else if (wsp->ws_flags & WRDSF_RETURN_DELIMS) + { + i++; + } + else if (!(wsp->ws_flags & WRDSF_SQUEEZE_DELIMS)) + flags |= _WSNF_EMPTYOK; + + if (join && i > start && wsp->ws_tail) + wsp->ws_tail->flags |= _WSNF_JOIN; + if (wordsplit_add_segm (wsp, start, i, flags)) + return _WRDS_ERR; + wsp->ws_endp = i; + if (wsp->ws_flags & WRDSF_INCREMENTAL) + return _WRDS_EOF; + return _WRDS_OK; +} + +static char quote_transtab[] = "\\\\\"\"a\ab\bf\fn\nr\rt\tv\v"; + +int +wordsplit_c_unquote_char (int c) +{ + char *p; + + for (p = quote_transtab; *p; p += 2) + { + if (*p == c) + return p[1]; + } + return c; +} + +int +wordsplit_c_quote_char (int c) +{ + char *p; + + for (p = quote_transtab + sizeof (quote_transtab) - 2; + p > quote_transtab; p -= 2) + { + if (*p == c) + return p[-1]; + } + return -1; +} + +#define to_num(c) \ + (ISDIGIT(c) ? c - '0' : (ISXDIGIT(c) ? toupper(c) - 'A' + 10 : 255 )) + +static int +xtonum (int *pval, const char *src, int base, int cnt) +{ + int i, val; + + for (i = 0, val = 0; i < cnt; i++, src++) + { + int n = *(unsigned char *) src; + if (n > 127 || (n = to_num (n)) >= base) + break; + val = val * base + n; + } + *pval = val; + return i; +} + +size_t +wordsplit_c_quoted_length (const char *str, int quote_hex, int *quote) +{ + size_t len = 0; + + *quote = 0; + for (; *str; str++) + { + if (strchr (" \"", *str)) + *quote = 1; + + if (*str == ' ') + len++; + else if (*str == '"') + len += 2; + else if (*str != '\t' && *str != '\\' && ISPRINT (*str)) + len++; + else if (quote_hex) + len += 3; + else + { + if (wordsplit_c_quote_char (*str) != -1) + len += 2; + else + len += 4; + } + } + return len; +} + +void +wordsplit_general_unquote_copy (char *dst, const char *src, size_t n, + const char *escapable) +{ + int i; + + for (i = 0; i < n;) + { + if (src[i] == '\\' && i < n && strchr (escapable, src[i + 1])) + i++; + *dst++ = src[i++]; + } + *dst = 0; +} + +void +wordsplit_sh_unquote_copy (char *dst, const char *src, size_t n) +{ + int i; + + for (i = 0; i < n;) + { + if (src[i] == '\\') + i++; + *dst++ = src[i++]; + } + *dst = 0; +} + +void +wordsplit_c_unquote_copy (char *dst, const char *src, size_t n) +{ + int i = 0; + int c; + + while (i < n) + { + if (src[i] == '\\') + { + ++i; + if (src[i] == 'x' || src[i] == 'X') + { + if (n - i < 2) + { + *dst++ = '\\'; + *dst++ = src[i++]; + } + else + { + int off = xtonum (&c, src + i + 1, + 16, 2); + if (off == 0) + { + *dst++ = '\\'; + *dst++ = src[i++]; + } + else + { + *dst++ = c; + i += off + 1; + } + } + } + else if ((unsigned char) src[i] < 128 && ISDIGIT (src[i])) + { + if (n - i < 1) + { + *dst++ = '\\'; + *dst++ = src[i++]; + } + else + { + int off = xtonum (&c, src + i, 8, 3); + if (off == 0) + { + *dst++ = '\\'; + *dst++ = src[i++]; + } + else + { + *dst++ = c; + i += off; + } + } + } + else + *dst++ = wordsplit_c_unquote_char (src[i++]); + } + else + *dst++ = src[i++]; + } + *dst = 0; +} + +void +wordsplit_c_quote_copy (char *dst, const char *src, int quote_hex) +{ + for (; *src; src++) + { + if (*src == '"') + { + *dst++ = '\\'; + *dst++ = *src; + } + else if (*src != '\t' && *src != '\\' && ISPRINT (*src)) + *dst++ = *src; + else + { + char tmp[4]; + + if (quote_hex) + { + snprintf (tmp, sizeof tmp, "%%%02X", *(unsigned char *) src); + memcpy (dst, tmp, 3); + dst += 3; + } + else + { + int c = wordsplit_c_quote_char (*src); + *dst++ = '\\'; + if (c != -1) + *dst++ = c; + else + { + snprintf (tmp, sizeof tmp, "%03o", *(unsigned char *) src); + memcpy (dst, tmp, 3); + dst += 3; + } + } + } + } +} + +static int +wordsplit_process_list (struct wordsplit *wsp, size_t start) +{ + if (wsp->ws_flags & WRDSF_NOSPLIT) + { + /* Treat entire input as a quoted argument */ + if (wordsplit_add_segm (wsp, start, wsp->ws_len, _WSNF_QUOTE)) + return wsp->ws_errno; + } + else + { + int rc; + + while ((rc = scan_word (wsp, start)) == _WRDS_OK) + start = skip_delim (wsp); + /* Make sure tail element is not joinable */ + if (wsp->ws_tail) + wsp->ws_tail->flags &= ~_WSNF_JOIN; + if (rc == _WRDS_ERR) + return wsp->ws_errno; + } + + if (wsp->ws_flags & WRDSF_SHOWDBG) + { + wsp->ws_debug ("Initial list:"); + wordsplit_dump_nodes (wsp); + } + + if (wsp->ws_flags & WRDSF_WS) + { + /* Trim leading and trailing whitespace */ + wordsplit_trimws (wsp); + if (wsp->ws_flags & WRDSF_SHOWDBG) + { + wsp->ws_debug ("After WS trimming:"); + wordsplit_dump_nodes (wsp); + } + } + + /* Expand variables (FIXME: & commands) */ + if (!(wsp->ws_flags & WRDSF_NOVAR)) + { + if (wordsplit_varexp (wsp)) + { + wordsplit_free_nodes (wsp); + return wsp->ws_errno; + } + if (wsp->ws_flags & WRDSF_SHOWDBG) + { + wsp->ws_debug ("Expanded list:"); + wordsplit_dump_nodes (wsp); + } + } + + do + { + if (wsnode_quoteremoval (wsp)) + break; + if (wsp->ws_flags & WRDSF_SHOWDBG) + { + wsp->ws_debug ("After quote removal:"); + wordsplit_dump_nodes (wsp); + } + + if (wsnode_coalesce (wsp)) + break; + + if (wsp->ws_flags & WRDSF_SHOWDBG) + { + wsp->ws_debug ("Coalesced list:"); + wordsplit_dump_nodes (wsp); + } + } + while (0); + return wsp->ws_errno; +} + +int +wordsplit_len (const char *command, size_t length, struct wordsplit *wsp, + int flags) +{ + int rc; + size_t start; + const char *cmdptr; + size_t cmdlen; + + if (!command) + { + if (!(flags & WRDSF_INCREMENTAL)) + return EINVAL; + + start = skip_delim (wsp); + if (wsp->ws_endp == wsp->ws_len) + { + wsp->ws_errno = WRDSE_NOINPUT; + if (wsp->ws_flags & WRDSF_SHOWERR) + wordsplit_perror (wsp); + return wsp->ws_errno; + } + + cmdptr = wsp->ws_input + wsp->ws_endp; + cmdlen = wsp->ws_len - wsp->ws_endp; + wsp->ws_flags |= WRDSF_REUSE; + wordsplit_init0 (wsp); + } + else + { + cmdptr = command; + cmdlen = length; + start = 0; + rc = wordsplit_init (wsp, cmdptr, cmdlen, flags); + if (rc) + return rc; + } + + if (wsp->ws_flags & WRDSF_SHOWDBG) + wsp->ws_debug ("Input:%.*s;", (int) cmdlen, cmdptr); + + rc = wordsplit_process_list (wsp, start); + if (rc == 0 && (flags & WRDSF_INCREMENTAL)) + { + while (!wsp->ws_head && wsp->ws_endp < wsp->ws_len) + { + start = skip_delim (wsp); + if (wsp->ws_flags & WRDSF_SHOWDBG) + { + cmdptr = wsp->ws_input + wsp->ws_endp; + cmdlen = wsp->ws_len - wsp->ws_endp; + wsp->ws_debug ("Restart:%.*s;", (int) cmdlen, cmdptr); + } + rc = wordsplit_process_list (wsp, start); + if (rc) + break; + } + } + if (rc) + { + wordsplit_free_nodes (wsp); + return rc; + } + wordsplit_finish (wsp); + wordsplit_free_nodes (wsp); + return wsp->ws_errno; +} + +int +wordsplit (const char *command, struct wordsplit *ws, int flags) +{ + return wordsplit_len (command, command ? strlen (command) : 0, ws, + flags); +} + +void +wordsplit_free_words (struct wordsplit *ws) +{ + size_t i; + + for (i = 0; i < ws->ws_wordc; i++) + { + char *p = ws->ws_wordv[ws->ws_offs + i]; + if (p) + { + free (p); + ws->ws_wordv[ws->ws_offs + i] = NULL; + } + } + ws->ws_wordc = 0; +} + +void +wordsplit_free (struct wordsplit *ws) +{ + wordsplit_free_words (ws); + free (ws->ws_wordv); + ws->ws_wordv = NULL; +} + +void +wordsplit_perror (struct wordsplit *wsp) +{ + switch (wsp->ws_errno) + { + case WRDSE_EOF: + wsp->ws_error (_("no error")); + break; + + case WRDSE_QUOTE: + wsp->ws_error (_("missing closing %c (start near #%lu)"), + wsp->ws_input[wsp->ws_endp], + (unsigned long) wsp->ws_endp); + break; + + case WRDSE_NOSPACE: + wsp->ws_error (_("memory exhausted")); + break; + + case WRDSE_NOSUPP: + wsp->ws_error (_("command substitution is not yet supported")); + + case WRDSE_USAGE: + wsp->ws_error (_("invalid wordsplit usage")); + break; + + case WRDSE_CBRACE: + wsp->ws_error (_("unbalanced curly brace")); + break; + + case WRDSE_UNDEF: + wsp->ws_error (_("undefined variable")); + break; + + case WRDSE_NOINPUT: + wsp->ws_error (_("input exhausted")); + break; + + default: + wsp->ws_error (_("unknown error")); + } +} + +const char *_wordsplit_errstr[] = { + N_("no error"), + N_("missing closing quote"), + N_("memory exhausted"), + N_("command substitution is not yet supported"), + N_("invalid wordsplit usage"), + N_("unbalanced curly brace"), + N_("undefined variable"), + N_("input exhausted") +}; +int _wordsplit_nerrs = + sizeof (_wordsplit_errstr) / sizeof (_wordsplit_errstr[0]); + +const char * +wordsplit_strerror (struct wordsplit *ws) +{ + if (ws->ws_errno < _wordsplit_nerrs) + return _wordsplit_errstr[ws->ws_errno]; + return N_("unknown error"); +} diff --git a/lib/wordsplit.h b/lib/wordsplit.h new file mode 100644 index 0000000..e0d2559 --- /dev/null +++ b/lib/wordsplit.h @@ -0,0 +1,168 @@ +/* wordsplit - a word splitter + Copyright (C) 2009-2014, 2016 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by the + Free Software Foundation; either version 3 of the License, or (at your + option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program. If not, see <http://www.gnu.org/licenses/>. + + Written by Sergey Poznyakoff +*/ + +#ifndef __WORDSPLIT_H +#define __WORDSPLIT_H + +#include <stddef.h> + +#if 2 < __GNUC__ + (7 <= __GNUC_MINOR__) +# define __WORDSPLIT_ATTRIBUTE_FORMAT(spec) __attribute__ ((__format__ spec)) +#else +# define __WORDSPLIT_ATTRIBUTE_FORMAT(spec) /* empty */ +#endif + +struct wordsplit +{ + size_t ws_wordc; + char **ws_wordv; + size_t ws_offs; + size_t ws_wordn; + int ws_flags; + const char *ws_delim; + const char *ws_comment; + const char *ws_escape; + void (*ws_alloc_die) (struct wordsplit * wsp); + void (*ws_error) (const char *, ...) + __WORDSPLIT_ATTRIBUTE_FORMAT ((__printf__, 1, 2)); + void (*ws_debug) (const char *, ...) + __WORDSPLIT_ATTRIBUTE_FORMAT ((__printf__, 1, 2)); + + const char **ws_env; + const char *(*ws_getvar) (const char *, size_t, void *); + void *ws_closure; + + const char *ws_input; + size_t ws_len; + size_t ws_endp; + int ws_errno; + struct wordsplit_node *ws_head, *ws_tail; +}; + +/* Wordsplit flags. Only 2 bits of a 32-bit word remain unused. + It is getting crowded... */ +/* Append the words found to the array resulting from a previous + call. */ +#define WRDSF_APPEND 0x00000001 +/* Insert we_offs initial NULLs in the array ws_wordv. + (These are not counted in the returned ws_wordc.) */ +#define WRDSF_DOOFFS 0x00000002 +/* Don't do command substitution. Reserved for future use. */ +#define WRDSF_NOCMD 0x00000004 +/* The parameter p resulted from a previous call to + wordsplit(), and wordsplit_free() was not called. Reuse the + allocated storage. */ +#define WRDSF_REUSE 0x00000008 +/* Print errors */ +#define WRDSF_SHOWERR 0x00000010 +/* Consider it an error if an undefined shell variable + is expanded. */ +#define WRDSF_UNDEF 0x00000020 + +/* Don't do variable expansion. */ +#define WRDSF_NOVAR 0x00000040 +/* Abort on ENOMEM error */ +#define WRDSF_ENOMEMABRT 0x00000080 +/* Trim off any leading and trailind whitespace */ +#define WRDSF_WS 0x00000100 +/* Handle single quotes */ +#define WRDSF_SQUOTE 0x00000200 +/* Handle double quotes */ +#define WRDSF_DQUOTE 0x00000400 +/* Handle quotes and escape directives */ +#define WRDSF_QUOTE (WRDSF_SQUOTE|WRDSF_DQUOTE) +/* Replace each input sequence of repeated delimiters with a single + delimiter */ +#define WRDSF_SQUEEZE_DELIMS 0x00000800 +/* Return delimiters */ +#define WRDSF_RETURN_DELIMS 0x00001000 +/* Treat sed expressions as words */ +#define WRDSF_SED_EXPR 0x00002000 +/* ws_delim field is initialized */ +#define WRDSF_DELIM 0x00004000 +/* ws_comment field is initialized */ +#define WRDSF_COMMENT 0x00008000 +/* ws_alloc_die field is initialized */ +#define WRDSF_ALLOC_DIE 0x00010000 +/* ws_error field is initialized */ +#define WRDSF_ERROR 0x00020000 +/* ws_debug field is initialized */ +#define WRDSF_DEBUG 0x00040000 +/* ws_env field is initialized */ +#define WRDSF_ENV 0x00080000 +/* ws_getvar field is initialized */ +#define WRDSF_GETVAR 0x00100000 +/* enable debugging */ +#define WRDSF_SHOWDBG 0x00200000 +/* Don't split input into words. Useful for side effects. */ +#define WRDSF_NOSPLIT 0x00400000 +/* Keep undefined variables in place, instead of expanding them to + empty string */ +#define WRDSF_KEEPUNDEF 0x00800000 +/* Warn about undefined variables */ +#define WRDSF_WARNUNDEF 0x01000000 +/* Handle C escapes */ +#define WRDSF_CESCAPES 0x02000000 + +/* ws_closure is set */ +#define WRDSF_CLOSURE 0x04000000 +/* ws_env is a Key/Value environment, i.e. the value of a variable is + stored in the element that follows its name. */ +#define WRDSF_ENV_KV 0x08000000 + +/* ws_escape is set */ +#define WRDSF_ESCAPE 0x10000000 + +/* Incremental mode */ +#define WRDSF_INCREMENTAL 0x20000000 + +#define WRDSF_DEFFLAGS \ + (WRDSF_NOVAR | WRDSF_NOCMD | \ + WRDSF_QUOTE | WRDSF_SQUEEZE_DELIMS | WRDSF_CESCAPES) + +#define WRDSE_EOF 0 +#define WRDSE_QUOTE 1 +#define WRDSE_NOSPACE 2 +#define WRDSE_NOSUPP 3 +#define WRDSE_USAGE 4 +#define WRDSE_CBRACE 5 +#define WRDSE_UNDEF 6 +#define WRDSE_NOINPUT 7 + +int wordsplit (const char *s, struct wordsplit *p, int flags); +int wordsplit_len (const char *s, size_t len, + struct wordsplit *p, int flags); +void wordsplit_free (struct wordsplit *p); +void wordsplit_free_words (struct wordsplit *ws); + +int wordsplit_c_unquote_char (int c); +int wordsplit_c_quote_char (int c); +size_t wordsplit_c_quoted_length (const char *str, int quote_hex, + int *quote); +void wordsplit_general_unquote_copy (char *dst, const char *src, size_t n, + const char *escapable); +void wordsplit_sh_unquote_copy (char *dst, const char *src, size_t n); +void wordsplit_c_unquote_copy (char *dst, const char *src, size_t n); +void wordsplit_c_quote_copy (char *dst, const char *src, int quote_hex); + +void wordsplit_perror (struct wordsplit *ws); +const char *wordsplit_strerror (struct wordsplit *ws); + + +#endif diff --git a/lib/xattr-at.c b/lib/xattr-at.c new file mode 100644 index 0000000..1bb48fa --- /dev/null +++ b/lib/xattr-at.c @@ -0,0 +1,114 @@ +/* openat-style fd-relative functions for operating with extended file + attributes. + + Copyright 2012-2014, 2016 Free Software Foundation, Inc. + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +#include <config.h> + +#include "xattr-at.h" +#include "openat.h" + +#include <stdlib.h> +#include <unistd.h> +#include <errno.h> +#include <fcntl.h> + +#include "dirname.h" /* solely for definition of IS_ABSOLUTE_FILE_NAME */ +#include "save-cwd.h" + +#include "openat-priv.h" + +#ifdef HAVE_XATTRS + +/* setxattrat */ +#define AT_FUNC_NAME setxattrat +#define AT_FUNC_F1 setxattr +#define AT_FUNC_POST_FILE_PARAM_DECLS , const char *name, const void *value \ + , size_t size, int flags +#define AT_FUNC_POST_FILE_ARGS , name, value, size, flags +#include "at-func.c" +#undef AT_FUNC_NAME +#undef AT_FUNC_F1 +#undef AT_FUNC_POST_FILE_PARAM_DECLS +#undef AT_FUNC_POST_FILE_ARGS + +/* lsetxattrat */ +#define AT_FUNC_NAME lsetxattrat +#define AT_FUNC_F1 lsetxattr +#define AT_FUNC_POST_FILE_PARAM_DECLS , const char *name, const void *value \ + , size_t size, int flags +#define AT_FUNC_POST_FILE_ARGS , name, value, size, flags +#include "at-func.c" +#undef AT_FUNC_NAME +#undef AT_FUNC_F1 +#undef AT_FUNC_POST_FILE_PARAM_DECLS +#undef AT_FUNC_POST_FILE_ARGS + +/* getxattrat */ +#define AT_FUNC_NAME getxattrat +#define AT_FUNC_RESULT ssize_t +#define AT_FUNC_F1 getxattr +#define AT_FUNC_POST_FILE_PARAM_DECLS , const char *name, void *value \ + , size_t size +#define AT_FUNC_POST_FILE_ARGS , name, value, size +#include "at-func.c" +#undef AT_FUNC_NAME +#undef AT_FUNC_F1 +#undef AT_FUNC_RESULT +#undef AT_FUNC_POST_FILE_PARAM_DECLS +#undef AT_FUNC_POST_FILE_ARGS + +/* lgetxattrat */ +#define AT_FUNC_NAME lgetxattrat +#define AT_FUNC_RESULT ssize_t +#define AT_FUNC_F1 lgetxattr +#define AT_FUNC_POST_FILE_PARAM_DECLS , const char *name, void *value \ + , size_t size +#define AT_FUNC_POST_FILE_ARGS , name, value, size +#include "at-func.c" +#undef AT_FUNC_NAME +#undef AT_FUNC_F1 +#undef AT_FUNC_RESULT +#undef AT_FUNC_POST_FILE_PARAM_DECLS +#undef AT_FUNC_POST_FILE_ARGS + +/* listxattrat */ +#define AT_FUNC_NAME listxattrat +#define AT_FUNC_RESULT ssize_t +#define AT_FUNC_F1 listxattr +#define AT_FUNC_POST_FILE_PARAM_DECLS , char *list , size_t size +#define AT_FUNC_POST_FILE_ARGS , list , size +#include "at-func.c" +#undef AT_FUNC_NAME +#undef AT_FUNC_F1 +#undef AT_FUNC_RESULT +#undef AT_FUNC_POST_FILE_PARAM_DECLS +#undef AT_FUNC_POST_FILE_ARGS + +/* llistxattrat */ +#define AT_FUNC_NAME llistxattrat +#define AT_FUNC_RESULT ssize_t +#define AT_FUNC_F1 llistxattr +#define AT_FUNC_POST_FILE_PARAM_DECLS , char *list , size_t size +#define AT_FUNC_POST_FILE_ARGS , list , size +#include "at-func.c" +#undef AT_FUNC_NAME +#undef AT_FUNC_F1 +#undef AT_FUNC_RESULT +#undef AT_FUNC_POST_FILE_PARAM_DECLS +#undef AT_FUNC_POST_FILE_ARGS + +#endif /* HAVE_XATTRS */ diff --git a/lib/xattr-at.h b/lib/xattr-at.h new file mode 100644 index 0000000..30e52d7 --- /dev/null +++ b/lib/xattr-at.h @@ -0,0 +1,74 @@ +/* Prototypes for openat-style fd-relative functions for operating with + extended file attributes. + + Copyright 2012-2014, 2016 Free Software Foundation, Inc. + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +#ifndef XATTRS_AT_H +#define XATTRS_AT_H + +#include <sys/types.h> +#if defined(HAVE_SYS_XATTR_H) +# include <sys/xattr.h> +#elif defined(HAVE_ATTR_XATTR_H) +# include <attr/xattr.h> +#endif + +#ifndef ENOATTR +# define ENOATTR ENODATA /* No such attribute */ +#endif + +/* These are the dir-fd-relative variants of the functions without the + "at" suffix. For example, setxattrat (AT_FDCWD, path, name, value, size, + flags &c) is usually equivalent to setxattr (file, name, value, size, + flags). For more info use the setxattr(2), getxattr(2) or listxattr(2) + manpages. */ + +/* dir-fd-relative setxattr. Operation sets the VALUE of the extended + attribute identified by NAME and associated with the given PATH in the + filesystem relatively to directory identified by DIR_FD. See the + setxattr(2) manpage for the description of all parameters. */ +int setxattrat (int dir_fd, const char *path, const char *name, + const void *value, size_t size, int flags); + +/* dir-fd-relative lsetxattr. This function is just like setxattrat, + except when DIR_FD and FILE specify a symlink: lsetxattrat operates on the + symlink, while the setxattrat operates on the referent of the symlink. */ +int lsetxattrat (int dir_fd, const char *path, const char *name, + const void *value, size_t size, int flags); + +/* dir-fd-relative getxattr. Operation gets the VALUE of the extended + attribute idenfified by NAME and associated with the given PATH in the + filesystem relatively to directory identified by DIR_FD. For more info + about all parameters see the getxattr(2) manpage. */ +ssize_t getxattrat (int dir_fd, const char *path, const char *name, + void *value, size_t size); + +/* dir-fd-relative lgetxattr. This function is just like getxattrat, + except when DIR_FD and FILE specify a symlink: lgetxattrat operates on the + symlink, while the getxattrat operates on the referent of the symlink. */ +ssize_t lgetxattrat (int dir_fd, const char *path, const char *name, + void *value, size_t size); + +/* dir-fd-relative listxattr. Obtain the list of extended attrubtes names. For + more info see the listxattr(2) manpage. */ +ssize_t listxattrat (int dir_fd, const char *path, char *list, size_t size); + +/* dir-fd-relative llistxattr. This function is just like listxattrat, + except when DIR_FD and FILE specify a symlink: llistxattr operates on the + symlink, while the listxattrat operates on the referent of the symlink. */ +ssize_t llistxattrat (int dir_fd, const char *path, char *list, size_t size); + +#endif /* XATTRS_AT_H */ |