diff options
Diffstat (limited to 'lib')
38 files changed, 6913 insertions, 0 deletions
diff --git a/lib/Makefile.am b/lib/Makefile.am new file mode 100644 index 0000000..8623ea4 --- /dev/null +++ b/lib/Makefile.am @@ -0,0 +1,78 @@ +## Process this file with automake to produce Makefile.in +## +## Copyright (C) 1994, 1995 Graeme Wilford. +## Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 Colin Watson. +## +## This file is part of man-db. +## +## man-db is free software; you can redistribute it and/or modify it +## under the terms of the GNU General Public License as published by +## the Free Software Foundation; either version 2 of the License, or +## (at your option) any later version. +## +## man-db 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 man-db; if not, write to the Free Software Foundation, +## Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +pkglib_LTLIBRARIES = libman.la +dist_noinst_DATA = README + +AM_CFLAGS = $(WARN_CFLAGS) + +libman_la_CPPFLAGS = \ + -I$(top_srcdir)/include \ + -I$(top_srcdir)/gl/lib \ + -I$(top_builddir)/gl/lib \ + -DLOCALEDIR=\"$(localedir)\" \ + $(libseccomp_CFLAGS) + +libman_la_SOURCES = \ + appendstr.c \ + appendstr.h \ + cleanup.c \ + cleanup.h \ + compression.c \ + compression.h \ + debug.c \ + debug.h \ + encodings.c \ + encodings.h \ + fatal.c \ + fatal.h \ + filenames.c \ + filenames.h \ + glcontainers.c \ + glcontainers.h \ + linelength.c \ + linelength.h \ + mp.h \ + orderfiles.c \ + orderfiles.h \ + pathsearch.c \ + pathsearch.h \ + sandbox.c \ + sandbox.h \ + security.c \ + security.h \ + tempfile.c \ + tempfile.h \ + util.c \ + util.h \ + wordfnmatch.c \ + wordfnmatch.h \ + xregcomp.c \ + xregcomp.h + +libman_la_LIBADD = ../gl/lib/libgnu.la $(LTLIBOBJS) \ + @LTLIBINTL@ + +libman_la_LDFLAGS = \ + -avoid-version -release $(VERSION) -rpath $(pkglibdir) \ + -no-undefined \ + $(LIBMAN_EXPORT_LDFLAGS) \ + $(libseccomp_LIBS) diff --git a/lib/Makefile.in b/lib/Makefile.in new file mode 100644 index 0000000..8e87e50 --- /dev/null +++ b/lib/Makefile.in @@ -0,0 +1,2272 @@ +# Makefile.in generated by automake 1.16.5 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2021 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@ + + +VPATH = @srcdir@ +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} +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@ +pkglibexecdir = $(libexecdir)/@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@ +subdir = lib +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/man-arg-automatic-create.m4 \ + $(top_srcdir)/m4/man-arg-automatic-update.m4 \ + $(top_srcdir)/m4/man-arg-cache-owner.m4 \ + $(top_srcdir)/m4/man-arg-cats.m4 \ + $(top_srcdir)/m4/man-arg-config-file.m4 \ + $(top_srcdir)/m4/man-arg-db.m4 \ + $(top_srcdir)/m4/man-arg-device.m4 \ + $(top_srcdir)/m4/man-arg-mandirs.m4 \ + $(top_srcdir)/m4/man-arg-manual.m4 \ + $(top_srcdir)/m4/man-arg-override-dir.m4 \ + $(top_srcdir)/m4/man-arg-sections.m4 \ + $(top_srcdir)/m4/man-arg-setuid.m4 \ + $(top_srcdir)/m4/man-arg-snapdir.m4 \ + $(top_srcdir)/m4/man-arg-systemdsystemunitdir.m4 \ + $(top_srcdir)/m4/man-arg-systemdtmpfilesdir.m4 \ + $(top_srcdir)/m4/man-arg-undoc.m4 $(top_srcdir)/m4/man-bdb.m4 \ + $(top_srcdir)/m4/man-check-progs.m4 \ + $(top_srcdir)/m4/man-compress-lib.m4 \ + $(top_srcdir)/m4/man-gnu-nroff.m4 \ + $(top_srcdir)/m4/man-heirloom-nroff.m4 \ + $(top_srcdir)/m4/man-libseccomp.m4 \ + $(top_srcdir)/m4/man-linguas.m4 $(top_srcdir)/m4/man-po4a.m4 \ + $(top_srcdir)/m4/man-tar-sort-name.m4 \ + $(top_srcdir)/m4/man-trans-subst.m4 \ + $(top_srcdir)/gl/m4/00gnulib.m4 \ + $(top_srcdir)/gl/m4/__inline.m4 \ + $(top_srcdir)/gl/m4/absolute-header.m4 \ + $(top_srcdir)/gl/m4/alloca.m4 $(top_srcdir)/gl/m4/argp.m4 \ + $(top_srcdir)/gl/m4/asm-underscore.m4 \ + $(top_srcdir)/gl/m4/assert_h.m4 $(top_srcdir)/gl/m4/btowc.m4 \ + $(top_srcdir)/gl/m4/builtin-expect.m4 \ + $(top_srcdir)/gl/m4/c-bool.m4 $(top_srcdir)/gl/m4/calloc.m4 \ + $(top_srcdir)/gl/m4/canonicalize.m4 \ + $(top_srcdir)/gl/m4/chdir-long.m4 $(top_srcdir)/gl/m4/chown.m4 \ + $(top_srcdir)/gl/m4/clock_time.m4 $(top_srcdir)/gl/m4/close.m4 \ + $(top_srcdir)/gl/m4/closedir.m4 $(top_srcdir)/gl/m4/codeset.m4 \ + $(top_srcdir)/gl/m4/ctype_h.m4 $(top_srcdir)/gl/m4/d-ino.m4 \ + $(top_srcdir)/gl/m4/d-type.m4 $(top_srcdir)/gl/m4/dirent_h.m4 \ + $(top_srcdir)/gl/m4/dirfd.m4 \ + $(top_srcdir)/gl/m4/double-slash-root.m4 \ + $(top_srcdir)/gl/m4/dup.m4 $(top_srcdir)/gl/m4/dup2.m4 \ + $(top_srcdir)/gl/m4/eealloc.m4 $(top_srcdir)/gl/m4/environ.m4 \ + $(top_srcdir)/gl/m4/errno_h.m4 $(top_srcdir)/gl/m4/error.m4 \ + $(top_srcdir)/gl/m4/error_h.m4 \ + $(top_srcdir)/gl/m4/exponentd.m4 \ + $(top_srcdir)/gl/m4/extensions.m4 \ + $(top_srcdir)/gl/m4/extern-inline.m4 \ + $(top_srcdir)/gl/m4/fchdir.m4 $(top_srcdir)/gl/m4/fcntl-o.m4 \ + $(top_srcdir)/gl/m4/fcntl.m4 $(top_srcdir)/gl/m4/fcntl_h.m4 \ + $(top_srcdir)/gl/m4/fdopendir.m4 \ + $(top_srcdir)/gl/m4/filenamecat.m4 \ + $(top_srcdir)/gl/m4/flexmember.m4 \ + $(top_srcdir)/gl/m4/float_h.m4 $(top_srcdir)/gl/m4/flock.m4 \ + $(top_srcdir)/gl/m4/fnmatch.m4 \ + $(top_srcdir)/gl/m4/fnmatch_h.m4 $(top_srcdir)/gl/m4/free.m4 \ + $(top_srcdir)/gl/m4/fstat.m4 $(top_srcdir)/gl/m4/fstatat.m4 \ + $(top_srcdir)/gl/m4/getcwd-abort-bug.m4 \ + $(top_srcdir)/gl/m4/getcwd-path-max.m4 \ + $(top_srcdir)/gl/m4/getcwd.m4 $(top_srcdir)/gl/m4/getdelim.m4 \ + $(top_srcdir)/gl/m4/getdtablesize.m4 \ + $(top_srcdir)/gl/m4/getline.m4 $(top_srcdir)/gl/m4/getlogin.m4 \ + $(top_srcdir)/gl/m4/getlogin_r.m4 \ + $(top_srcdir)/gl/m4/getopt.m4 \ + $(top_srcdir)/gl/m4/getpagesize.m4 \ + $(top_srcdir)/gl/m4/getprogname.m4 \ + $(top_srcdir)/gl/m4/getrandom.m4 \ + $(top_srcdir)/gl/m4/gettext.m4 $(top_srcdir)/gl/m4/gettime.m4 \ + $(top_srcdir)/gl/m4/gettimeofday.m4 \ + $(top_srcdir)/gl/m4/glob.m4 $(top_srcdir)/gl/m4/glob_h.m4 \ + $(top_srcdir)/gl/m4/gnulib-common.m4 \ + $(top_srcdir)/gl/m4/gnulib-comp.m4 \ + $(top_srcdir)/gl/m4/host-cpu-c-abi.m4 \ + $(top_srcdir)/gl/m4/iconv.m4 $(top_srcdir)/gl/m4/idpriv.m4 \ + $(top_srcdir)/gl/m4/include_next.m4 \ + $(top_srcdir)/gl/m4/intlmacosx.m4 \ + $(top_srcdir)/gl/m4/intmax_t.m4 \ + $(top_srcdir)/gl/m4/inttypes.m4 \ + $(top_srcdir)/gl/m4/inttypes_h.m4 $(top_srcdir)/gl/m4/ioctl.m4 \ + $(top_srcdir)/gl/m4/isblank.m4 \ + $(top_srcdir)/gl/m4/langinfo_h.m4 \ + $(top_srcdir)/gl/m4/largefile.m4 $(top_srcdir)/gl/m4/lchown.m4 \ + $(top_srcdir)/gl/m4/lib-ignore.m4 \ + $(top_srcdir)/gl/m4/lib-ld.m4 $(top_srcdir)/gl/m4/lib-link.m4 \ + $(top_srcdir)/gl/m4/lib-prefix.m4 \ + $(top_srcdir)/gl/m4/libtool.m4 $(top_srcdir)/gl/m4/limits-h.m4 \ + $(top_srcdir)/gl/m4/localcharset.m4 \ + $(top_srcdir)/gl/m4/locale-fr.m4 \ + $(top_srcdir)/gl/m4/locale-ja.m4 \ + $(top_srcdir)/gl/m4/locale-zh.m4 \ + $(top_srcdir)/gl/m4/locale_h.m4 \ + $(top_srcdir)/gl/m4/localeconv.m4 $(top_srcdir)/gl/m4/lock.m4 \ + $(top_srcdir)/gl/m4/lstat.m4 $(top_srcdir)/gl/m4/ltoptions.m4 \ + $(top_srcdir)/gl/m4/ltsugar.m4 \ + $(top_srcdir)/gl/m4/ltversion.m4 \ + $(top_srcdir)/gl/m4/lt~obsolete.m4 \ + $(top_srcdir)/gl/m4/malloc.m4 $(top_srcdir)/gl/m4/malloca.m4 \ + $(top_srcdir)/gl/m4/manywarnings.m4 \ + $(top_srcdir)/gl/m4/mbrtowc.m4 $(top_srcdir)/gl/m4/mbsinit.m4 \ + $(top_srcdir)/gl/m4/mbsrtowcs.m4 \ + $(top_srcdir)/gl/m4/mbstate_t.m4 $(top_srcdir)/gl/m4/mbtowc.m4 \ + $(top_srcdir)/gl/m4/memchr.m4 $(top_srcdir)/gl/m4/memmem.m4 \ + $(top_srcdir)/gl/m4/mempcpy.m4 $(top_srcdir)/gl/m4/memrchr.m4 \ + $(top_srcdir)/gl/m4/minmax.m4 $(top_srcdir)/gl/m4/mkdir.m4 \ + $(top_srcdir)/gl/m4/mkdtemp.m4 $(top_srcdir)/gl/m4/mkstemp.m4 \ + $(top_srcdir)/gl/m4/mmap-anon.m4 $(top_srcdir)/gl/m4/mode_t.m4 \ + $(top_srcdir)/gl/m4/msvc-inval.m4 \ + $(top_srcdir)/gl/m4/msvc-nothrow.m4 \ + $(top_srcdir)/gl/m4/multiarch.m4 $(top_srcdir)/gl/m4/musl.m4 \ + $(top_srcdir)/gl/m4/nanosleep.m4 \ + $(top_srcdir)/gl/m4/nl_langinfo.m4 $(top_srcdir)/gl/m4/nls.m4 \ + $(top_srcdir)/gl/m4/nocrash.m4 \ + $(top_srcdir)/gl/m4/nonblocking.m4 \ + $(top_srcdir)/gl/m4/off_t.m4 \ + $(top_srcdir)/gl/m4/open-cloexec.m4 \ + $(top_srcdir)/gl/m4/open-slash.m4 $(top_srcdir)/gl/m4/open.m4 \ + $(top_srcdir)/gl/m4/openat.m4 $(top_srcdir)/gl/m4/opendir.m4 \ + $(top_srcdir)/gl/m4/pathmax.m4 $(top_srcdir)/gl/m4/pipe.m4 \ + $(top_srcdir)/gl/m4/po.m4 $(top_srcdir)/gl/m4/printf.m4 \ + $(top_srcdir)/gl/m4/progtest.m4 $(top_srcdir)/gl/m4/pselect.m4 \ + $(top_srcdir)/gl/m4/pthread_rwlock_rdlock.m4 \ + $(top_srcdir)/gl/m4/pthread_sigmask.m4 \ + $(top_srcdir)/gl/m4/raise.m4 $(top_srcdir)/gl/m4/rawmemchr.m4 \ + $(top_srcdir)/gl/m4/readdir.m4 $(top_srcdir)/gl/m4/readlink.m4 \ + $(top_srcdir)/gl/m4/readlinkat.m4 \ + $(top_srcdir)/gl/m4/realloc.m4 \ + $(top_srcdir)/gl/m4/reallocarray.m4 \ + $(top_srcdir)/gl/m4/regex.m4 $(top_srcdir)/gl/m4/rename.m4 \ + $(top_srcdir)/gl/m4/renameat.m4 \ + $(top_srcdir)/gl/m4/rewinddir.m4 $(top_srcdir)/gl/m4/rmdir.m4 \ + $(top_srcdir)/gl/m4/save-cwd.m4 $(top_srcdir)/gl/m4/select.m4 \ + $(top_srcdir)/gl/m4/setenv.m4 \ + $(top_srcdir)/gl/m4/setlocale_null.m4 \ + $(top_srcdir)/gl/m4/sigaction.m4 \ + $(top_srcdir)/gl/m4/signal_h.m4 \ + $(top_srcdir)/gl/m4/signalblocking.m4 \ + $(top_srcdir)/gl/m4/sigpipe.m4 $(top_srcdir)/gl/m4/size_max.m4 \ + $(top_srcdir)/gl/m4/sleep.m4 $(top_srcdir)/gl/m4/socketlib.m4 \ + $(top_srcdir)/gl/m4/sockets.m4 $(top_srcdir)/gl/m4/socklen.m4 \ + $(top_srcdir)/gl/m4/ssize_t.m4 \ + $(top_srcdir)/gl/m4/stat-time.m4 $(top_srcdir)/gl/m4/stat.m4 \ + $(top_srcdir)/gl/m4/stdalign.m4 $(top_srcdir)/gl/m4/stdarg.m4 \ + $(top_srcdir)/gl/m4/stddef_h.m4 $(top_srcdir)/gl/m4/stdint.m4 \ + $(top_srcdir)/gl/m4/stdint_h.m4 $(top_srcdir)/gl/m4/stdio_h.m4 \ + $(top_srcdir)/gl/m4/stdlib_h.m4 $(top_srcdir)/gl/m4/stpcpy.m4 \ + $(top_srcdir)/gl/m4/strcase.m4 \ + $(top_srcdir)/gl/m4/strcasestr.m4 \ + $(top_srcdir)/gl/m4/strchrnul.m4 $(top_srcdir)/gl/m4/strdup.m4 \ + $(top_srcdir)/gl/m4/strerror.m4 \ + $(top_srcdir)/gl/m4/string_h.m4 \ + $(top_srcdir)/gl/m4/strings_h.m4 \ + $(top_srcdir)/gl/m4/strndup.m4 $(top_srcdir)/gl/m4/strnlen.m4 \ + $(top_srcdir)/gl/m4/strsep.m4 \ + $(top_srcdir)/gl/m4/sys_file_h.m4 \ + $(top_srcdir)/gl/m4/sys_ioctl_h.m4 \ + $(top_srcdir)/gl/m4/sys_random_h.m4 \ + $(top_srcdir)/gl/m4/sys_select_h.m4 \ + $(top_srcdir)/gl/m4/sys_socket_h.m4 \ + $(top_srcdir)/gl/m4/sys_stat_h.m4 \ + $(top_srcdir)/gl/m4/sys_time_h.m4 \ + $(top_srcdir)/gl/m4/sys_types_h.m4 \ + $(top_srcdir)/gl/m4/sys_uio_h.m4 \ + $(top_srcdir)/gl/m4/sysexits.m4 \ + $(top_srcdir)/gl/m4/tempname.m4 \ + $(top_srcdir)/gl/m4/termios_h.m4 \ + $(top_srcdir)/gl/m4/threadlib.m4 $(top_srcdir)/gl/m4/time_h.m4 \ + $(top_srcdir)/gl/m4/timespec.m4 \ + $(top_srcdir)/gl/m4/unistd-safer.m4 \ + $(top_srcdir)/gl/m4/unistd_h.m4 $(top_srcdir)/gl/m4/unlink.m4 \ + $(top_srcdir)/gl/m4/unlinkat.m4 $(top_srcdir)/gl/m4/utime.m4 \ + $(top_srcdir)/gl/m4/utime_h.m4 $(top_srcdir)/gl/m4/utimens.m4 \ + $(top_srcdir)/gl/m4/utimes.m4 \ + $(top_srcdir)/gl/m4/vasnprintf.m4 \ + $(top_srcdir)/gl/m4/vasprintf.m4 \ + $(top_srcdir)/gl/m4/visibility.m4 \ + $(top_srcdir)/gl/m4/vsnprintf.m4 \ + $(top_srcdir)/gl/m4/warn-on-use.m4 \ + $(top_srcdir)/gl/m4/warnings.m4 $(top_srcdir)/gl/m4/wchar_h.m4 \ + $(top_srcdir)/gl/m4/wchar_t.m4 $(top_srcdir)/gl/m4/wcrtomb.m4 \ + $(top_srcdir)/gl/m4/wctype_h.m4 $(top_srcdir)/gl/m4/wint_t.m4 \ + $(top_srcdir)/gl/m4/wmemchr.m4 $(top_srcdir)/gl/m4/wmempcpy.m4 \ + $(top_srcdir)/gl/m4/xalloc.m4 $(top_srcdir)/gl/m4/xgetcwd.m4 \ + $(top_srcdir)/gl/m4/xsize.m4 $(top_srcdir)/gl/m4/xstrndup.m4 \ + $(top_srcdir)/gl/m4/xvasprintf.m4 \ + $(top_srcdir)/gl/m4/zzgnulib.m4 $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(dist_noinst_DATA) \ + $(am__DIST_COMMON) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; +am__install_max = 40 +am__nobase_strip_setup = \ + srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` +am__nobase_strip = \ + for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" +am__nobase_list = $(am__nobase_strip_setup); \ + for p in $$list; do echo "$$p $$p"; done | \ + sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ + $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ + if (++n[$$2] == $(am__install_max)) \ + { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ + END { for (dir in files) print dir, files[dir] }' +am__base_list = \ + sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ + sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' +am__uninstall_files_from_dir = { \ + test -z "$$files" \ + || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ + || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ + $(am__cd) "$$dir" && rm -f $$files; }; \ + } +am__installdirs = "$(DESTDIR)$(pkglibdir)" +LTLIBRARIES = $(pkglib_LTLIBRARIES) +libman_la_DEPENDENCIES = ../gl/lib/libgnu.la $(LTLIBOBJS) +am_libman_la_OBJECTS = libman_la-appendstr.lo libman_la-cleanup.lo \ + libman_la-compression.lo libman_la-debug.lo \ + libman_la-encodings.lo libman_la-fatal.lo \ + libman_la-filenames.lo libman_la-glcontainers.lo \ + libman_la-linelength.lo libman_la-orderfiles.lo \ + libman_la-pathsearch.lo libman_la-sandbox.lo \ + libman_la-security.lo libman_la-tempfile.lo libman_la-util.lo \ + libman_la-wordfnmatch.lo libman_la-xregcomp.lo +libman_la_OBJECTS = $(am_libman_la_OBJECTS) +AM_V_lt = $(am__v_lt_@AM_V@) +am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) +am__v_lt_0 = --silent +am__v_lt_1 = +libman_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(libman_la_LDFLAGS) $(LDFLAGS) -o $@ +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__maybe_remake_depfiles = depfiles +am__depfiles_remade = ./$(DEPDIR)/libman_la-appendstr.Plo \ + ./$(DEPDIR)/libman_la-cleanup.Plo \ + ./$(DEPDIR)/libman_la-compression.Plo \ + ./$(DEPDIR)/libman_la-debug.Plo \ + ./$(DEPDIR)/libman_la-encodings.Plo \ + ./$(DEPDIR)/libman_la-fatal.Plo \ + ./$(DEPDIR)/libman_la-filenames.Plo \ + ./$(DEPDIR)/libman_la-glcontainers.Plo \ + ./$(DEPDIR)/libman_la-linelength.Plo \ + ./$(DEPDIR)/libman_la-orderfiles.Plo \ + ./$(DEPDIR)/libman_la-pathsearch.Plo \ + ./$(DEPDIR)/libman_la-sandbox.Plo \ + ./$(DEPDIR)/libman_la-security.Plo \ + ./$(DEPDIR)/libman_la-tempfile.Plo \ + ./$(DEPDIR)/libman_la-util.Plo \ + ./$(DEPDIR)/libman_la-wordfnmatch.Plo \ + ./$(DEPDIR)/libman_la-xregcomp.Plo +am__mv = mv -f +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=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 = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=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 = $(libman_la_SOURCES) +DIST_SOURCES = $(libman_la_SOURCES) +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +DATA = $(dist_noinst_DATA) +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)` +am__DIST_COMMON = $(srcdir)/Makefile.in \ + $(top_srcdir)/build-aux/depcomp README +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +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@ +ASM_SYMBOL_PREFIX = @ASM_SYMBOL_PREFIX@ +ASSERT_H = @ASSERT_H@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +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@ +CFLAG_VISIBILITY = @CFLAG_VISIBILITY@ +CLOCK_TIME_LIB = @CLOCK_TIME_LIB@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CSCOPE = @CSCOPE@ +CTAGS = @CTAGS@ +CYGPATH_W = @CYGPATH_W@ +DBLIBS = @DBLIBS@ +DBTYPE = @DBTYPE@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DIR_HAS_FD_MEMBER = @DIR_HAS_FD_MEMBER@ +DLLTOOL = @DLLTOOL@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +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@ +ETAGS = @ETAGS@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +FILECMD = @FILECMD@ +FLOAT_H = @FLOAT_H@ +FNMATCH_H = @FNMATCH_H@ +GETLOGIN_LIB = @GETLOGIN_LIB@ +GETOPT_CDEFS_H = @GETOPT_CDEFS_H@ +GETOPT_H = @GETOPT_H@ +GETRANDOM_LIB = @GETRANDOM_LIB@ +GETTEXT_MACRO_VERSION = @GETTEXT_MACRO_VERSION@ +GLOB_H = @GLOB_H@ +GL_CFLAG_ALLOW_WARNINGS = @GL_CFLAG_ALLOW_WARNINGS@ +GL_CFLAG_GNULIB_WARNINGS = @GL_CFLAG_GNULIB_WARNINGS@ +GL_GNULIB_ACCEPT = @GL_GNULIB_ACCEPT@ +GL_GNULIB_ACCEPT4 = @GL_GNULIB_ACCEPT4@ +GL_GNULIB_ACCESS = @GL_GNULIB_ACCESS@ +GL_GNULIB_ALIGNED_ALLOC = @GL_GNULIB_ALIGNED_ALLOC@ +GL_GNULIB_ALPHASORT = @GL_GNULIB_ALPHASORT@ +GL_GNULIB_ATOLL = @GL_GNULIB_ATOLL@ +GL_GNULIB_BIND = @GL_GNULIB_BIND@ +GL_GNULIB_BTOWC = @GL_GNULIB_BTOWC@ +GL_GNULIB_CALLOC_GNU = @GL_GNULIB_CALLOC_GNU@ +GL_GNULIB_CALLOC_POSIX = @GL_GNULIB_CALLOC_POSIX@ +GL_GNULIB_CANONICALIZE_FILE_NAME = @GL_GNULIB_CANONICALIZE_FILE_NAME@ +GL_GNULIB_CHDIR = @GL_GNULIB_CHDIR@ +GL_GNULIB_CHMOD = @GL_GNULIB_CHMOD@ +GL_GNULIB_CHOWN = @GL_GNULIB_CHOWN@ +GL_GNULIB_CLOSE = @GL_GNULIB_CLOSE@ +GL_GNULIB_CLOSEDIR = @GL_GNULIB_CLOSEDIR@ +GL_GNULIB_CONNECT = @GL_GNULIB_CONNECT@ +GL_GNULIB_COPY_FILE_RANGE = @GL_GNULIB_COPY_FILE_RANGE@ +GL_GNULIB_CREAT = @GL_GNULIB_CREAT@ +GL_GNULIB_CTIME = @GL_GNULIB_CTIME@ +GL_GNULIB_DIRFD = @GL_GNULIB_DIRFD@ +GL_GNULIB_DPRINTF = @GL_GNULIB_DPRINTF@ +GL_GNULIB_DUP = @GL_GNULIB_DUP@ +GL_GNULIB_DUP2 = @GL_GNULIB_DUP2@ +GL_GNULIB_DUP3 = @GL_GNULIB_DUP3@ +GL_GNULIB_DUPLOCALE = @GL_GNULIB_DUPLOCALE@ +GL_GNULIB_ENVIRON = @GL_GNULIB_ENVIRON@ +GL_GNULIB_EUIDACCESS = @GL_GNULIB_EUIDACCESS@ +GL_GNULIB_EXECL = @GL_GNULIB_EXECL@ +GL_GNULIB_EXECLE = @GL_GNULIB_EXECLE@ +GL_GNULIB_EXECLP = @GL_GNULIB_EXECLP@ +GL_GNULIB_EXECV = @GL_GNULIB_EXECV@ +GL_GNULIB_EXECVE = @GL_GNULIB_EXECVE@ +GL_GNULIB_EXECVP = @GL_GNULIB_EXECVP@ +GL_GNULIB_EXECVPE = @GL_GNULIB_EXECVPE@ +GL_GNULIB_EXPLICIT_BZERO = @GL_GNULIB_EXPLICIT_BZERO@ +GL_GNULIB_FACCESSAT = @GL_GNULIB_FACCESSAT@ +GL_GNULIB_FCHDIR = @GL_GNULIB_FCHDIR@ +GL_GNULIB_FCHMODAT = @GL_GNULIB_FCHMODAT@ +GL_GNULIB_FCHOWNAT = @GL_GNULIB_FCHOWNAT@ +GL_GNULIB_FCLOSE = @GL_GNULIB_FCLOSE@ +GL_GNULIB_FCNTL = @GL_GNULIB_FCNTL@ +GL_GNULIB_FDATASYNC = @GL_GNULIB_FDATASYNC@ +GL_GNULIB_FDOPEN = @GL_GNULIB_FDOPEN@ +GL_GNULIB_FDOPENDIR = @GL_GNULIB_FDOPENDIR@ +GL_GNULIB_FFLUSH = @GL_GNULIB_FFLUSH@ +GL_GNULIB_FFS = @GL_GNULIB_FFS@ +GL_GNULIB_FFSL = @GL_GNULIB_FFSL@ +GL_GNULIB_FFSLL = @GL_GNULIB_FFSLL@ +GL_GNULIB_FGETC = @GL_GNULIB_FGETC@ +GL_GNULIB_FGETS = @GL_GNULIB_FGETS@ +GL_GNULIB_FLOCK = @GL_GNULIB_FLOCK@ +GL_GNULIB_FNMATCH = @GL_GNULIB_FNMATCH@ +GL_GNULIB_FOPEN = @GL_GNULIB_FOPEN@ +GL_GNULIB_FOPEN_GNU = @GL_GNULIB_FOPEN_GNU@ +GL_GNULIB_FPRINTF = @GL_GNULIB_FPRINTF@ +GL_GNULIB_FPRINTF_POSIX = @GL_GNULIB_FPRINTF_POSIX@ +GL_GNULIB_FPURGE = @GL_GNULIB_FPURGE@ +GL_GNULIB_FPUTC = @GL_GNULIB_FPUTC@ +GL_GNULIB_FPUTS = @GL_GNULIB_FPUTS@ +GL_GNULIB_FREAD = @GL_GNULIB_FREAD@ +GL_GNULIB_FREE_POSIX = @GL_GNULIB_FREE_POSIX@ +GL_GNULIB_FREOPEN = @GL_GNULIB_FREOPEN@ +GL_GNULIB_FSCANF = @GL_GNULIB_FSCANF@ +GL_GNULIB_FSEEK = @GL_GNULIB_FSEEK@ +GL_GNULIB_FSEEKO = @GL_GNULIB_FSEEKO@ +GL_GNULIB_FSTAT = @GL_GNULIB_FSTAT@ +GL_GNULIB_FSTATAT = @GL_GNULIB_FSTATAT@ +GL_GNULIB_FSYNC = @GL_GNULIB_FSYNC@ +GL_GNULIB_FTELL = @GL_GNULIB_FTELL@ +GL_GNULIB_FTELLO = @GL_GNULIB_FTELLO@ +GL_GNULIB_FTRUNCATE = @GL_GNULIB_FTRUNCATE@ +GL_GNULIB_FUTIMENS = @GL_GNULIB_FUTIMENS@ +GL_GNULIB_FWRITE = @GL_GNULIB_FWRITE@ +GL_GNULIB_GETC = @GL_GNULIB_GETC@ +GL_GNULIB_GETCHAR = @GL_GNULIB_GETCHAR@ +GL_GNULIB_GETCWD = @GL_GNULIB_GETCWD@ +GL_GNULIB_GETDELIM = @GL_GNULIB_GETDELIM@ +GL_GNULIB_GETDOMAINNAME = @GL_GNULIB_GETDOMAINNAME@ +GL_GNULIB_GETDTABLESIZE = @GL_GNULIB_GETDTABLESIZE@ +GL_GNULIB_GETENTROPY = @GL_GNULIB_GETENTROPY@ +GL_GNULIB_GETGROUPS = @GL_GNULIB_GETGROUPS@ +GL_GNULIB_GETHOSTNAME = @GL_GNULIB_GETHOSTNAME@ +GL_GNULIB_GETLINE = @GL_GNULIB_GETLINE@ +GL_GNULIB_GETLOADAVG = @GL_GNULIB_GETLOADAVG@ +GL_GNULIB_GETLOGIN = @GL_GNULIB_GETLOGIN@ +GL_GNULIB_GETLOGIN_R = @GL_GNULIB_GETLOGIN_R@ +GL_GNULIB_GETOPT_POSIX = @GL_GNULIB_GETOPT_POSIX@ +GL_GNULIB_GETPAGESIZE = @GL_GNULIB_GETPAGESIZE@ +GL_GNULIB_GETPASS = @GL_GNULIB_GETPASS@ +GL_GNULIB_GETPASS_GNU = @GL_GNULIB_GETPASS_GNU@ +GL_GNULIB_GETPEERNAME = @GL_GNULIB_GETPEERNAME@ +GL_GNULIB_GETPROGNAME = @GL_GNULIB_GETPROGNAME@ +GL_GNULIB_GETRANDOM = @GL_GNULIB_GETRANDOM@ +GL_GNULIB_GETSOCKNAME = @GL_GNULIB_GETSOCKNAME@ +GL_GNULIB_GETSOCKOPT = @GL_GNULIB_GETSOCKOPT@ +GL_GNULIB_GETSUBOPT = @GL_GNULIB_GETSUBOPT@ +GL_GNULIB_GETTIMEOFDAY = @GL_GNULIB_GETTIMEOFDAY@ +GL_GNULIB_GETUMASK = @GL_GNULIB_GETUMASK@ +GL_GNULIB_GETUSERSHELL = @GL_GNULIB_GETUSERSHELL@ +GL_GNULIB_GLOB = @GL_GNULIB_GLOB@ +GL_GNULIB_GRANTPT = @GL_GNULIB_GRANTPT@ +GL_GNULIB_GROUP_MEMBER = @GL_GNULIB_GROUP_MEMBER@ +GL_GNULIB_IMAXABS = @GL_GNULIB_IMAXABS@ +GL_GNULIB_IMAXDIV = @GL_GNULIB_IMAXDIV@ +GL_GNULIB_IOCTL = @GL_GNULIB_IOCTL@ +GL_GNULIB_ISATTY = @GL_GNULIB_ISATTY@ +GL_GNULIB_ISBLANK = @GL_GNULIB_ISBLANK@ +GL_GNULIB_ISWBLANK = @GL_GNULIB_ISWBLANK@ +GL_GNULIB_ISWCTYPE = @GL_GNULIB_ISWCTYPE@ +GL_GNULIB_ISWDIGIT = @GL_GNULIB_ISWDIGIT@ +GL_GNULIB_ISWXDIGIT = @GL_GNULIB_ISWXDIGIT@ +GL_GNULIB_LCHMOD = @GL_GNULIB_LCHMOD@ +GL_GNULIB_LCHOWN = @GL_GNULIB_LCHOWN@ +GL_GNULIB_LINK = @GL_GNULIB_LINK@ +GL_GNULIB_LINKAT = @GL_GNULIB_LINKAT@ +GL_GNULIB_LISTEN = @GL_GNULIB_LISTEN@ +GL_GNULIB_LOCALECONV = @GL_GNULIB_LOCALECONV@ +GL_GNULIB_LOCALENAME = @GL_GNULIB_LOCALENAME@ +GL_GNULIB_LOCALTIME = @GL_GNULIB_LOCALTIME@ +GL_GNULIB_LSEEK = @GL_GNULIB_LSEEK@ +GL_GNULIB_LSTAT = @GL_GNULIB_LSTAT@ +GL_GNULIB_MALLOC_GNU = @GL_GNULIB_MALLOC_GNU@ +GL_GNULIB_MALLOC_POSIX = @GL_GNULIB_MALLOC_POSIX@ +GL_GNULIB_MBRLEN = @GL_GNULIB_MBRLEN@ +GL_GNULIB_MBRTOWC = @GL_GNULIB_MBRTOWC@ +GL_GNULIB_MBSCASECMP = @GL_GNULIB_MBSCASECMP@ +GL_GNULIB_MBSCASESTR = @GL_GNULIB_MBSCASESTR@ +GL_GNULIB_MBSCHR = @GL_GNULIB_MBSCHR@ +GL_GNULIB_MBSCSPN = @GL_GNULIB_MBSCSPN@ +GL_GNULIB_MBSINIT = @GL_GNULIB_MBSINIT@ +GL_GNULIB_MBSLEN = @GL_GNULIB_MBSLEN@ +GL_GNULIB_MBSNCASECMP = @GL_GNULIB_MBSNCASECMP@ +GL_GNULIB_MBSNLEN = @GL_GNULIB_MBSNLEN@ +GL_GNULIB_MBSNRTOWCS = @GL_GNULIB_MBSNRTOWCS@ +GL_GNULIB_MBSPBRK = @GL_GNULIB_MBSPBRK@ +GL_GNULIB_MBSPCASECMP = @GL_GNULIB_MBSPCASECMP@ +GL_GNULIB_MBSRCHR = @GL_GNULIB_MBSRCHR@ +GL_GNULIB_MBSRTOWCS = @GL_GNULIB_MBSRTOWCS@ +GL_GNULIB_MBSSEP = @GL_GNULIB_MBSSEP@ +GL_GNULIB_MBSSPN = @GL_GNULIB_MBSSPN@ +GL_GNULIB_MBSSTR = @GL_GNULIB_MBSSTR@ +GL_GNULIB_MBSTOK_R = @GL_GNULIB_MBSTOK_R@ +GL_GNULIB_MBSTOWCS = @GL_GNULIB_MBSTOWCS@ +GL_GNULIB_MBTOWC = @GL_GNULIB_MBTOWC@ +GL_GNULIB_MDA_ACCESS = @GL_GNULIB_MDA_ACCESS@ +GL_GNULIB_MDA_CHDIR = @GL_GNULIB_MDA_CHDIR@ +GL_GNULIB_MDA_CHMOD = @GL_GNULIB_MDA_CHMOD@ +GL_GNULIB_MDA_CLOSE = @GL_GNULIB_MDA_CLOSE@ +GL_GNULIB_MDA_CREAT = @GL_GNULIB_MDA_CREAT@ +GL_GNULIB_MDA_DUP = @GL_GNULIB_MDA_DUP@ +GL_GNULIB_MDA_DUP2 = @GL_GNULIB_MDA_DUP2@ +GL_GNULIB_MDA_ECVT = @GL_GNULIB_MDA_ECVT@ +GL_GNULIB_MDA_EXECL = @GL_GNULIB_MDA_EXECL@ +GL_GNULIB_MDA_EXECLE = @GL_GNULIB_MDA_EXECLE@ +GL_GNULIB_MDA_EXECLP = @GL_GNULIB_MDA_EXECLP@ +GL_GNULIB_MDA_EXECV = @GL_GNULIB_MDA_EXECV@ +GL_GNULIB_MDA_EXECVE = @GL_GNULIB_MDA_EXECVE@ +GL_GNULIB_MDA_EXECVP = @GL_GNULIB_MDA_EXECVP@ +GL_GNULIB_MDA_EXECVPE = @GL_GNULIB_MDA_EXECVPE@ +GL_GNULIB_MDA_FCLOSEALL = @GL_GNULIB_MDA_FCLOSEALL@ +GL_GNULIB_MDA_FCVT = @GL_GNULIB_MDA_FCVT@ +GL_GNULIB_MDA_FDOPEN = @GL_GNULIB_MDA_FDOPEN@ +GL_GNULIB_MDA_FILENO = @GL_GNULIB_MDA_FILENO@ +GL_GNULIB_MDA_GCVT = @GL_GNULIB_MDA_GCVT@ +GL_GNULIB_MDA_GETCWD = @GL_GNULIB_MDA_GETCWD@ +GL_GNULIB_MDA_GETPID = @GL_GNULIB_MDA_GETPID@ +GL_GNULIB_MDA_GETW = @GL_GNULIB_MDA_GETW@ +GL_GNULIB_MDA_ISATTY = @GL_GNULIB_MDA_ISATTY@ +GL_GNULIB_MDA_LSEEK = @GL_GNULIB_MDA_LSEEK@ +GL_GNULIB_MDA_MEMCCPY = @GL_GNULIB_MDA_MEMCCPY@ +GL_GNULIB_MDA_MKDIR = @GL_GNULIB_MDA_MKDIR@ +GL_GNULIB_MDA_MKTEMP = @GL_GNULIB_MDA_MKTEMP@ +GL_GNULIB_MDA_OPEN = @GL_GNULIB_MDA_OPEN@ +GL_GNULIB_MDA_PUTENV = @GL_GNULIB_MDA_PUTENV@ +GL_GNULIB_MDA_PUTW = @GL_GNULIB_MDA_PUTW@ +GL_GNULIB_MDA_READ = @GL_GNULIB_MDA_READ@ +GL_GNULIB_MDA_RMDIR = @GL_GNULIB_MDA_RMDIR@ +GL_GNULIB_MDA_STRDUP = @GL_GNULIB_MDA_STRDUP@ +GL_GNULIB_MDA_SWAB = @GL_GNULIB_MDA_SWAB@ +GL_GNULIB_MDA_TEMPNAM = @GL_GNULIB_MDA_TEMPNAM@ +GL_GNULIB_MDA_TZSET = @GL_GNULIB_MDA_TZSET@ +GL_GNULIB_MDA_UMASK = @GL_GNULIB_MDA_UMASK@ +GL_GNULIB_MDA_UNLINK = @GL_GNULIB_MDA_UNLINK@ +GL_GNULIB_MDA_UTIME = @GL_GNULIB_MDA_UTIME@ +GL_GNULIB_MDA_WCSDUP = @GL_GNULIB_MDA_WCSDUP@ +GL_GNULIB_MDA_WRITE = @GL_GNULIB_MDA_WRITE@ +GL_GNULIB_MEMCHR = @GL_GNULIB_MEMCHR@ +GL_GNULIB_MEMMEM = @GL_GNULIB_MEMMEM@ +GL_GNULIB_MEMPCPY = @GL_GNULIB_MEMPCPY@ +GL_GNULIB_MEMRCHR = @GL_GNULIB_MEMRCHR@ +GL_GNULIB_MEMSET_EXPLICIT = @GL_GNULIB_MEMSET_EXPLICIT@ +GL_GNULIB_MKDIR = @GL_GNULIB_MKDIR@ +GL_GNULIB_MKDIRAT = @GL_GNULIB_MKDIRAT@ +GL_GNULIB_MKDTEMP = @GL_GNULIB_MKDTEMP@ +GL_GNULIB_MKFIFO = @GL_GNULIB_MKFIFO@ +GL_GNULIB_MKFIFOAT = @GL_GNULIB_MKFIFOAT@ +GL_GNULIB_MKNOD = @GL_GNULIB_MKNOD@ +GL_GNULIB_MKNODAT = @GL_GNULIB_MKNODAT@ +GL_GNULIB_MKOSTEMP = @GL_GNULIB_MKOSTEMP@ +GL_GNULIB_MKOSTEMPS = @GL_GNULIB_MKOSTEMPS@ +GL_GNULIB_MKSTEMP = @GL_GNULIB_MKSTEMP@ +GL_GNULIB_MKSTEMPS = @GL_GNULIB_MKSTEMPS@ +GL_GNULIB_MKTIME = @GL_GNULIB_MKTIME@ +GL_GNULIB_NANOSLEEP = @GL_GNULIB_NANOSLEEP@ +GL_GNULIB_NL_LANGINFO = @GL_GNULIB_NL_LANGINFO@ +GL_GNULIB_NONBLOCKING = @GL_GNULIB_NONBLOCKING@ +GL_GNULIB_OBSTACK_PRINTF = @GL_GNULIB_OBSTACK_PRINTF@ +GL_GNULIB_OBSTACK_PRINTF_POSIX = @GL_GNULIB_OBSTACK_PRINTF_POSIX@ +GL_GNULIB_OPEN = @GL_GNULIB_OPEN@ +GL_GNULIB_OPENAT = @GL_GNULIB_OPENAT@ +GL_GNULIB_OPENDIR = @GL_GNULIB_OPENDIR@ +GL_GNULIB_OVERRIDES_STRUCT_STAT = @GL_GNULIB_OVERRIDES_STRUCT_STAT@ +GL_GNULIB_PCLOSE = @GL_GNULIB_PCLOSE@ +GL_GNULIB_PERROR = @GL_GNULIB_PERROR@ +GL_GNULIB_PIPE = @GL_GNULIB_PIPE@ +GL_GNULIB_PIPE2 = @GL_GNULIB_PIPE2@ +GL_GNULIB_POPEN = @GL_GNULIB_POPEN@ +GL_GNULIB_POSIX_MEMALIGN = @GL_GNULIB_POSIX_MEMALIGN@ +GL_GNULIB_POSIX_OPENPT = @GL_GNULIB_POSIX_OPENPT@ +GL_GNULIB_PREAD = @GL_GNULIB_PREAD@ +GL_GNULIB_PRINTF = @GL_GNULIB_PRINTF@ +GL_GNULIB_PRINTF_POSIX = @GL_GNULIB_PRINTF_POSIX@ +GL_GNULIB_PSELECT = @GL_GNULIB_PSELECT@ +GL_GNULIB_PTHREAD_SIGMASK = @GL_GNULIB_PTHREAD_SIGMASK@ +GL_GNULIB_PTSNAME = @GL_GNULIB_PTSNAME@ +GL_GNULIB_PTSNAME_R = @GL_GNULIB_PTSNAME_R@ +GL_GNULIB_PUTC = @GL_GNULIB_PUTC@ +GL_GNULIB_PUTCHAR = @GL_GNULIB_PUTCHAR@ +GL_GNULIB_PUTENV = @GL_GNULIB_PUTENV@ +GL_GNULIB_PUTS = @GL_GNULIB_PUTS@ +GL_GNULIB_PWRITE = @GL_GNULIB_PWRITE@ +GL_GNULIB_QSORT_R = @GL_GNULIB_QSORT_R@ +GL_GNULIB_RAISE = @GL_GNULIB_RAISE@ +GL_GNULIB_RANDOM = @GL_GNULIB_RANDOM@ +GL_GNULIB_RANDOM_R = @GL_GNULIB_RANDOM_R@ +GL_GNULIB_RAWMEMCHR = @GL_GNULIB_RAWMEMCHR@ +GL_GNULIB_READ = @GL_GNULIB_READ@ +GL_GNULIB_READDIR = @GL_GNULIB_READDIR@ +GL_GNULIB_READLINK = @GL_GNULIB_READLINK@ +GL_GNULIB_READLINKAT = @GL_GNULIB_READLINKAT@ +GL_GNULIB_REALLOCARRAY = @GL_GNULIB_REALLOCARRAY@ +GL_GNULIB_REALLOC_GNU = @GL_GNULIB_REALLOC_GNU@ +GL_GNULIB_REALLOC_POSIX = @GL_GNULIB_REALLOC_POSIX@ +GL_GNULIB_REALPATH = @GL_GNULIB_REALPATH@ +GL_GNULIB_RECV = @GL_GNULIB_RECV@ +GL_GNULIB_RECVFROM = @GL_GNULIB_RECVFROM@ +GL_GNULIB_REMOVE = @GL_GNULIB_REMOVE@ +GL_GNULIB_RENAME = @GL_GNULIB_RENAME@ +GL_GNULIB_RENAMEAT = @GL_GNULIB_RENAMEAT@ +GL_GNULIB_REWINDDIR = @GL_GNULIB_REWINDDIR@ +GL_GNULIB_RMDIR = @GL_GNULIB_RMDIR@ +GL_GNULIB_RPMATCH = @GL_GNULIB_RPMATCH@ +GL_GNULIB_SCANDIR = @GL_GNULIB_SCANDIR@ +GL_GNULIB_SCANF = @GL_GNULIB_SCANF@ +GL_GNULIB_SECURE_GETENV = @GL_GNULIB_SECURE_GETENV@ +GL_GNULIB_SELECT = @GL_GNULIB_SELECT@ +GL_GNULIB_SEND = @GL_GNULIB_SEND@ +GL_GNULIB_SENDTO = @GL_GNULIB_SENDTO@ +GL_GNULIB_SETENV = @GL_GNULIB_SETENV@ +GL_GNULIB_SETHOSTNAME = @GL_GNULIB_SETHOSTNAME@ +GL_GNULIB_SETLOCALE = @GL_GNULIB_SETLOCALE@ +GL_GNULIB_SETLOCALE_NULL = @GL_GNULIB_SETLOCALE_NULL@ +GL_GNULIB_SETSOCKOPT = @GL_GNULIB_SETSOCKOPT@ +GL_GNULIB_SHUTDOWN = @GL_GNULIB_SHUTDOWN@ +GL_GNULIB_SIGABBREV_NP = @GL_GNULIB_SIGABBREV_NP@ +GL_GNULIB_SIGACTION = @GL_GNULIB_SIGACTION@ +GL_GNULIB_SIGDESCR_NP = @GL_GNULIB_SIGDESCR_NP@ +GL_GNULIB_SIGNAL_H_SIGPIPE = @GL_GNULIB_SIGNAL_H_SIGPIPE@ +GL_GNULIB_SIGPROCMASK = @GL_GNULIB_SIGPROCMASK@ +GL_GNULIB_SLEEP = @GL_GNULIB_SLEEP@ +GL_GNULIB_SNPRINTF = @GL_GNULIB_SNPRINTF@ +GL_GNULIB_SOCKET = @GL_GNULIB_SOCKET@ +GL_GNULIB_SPRINTF_POSIX = @GL_GNULIB_SPRINTF_POSIX@ +GL_GNULIB_STAT = @GL_GNULIB_STAT@ +GL_GNULIB_STDIO_H_NONBLOCKING = @GL_GNULIB_STDIO_H_NONBLOCKING@ +GL_GNULIB_STDIO_H_SIGPIPE = @GL_GNULIB_STDIO_H_SIGPIPE@ +GL_GNULIB_STPCPY = @GL_GNULIB_STPCPY@ +GL_GNULIB_STPNCPY = @GL_GNULIB_STPNCPY@ +GL_GNULIB_STRCASESTR = @GL_GNULIB_STRCASESTR@ +GL_GNULIB_STRCHRNUL = @GL_GNULIB_STRCHRNUL@ +GL_GNULIB_STRDUP = @GL_GNULIB_STRDUP@ +GL_GNULIB_STRERROR = @GL_GNULIB_STRERROR@ +GL_GNULIB_STRERRORNAME_NP = @GL_GNULIB_STRERRORNAME_NP@ +GL_GNULIB_STRERROR_R = @GL_GNULIB_STRERROR_R@ +GL_GNULIB_STRFTIME = @GL_GNULIB_STRFTIME@ +GL_GNULIB_STRNCAT = @GL_GNULIB_STRNCAT@ +GL_GNULIB_STRNDUP = @GL_GNULIB_STRNDUP@ +GL_GNULIB_STRNLEN = @GL_GNULIB_STRNLEN@ +GL_GNULIB_STRPBRK = @GL_GNULIB_STRPBRK@ +GL_GNULIB_STRPTIME = @GL_GNULIB_STRPTIME@ +GL_GNULIB_STRSEP = @GL_GNULIB_STRSEP@ +GL_GNULIB_STRSIGNAL = @GL_GNULIB_STRSIGNAL@ +GL_GNULIB_STRSTR = @GL_GNULIB_STRSTR@ +GL_GNULIB_STRTOD = @GL_GNULIB_STRTOD@ +GL_GNULIB_STRTOIMAX = @GL_GNULIB_STRTOIMAX@ +GL_GNULIB_STRTOK_R = @GL_GNULIB_STRTOK_R@ +GL_GNULIB_STRTOL = @GL_GNULIB_STRTOL@ +GL_GNULIB_STRTOLD = @GL_GNULIB_STRTOLD@ +GL_GNULIB_STRTOLL = @GL_GNULIB_STRTOLL@ +GL_GNULIB_STRTOUL = @GL_GNULIB_STRTOUL@ +GL_GNULIB_STRTOULL = @GL_GNULIB_STRTOULL@ +GL_GNULIB_STRTOUMAX = @GL_GNULIB_STRTOUMAX@ +GL_GNULIB_STRVERSCMP = @GL_GNULIB_STRVERSCMP@ +GL_GNULIB_SYMLINK = @GL_GNULIB_SYMLINK@ +GL_GNULIB_SYMLINKAT = @GL_GNULIB_SYMLINKAT@ +GL_GNULIB_SYSTEM_POSIX = @GL_GNULIB_SYSTEM_POSIX@ +GL_GNULIB_TCGETSID = @GL_GNULIB_TCGETSID@ +GL_GNULIB_TIME = @GL_GNULIB_TIME@ +GL_GNULIB_TIMEGM = @GL_GNULIB_TIMEGM@ +GL_GNULIB_TIMESPEC_GET = @GL_GNULIB_TIMESPEC_GET@ +GL_GNULIB_TIMESPEC_GETRES = @GL_GNULIB_TIMESPEC_GETRES@ +GL_GNULIB_TIME_R = @GL_GNULIB_TIME_R@ +GL_GNULIB_TIME_RZ = @GL_GNULIB_TIME_RZ@ +GL_GNULIB_TMPFILE = @GL_GNULIB_TMPFILE@ +GL_GNULIB_TOWCTRANS = @GL_GNULIB_TOWCTRANS@ +GL_GNULIB_TRUNCATE = @GL_GNULIB_TRUNCATE@ +GL_GNULIB_TTYNAME_R = @GL_GNULIB_TTYNAME_R@ +GL_GNULIB_TZSET = @GL_GNULIB_TZSET@ +GL_GNULIB_UNISTD_H_GETOPT = @GL_GNULIB_UNISTD_H_GETOPT@ +GL_GNULIB_UNISTD_H_NONBLOCKING = @GL_GNULIB_UNISTD_H_NONBLOCKING@ +GL_GNULIB_UNISTD_H_SIGPIPE = @GL_GNULIB_UNISTD_H_SIGPIPE@ +GL_GNULIB_UNLINK = @GL_GNULIB_UNLINK@ +GL_GNULIB_UNLINKAT = @GL_GNULIB_UNLINKAT@ +GL_GNULIB_UNLOCKPT = @GL_GNULIB_UNLOCKPT@ +GL_GNULIB_UNSETENV = @GL_GNULIB_UNSETENV@ +GL_GNULIB_USLEEP = @GL_GNULIB_USLEEP@ +GL_GNULIB_UTIME = @GL_GNULIB_UTIME@ +GL_GNULIB_UTIMENSAT = @GL_GNULIB_UTIMENSAT@ +GL_GNULIB_VASPRINTF = @GL_GNULIB_VASPRINTF@ +GL_GNULIB_VDPRINTF = @GL_GNULIB_VDPRINTF@ +GL_GNULIB_VFPRINTF = @GL_GNULIB_VFPRINTF@ +GL_GNULIB_VFPRINTF_POSIX = @GL_GNULIB_VFPRINTF_POSIX@ +GL_GNULIB_VFSCANF = @GL_GNULIB_VFSCANF@ +GL_GNULIB_VPRINTF = @GL_GNULIB_VPRINTF@ +GL_GNULIB_VPRINTF_POSIX = @GL_GNULIB_VPRINTF_POSIX@ +GL_GNULIB_VSCANF = @GL_GNULIB_VSCANF@ +GL_GNULIB_VSNPRINTF = @GL_GNULIB_VSNPRINTF@ +GL_GNULIB_VSPRINTF_POSIX = @GL_GNULIB_VSPRINTF_POSIX@ +GL_GNULIB_WCPCPY = @GL_GNULIB_WCPCPY@ +GL_GNULIB_WCPNCPY = @GL_GNULIB_WCPNCPY@ +GL_GNULIB_WCRTOMB = @GL_GNULIB_WCRTOMB@ +GL_GNULIB_WCSCASECMP = @GL_GNULIB_WCSCASECMP@ +GL_GNULIB_WCSCAT = @GL_GNULIB_WCSCAT@ +GL_GNULIB_WCSCHR = @GL_GNULIB_WCSCHR@ +GL_GNULIB_WCSCMP = @GL_GNULIB_WCSCMP@ +GL_GNULIB_WCSCOLL = @GL_GNULIB_WCSCOLL@ +GL_GNULIB_WCSCPY = @GL_GNULIB_WCSCPY@ +GL_GNULIB_WCSCSPN = @GL_GNULIB_WCSCSPN@ +GL_GNULIB_WCSDUP = @GL_GNULIB_WCSDUP@ +GL_GNULIB_WCSFTIME = @GL_GNULIB_WCSFTIME@ +GL_GNULIB_WCSLEN = @GL_GNULIB_WCSLEN@ +GL_GNULIB_WCSNCASECMP = @GL_GNULIB_WCSNCASECMP@ +GL_GNULIB_WCSNCAT = @GL_GNULIB_WCSNCAT@ +GL_GNULIB_WCSNCMP = @GL_GNULIB_WCSNCMP@ +GL_GNULIB_WCSNCPY = @GL_GNULIB_WCSNCPY@ +GL_GNULIB_WCSNLEN = @GL_GNULIB_WCSNLEN@ +GL_GNULIB_WCSNRTOMBS = @GL_GNULIB_WCSNRTOMBS@ +GL_GNULIB_WCSPBRK = @GL_GNULIB_WCSPBRK@ +GL_GNULIB_WCSRCHR = @GL_GNULIB_WCSRCHR@ +GL_GNULIB_WCSRTOMBS = @GL_GNULIB_WCSRTOMBS@ +GL_GNULIB_WCSSPN = @GL_GNULIB_WCSSPN@ +GL_GNULIB_WCSSTR = @GL_GNULIB_WCSSTR@ +GL_GNULIB_WCSTOK = @GL_GNULIB_WCSTOK@ +GL_GNULIB_WCSWIDTH = @GL_GNULIB_WCSWIDTH@ +GL_GNULIB_WCSXFRM = @GL_GNULIB_WCSXFRM@ +GL_GNULIB_WCTOB = @GL_GNULIB_WCTOB@ +GL_GNULIB_WCTOMB = @GL_GNULIB_WCTOMB@ +GL_GNULIB_WCTRANS = @GL_GNULIB_WCTRANS@ +GL_GNULIB_WCTYPE = @GL_GNULIB_WCTYPE@ +GL_GNULIB_WCWIDTH = @GL_GNULIB_WCWIDTH@ +GL_GNULIB_WMEMCHR = @GL_GNULIB_WMEMCHR@ +GL_GNULIB_WMEMCMP = @GL_GNULIB_WMEMCMP@ +GL_GNULIB_WMEMCPY = @GL_GNULIB_WMEMCPY@ +GL_GNULIB_WMEMMOVE = @GL_GNULIB_WMEMMOVE@ +GL_GNULIB_WMEMPCPY = @GL_GNULIB_WMEMPCPY@ +GL_GNULIB_WMEMSET = @GL_GNULIB_WMEMSET@ +GL_GNULIB_WRITE = @GL_GNULIB_WRITE@ +GL_GNULIB__EXIT = @GL_GNULIB__EXIT@ +GMSGFMT = @GMSGFMT@ +GMSGFMT_015 = @GMSGFMT_015@ +GNULIBHEADERS_OVERRIDE_WINT_T = @GNULIBHEADERS_OVERRIDE_WINT_T@ +GNULIB_GETTIMEOFDAY = @GNULIB_GETTIMEOFDAY@ +GREP = @GREP@ +HARD_LOCALE_LIB = @HARD_LOCALE_LIB@ +HAVE_ACCEPT4 = @HAVE_ACCEPT4@ +HAVE_ALIGNED_ALLOC = @HAVE_ALIGNED_ALLOC@ +HAVE_ALLOCA_H = @HAVE_ALLOCA_H@ +HAVE_ALPHASORT = @HAVE_ALPHASORT@ +HAVE_ATOLL = @HAVE_ATOLL@ +HAVE_BTOWC = @HAVE_BTOWC@ +HAVE_C99_STDINT_H = @HAVE_C99_STDINT_H@ +HAVE_CANONICALIZE_FILE_NAME = @HAVE_CANONICALIZE_FILE_NAME@ +HAVE_CHOWN = @HAVE_CHOWN@ +HAVE_CLOSEDIR = @HAVE_CLOSEDIR@ +HAVE_COPY_FILE_RANGE = @HAVE_COPY_FILE_RANGE@ +HAVE_CRTDEFS_H = @HAVE_CRTDEFS_H@ +HAVE_DECL_DIRFD = @HAVE_DECL_DIRFD@ +HAVE_DECL_ECVT = @HAVE_DECL_ECVT@ +HAVE_DECL_ENVIRON = @HAVE_DECL_ENVIRON@ +HAVE_DECL_EXECVPE = @HAVE_DECL_EXECVPE@ +HAVE_DECL_FCHDIR = @HAVE_DECL_FCHDIR@ +HAVE_DECL_FCLOSEALL = @HAVE_DECL_FCLOSEALL@ +HAVE_DECL_FCVT = @HAVE_DECL_FCVT@ +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_GCVT = @HAVE_DECL_GCVT@ +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 = @HAVE_DECL_GETLOGIN@ +HAVE_DECL_GETLOGIN_R = @HAVE_DECL_GETLOGIN_R@ +HAVE_DECL_GETPAGESIZE = @HAVE_DECL_GETPAGESIZE@ +HAVE_DECL_GETUSERSHELL = @HAVE_DECL_GETUSERSHELL@ +HAVE_DECL_GETW = @HAVE_DECL_GETW@ +HAVE_DECL_IMAXABS = @HAVE_DECL_IMAXABS@ +HAVE_DECL_IMAXDIV = @HAVE_DECL_IMAXDIV@ +HAVE_DECL_INITSTATE = @HAVE_DECL_INITSTATE@ +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_PROGRAM_INVOCATION_NAME = @HAVE_DECL_PROGRAM_INVOCATION_NAME@ +HAVE_DECL_PUTW = @HAVE_DECL_PUTW@ +HAVE_DECL_SETENV = @HAVE_DECL_SETENV@ +HAVE_DECL_SETHOSTNAME = @HAVE_DECL_SETHOSTNAME@ +HAVE_DECL_SETSTATE = @HAVE_DECL_SETSTATE@ +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_TCGETSID = @HAVE_DECL_TCGETSID@ +HAVE_DECL_TRUNCATE = @HAVE_DECL_TRUNCATE@ +HAVE_DECL_TTYNAME_R = @HAVE_DECL_TTYNAME_R@ +HAVE_DECL_UNSETENV = @HAVE_DECL_UNSETENV@ +HAVE_DECL_VSNPRINTF = @HAVE_DECL_VSNPRINTF@ +HAVE_DECL_WCSDUP = @HAVE_DECL_WCSDUP@ +HAVE_DECL_WCTOB = @HAVE_DECL_WCTOB@ +HAVE_DECL_WCWIDTH = @HAVE_DECL_WCWIDTH@ +HAVE_DIRENT_H = @HAVE_DIRENT_H@ +HAVE_DPRINTF = @HAVE_DPRINTF@ +HAVE_DUP3 = @HAVE_DUP3@ +HAVE_DUPLOCALE = @HAVE_DUPLOCALE@ +HAVE_ERROR = @HAVE_ERROR@ +HAVE_ERROR_AT_LINE = @HAVE_ERROR_AT_LINE@ +HAVE_ERROR_H = @HAVE_ERROR_H@ +HAVE_EUIDACCESS = @HAVE_EUIDACCESS@ +HAVE_EXECVPE = @HAVE_EXECVPE@ +HAVE_EXPLICIT_BZERO = @HAVE_EXPLICIT_BZERO@ +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_FLOCK = @HAVE_FLOCK@ +HAVE_FNMATCH = @HAVE_FNMATCH@ +HAVE_FNMATCH_H = @HAVE_FNMATCH_H@ +HAVE_FREELOCALE = @HAVE_FREELOCALE@ +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_GETENTROPY = @HAVE_GETENTROPY@ +HAVE_GETGROUPS = @HAVE_GETGROUPS@ +HAVE_GETHOSTNAME = @HAVE_GETHOSTNAME@ +HAVE_GETLOGIN = @HAVE_GETLOGIN@ +HAVE_GETOPT_H = @HAVE_GETOPT_H@ +HAVE_GETPAGESIZE = @HAVE_GETPAGESIZE@ +HAVE_GETPASS = @HAVE_GETPASS@ +HAVE_GETPROGNAME = @HAVE_GETPROGNAME@ +HAVE_GETRANDOM = @HAVE_GETRANDOM@ +HAVE_GETSUBOPT = @HAVE_GETSUBOPT@ +HAVE_GETTIMEOFDAY = @HAVE_GETTIMEOFDAY@ +HAVE_GETUMASK = @HAVE_GETUMASK@ +HAVE_GLOB = @HAVE_GLOB@ +HAVE_GLOB_H = @HAVE_GLOB_H@ +HAVE_GLOB_PATTERN_P = @HAVE_GLOB_PATTERN_P@ +HAVE_GRANTPT = @HAVE_GRANTPT@ +HAVE_GROUP_MEMBER = @HAVE_GROUP_MEMBER@ +HAVE_ICONV = @HAVE_ICONV@ +HAVE_IMAXABS = @HAVE_IMAXABS@ +HAVE_IMAXDIV = @HAVE_IMAXDIV@ +HAVE_IMAXDIV_T = @HAVE_IMAXDIV_T@ +HAVE_INITSTATE = @HAVE_INITSTATE@ +HAVE_INTTYPES_H = @HAVE_INTTYPES_H@ +HAVE_ISBLANK = @HAVE_ISBLANK@ +HAVE_ISWBLANK = @HAVE_ISWBLANK@ +HAVE_ISWCNTRL = @HAVE_ISWCNTRL@ +HAVE_LANGINFO_ALTMON = @HAVE_LANGINFO_ALTMON@ +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_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_MBTOWC = @HAVE_MBTOWC@ +HAVE_MEMPCPY = @HAVE_MEMPCPY@ +HAVE_MEMSET_EXPLICIT = @HAVE_MEMSET_EXPLICIT@ +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_NEWLOCALE = @HAVE_NEWLOCALE@ +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_MEMALIGN = @HAVE_POSIX_MEMALIGN@ +HAVE_POSIX_OPENPT = @HAVE_POSIX_OPENPT@ +HAVE_POSIX_SIGNALBLOCKING = @HAVE_POSIX_SIGNALBLOCKING@ +HAVE_PREAD = @HAVE_PREAD@ +HAVE_PSELECT = @HAVE_PSELECT@ +HAVE_PTHREAD_SIGMASK = @HAVE_PTHREAD_SIGMASK@ +HAVE_PTSNAME = @HAVE_PTSNAME@ +HAVE_PTSNAME_R = @HAVE_PTSNAME_R@ +HAVE_PWRITE = @HAVE_PWRITE@ +HAVE_QSORT_R = @HAVE_QSORT_R@ +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_REALLOCARRAY = @HAVE_REALLOCARRAY@ +HAVE_REALPATH = @HAVE_REALPATH@ +HAVE_RENAMEAT = @HAVE_RENAMEAT@ +HAVE_REWINDDIR = @HAVE_REWINDDIR@ +HAVE_RPMATCH = @HAVE_RPMATCH@ +HAVE_SA_FAMILY_T = @HAVE_SA_FAMILY_T@ +HAVE_SCANDIR = @HAVE_SCANDIR@ +HAVE_SECURE_GETENV = @HAVE_SECURE_GETENV@ +HAVE_SETENV = @HAVE_SETENV@ +HAVE_SETHOSTNAME = @HAVE_SETHOSTNAME@ +HAVE_SETSTATE = @HAVE_SETSTATE@ +HAVE_SIGABBREV_NP = @HAVE_SIGABBREV_NP@ +HAVE_SIGACTION = @HAVE_SIGACTION@ +HAVE_SIGDESCR_NP = @HAVE_SIGDESCR_NP@ +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_STRERRORNAME_NP = @HAVE_STRERRORNAME_NP@ +HAVE_STRINGS_H = @HAVE_STRINGS_H@ +HAVE_STRPBRK = @HAVE_STRPBRK@ +HAVE_STRPTIME = @HAVE_STRPTIME@ +HAVE_STRSEP = @HAVE_STRSEP@ +HAVE_STRTOD = @HAVE_STRTOD@ +HAVE_STRTOL = @HAVE_STRTOL@ +HAVE_STRTOLD = @HAVE_STRTOLD@ +HAVE_STRTOLL = @HAVE_STRTOLL@ +HAVE_STRTOUL = @HAVE_STRTOUL@ +HAVE_STRTOULL = @HAVE_STRTOULL@ +HAVE_STRUCT_RANDOM_DATA = @HAVE_STRUCT_RANDOM_DATA@ +HAVE_STRUCT_SIGACTION_SA_SIGACTION = @HAVE_STRUCT_SIGACTION_SA_SIGACTION@ +HAVE_STRUCT_SOCKADDR_STORAGE = @HAVE_STRUCT_SOCKADDR_STORAGE@ +HAVE_STRUCT_SOCKADDR_STORAGE_SS_FAMILY = @HAVE_STRUCT_SOCKADDR_STORAGE_SS_FAMILY@ +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_CDEFS_H = @HAVE_SYS_CDEFS_H@ +HAVE_SYS_FILE_H = @HAVE_SYS_FILE_H@ +HAVE_SYS_INTTYPES_H = @HAVE_SYS_INTTYPES_H@ +HAVE_SYS_IOCTL_H = @HAVE_SYS_IOCTL_H@ +HAVE_SYS_LOADAVG_H = @HAVE_SYS_LOADAVG_H@ +HAVE_SYS_PARAM_H = @HAVE_SYS_PARAM_H@ +HAVE_SYS_RANDOM_H = @HAVE_SYS_RANDOM_H@ +HAVE_SYS_SELECT_H = @HAVE_SYS_SELECT_H@ +HAVE_SYS_SOCKET_H = @HAVE_SYS_SOCKET_H@ +HAVE_SYS_TIME_H = @HAVE_SYS_TIME_H@ +HAVE_SYS_TYPES_H = @HAVE_SYS_TYPES_H@ +HAVE_SYS_UIO_H = @HAVE_SYS_UIO_H@ +HAVE_TERMIOS_H = @HAVE_TERMIOS_H@ +HAVE_TIMEGM = @HAVE_TIMEGM@ +HAVE_TIMESPEC_GET = @HAVE_TIMESPEC_GET@ +HAVE_TIMESPEC_GETRES = @HAVE_TIMESPEC_GETRES@ +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_USLEEP = @HAVE_USLEEP@ +HAVE_UTIME = @HAVE_UTIME@ +HAVE_UTIMENSAT = @HAVE_UTIMENSAT@ +HAVE_UTIME_H = @HAVE_UTIME_H@ +HAVE_VASPRINTF = @HAVE_VASPRINTF@ +HAVE_VDPRINTF = @HAVE_VDPRINTF@ +HAVE_VISIBILITY = @HAVE_VISIBILITY@ +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_WCSFTIME = @HAVE_WCSFTIME@ +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_WMEMPCPY = @HAVE_WMEMPCPY@ +HAVE_WMEMSET = @HAVE_WMEMSET@ +HAVE_WS2TCPIP_H = @HAVE_WS2TCPIP_H@ +HAVE_XLOCALE_H = @HAVE_XLOCALE_H@ +HAVE__EXIT = @HAVE__EXIT@ +IGNORE_UNUSED_LIBRARIES_CFLAGS = @IGNORE_UNUSED_LIBRARIES_CFLAGS@ +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@ +LC_COLLATE_IMPLEMENTED = @LC_COLLATE_IMPLEMENTED@ +LC_MONETARY_IMPLEMENTED = @LC_MONETARY_IMPLEMENTED@ +LC_NUMERIC_IMPLEMENTED = @LC_NUMERIC_IMPLEMENTED@ +LC_TIME_IMPLEMENTED = @LC_TIME_IMPLEMENTED@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LEX = @LEX@ +LEXLIB = @LEXLIB@ +LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ +LIBCOMPRESS = @LIBCOMPRESS@ +LIBICONV = @LIBICONV@ +LIBINTL = @LIBINTL@ +LIBMAN_EXPORT_LDFLAGS = @LIBMAN_EXPORT_LDFLAGS@ +LIBMULTITHREAD = @LIBMULTITHREAD@ +LIBOBJS = @LIBOBJS@ +LIBPMULTITHREAD = @LIBPMULTITHREAD@ +LIBPTHREAD = @LIBPTHREAD@ +LIBS = @LIBS@ +LIBSOCKET = @LIBSOCKET@ +LIBSTDTHREAD = @LIBSTDTHREAD@ +LIBTHREAD = @LIBTHREAD@ +LIBTOOL = @LIBTOOL@ +LIB_CLOCK_GETTIME = @LIB_CLOCK_GETTIME@ +LIB_GETLOGIN = @LIB_GETLOGIN@ +LIB_GETRANDOM = @LIB_GETRANDOM@ +LIB_HARD_LOCALE = @LIB_HARD_LOCALE@ +LIB_MBRTOWC = @LIB_MBRTOWC@ +LIB_NANOSLEEP = @LIB_NANOSLEEP@ +LIB_NL_LANGINFO = @LIB_NL_LANGINFO@ +LIB_PTHREAD_SIGMASK = @LIB_PTHREAD_SIGMASK@ +LIB_SCHED_YIELD = @LIB_SCHED_YIELD@ +LIB_SELECT = @LIB_SELECT@ +LIB_SETLOCALE_NULL = @LIB_SETLOCALE_NULL@ +LIMITS_H = @LIMITS_H@ +LINGUAS = @LINGUAS@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LOCALCHARSET_TESTS_ENVIRONMENT = @LOCALCHARSET_TESTS_ENVIRONMENT@ +LOCALENAME_ENHANCE_LOCALE_FUNCS = @LOCALENAME_ENHANCE_LOCALE_FUNCS@ +LOCALE_FR = @LOCALE_FR@ +LOCALE_FR_UTF8 = @LOCALE_FR_UTF8@ +LOCALE_JA = @LOCALE_JA@ +LOCALE_ZH_CN = @LOCALE_ZH_CN@ +LTALLOCA = @LTALLOCA@ +LTLIBICONV = @LTLIBICONV@ +LTLIBINTL = @LTLIBINTL@ +LTLIBMULTITHREAD = @LTLIBMULTITHREAD@ +LTLIBOBJS = @LTLIBOBJS@ +LTLIBTHREAD = @LTLIBTHREAD@ +LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ +MAKEINFO = @MAKEINFO@ +MANDIR_LAYOUT = @MANDIR_LAYOUT@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MAN_SUBDIRS = @MAN_SUBDIRS@ +MBRTOWC_LIB = @MBRTOWC_LIB@ +MKDIR_P = @MKDIR_P@ +MSGFMT = @MSGFMT@ +MSGFMT_015 = @MSGFMT_015@ +MSGMERGE = @MSGMERGE@ +NANOSLEEP_LIB = @NANOSLEEP_LIB@ +NEXT_ASSERT_H = @NEXT_ASSERT_H@ +NEXT_AS_FIRST_DIRECTIVE_ASSERT_H = @NEXT_AS_FIRST_DIRECTIVE_ASSERT_H@ +NEXT_AS_FIRST_DIRECTIVE_CTYPE_H = @NEXT_AS_FIRST_DIRECTIVE_CTYPE_H@ +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_ERROR_H = @NEXT_AS_FIRST_DIRECTIVE_ERROR_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_FNMATCH_H = @NEXT_AS_FIRST_DIRECTIVE_FNMATCH_H@ +NEXT_AS_FIRST_DIRECTIVE_GETOPT_H = @NEXT_AS_FIRST_DIRECTIVE_GETOPT_H@ +NEXT_AS_FIRST_DIRECTIVE_GLOB_H = @NEXT_AS_FIRST_DIRECTIVE_GLOB_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_LIMITS_H = @NEXT_AS_FIRST_DIRECTIVE_LIMITS_H@ +NEXT_AS_FIRST_DIRECTIVE_LOCALE_H = @NEXT_AS_FIRST_DIRECTIVE_LOCALE_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_FILE_H = @NEXT_AS_FIRST_DIRECTIVE_SYS_FILE_H@ +NEXT_AS_FIRST_DIRECTIVE_SYS_IOCTL_H = @NEXT_AS_FIRST_DIRECTIVE_SYS_IOCTL_H@ +NEXT_AS_FIRST_DIRECTIVE_SYS_RANDOM_H = @NEXT_AS_FIRST_DIRECTIVE_SYS_RANDOM_H@ +NEXT_AS_FIRST_DIRECTIVE_SYS_SELECT_H = @NEXT_AS_FIRST_DIRECTIVE_SYS_SELECT_H@ +NEXT_AS_FIRST_DIRECTIVE_SYS_SOCKET_H = @NEXT_AS_FIRST_DIRECTIVE_SYS_SOCKET_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_SYS_UIO_H = @NEXT_AS_FIRST_DIRECTIVE_SYS_UIO_H@ +NEXT_AS_FIRST_DIRECTIVE_TERMIOS_H = @NEXT_AS_FIRST_DIRECTIVE_TERMIOS_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_UTIME_H = @NEXT_AS_FIRST_DIRECTIVE_UTIME_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_CTYPE_H = @NEXT_CTYPE_H@ +NEXT_DIRENT_H = @NEXT_DIRENT_H@ +NEXT_ERRNO_H = @NEXT_ERRNO_H@ +NEXT_ERROR_H = @NEXT_ERROR_H@ +NEXT_FCNTL_H = @NEXT_FCNTL_H@ +NEXT_FLOAT_H = @NEXT_FLOAT_H@ +NEXT_FNMATCH_H = @NEXT_FNMATCH_H@ +NEXT_GETOPT_H = @NEXT_GETOPT_H@ +NEXT_GLOB_H = @NEXT_GLOB_H@ +NEXT_INTTYPES_H = @NEXT_INTTYPES_H@ +NEXT_LANGINFO_H = @NEXT_LANGINFO_H@ +NEXT_LIMITS_H = @NEXT_LIMITS_H@ +NEXT_LOCALE_H = @NEXT_LOCALE_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_FILE_H = @NEXT_SYS_FILE_H@ +NEXT_SYS_IOCTL_H = @NEXT_SYS_IOCTL_H@ +NEXT_SYS_RANDOM_H = @NEXT_SYS_RANDOM_H@ +NEXT_SYS_SELECT_H = @NEXT_SYS_SELECT_H@ +NEXT_SYS_SOCKET_H = @NEXT_SYS_SOCKET_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_SYS_UIO_H = @NEXT_SYS_UIO_H@ +NEXT_TERMIOS_H = @NEXT_TERMIOS_H@ +NEXT_TIME_H = @NEXT_TIME_H@ +NEXT_UNISTD_H = @NEXT_UNISTD_H@ +NEXT_UTIME_H = @NEXT_UTIME_H@ +NEXT_WCHAR_H = @NEXT_WCHAR_H@ +NEXT_WCTYPE_H = @NEXT_WCTYPE_H@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +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@ +PKG_CONFIG = @PKG_CONFIG@ +PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ +PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ +PO4A = @PO4A@ +POSUB = @POSUB@ +PRAGMA_COLUMNS = @PRAGMA_COLUMNS@ +PRAGMA_SYSTEM_HEADER = @PRAGMA_SYSTEM_HEADER@ +PRIPTR_PREFIX = @PRIPTR_PREFIX@ +PTHREAD_H_DEFINES_STRUCT_TIMESPEC = @PTHREAD_H_DEFINES_STRUCT_TIMESPEC@ +PTHREAD_SIGMASK_LIB = @PTHREAD_SIGMASK_LIB@ +PTRDIFF_T_SUFFIX = @PTRDIFF_T_SUFFIX@ +RANLIB = @RANLIB@ +REPLACE_ACCESS = @REPLACE_ACCESS@ +REPLACE_ALIGNED_ALLOC = @REPLACE_ALIGNED_ALLOC@ +REPLACE_BTOWC = @REPLACE_BTOWC@ +REPLACE_CALLOC_FOR_CALLOC_GNU = @REPLACE_CALLOC_FOR_CALLOC_GNU@ +REPLACE_CALLOC_FOR_CALLOC_POSIX = @REPLACE_CALLOC_FOR_CALLOC_POSIX@ +REPLACE_CANONICALIZE_FILE_NAME = @REPLACE_CANONICALIZE_FILE_NAME@ +REPLACE_CHMOD = @REPLACE_CHMOD@ +REPLACE_CHOWN = @REPLACE_CHOWN@ +REPLACE_CLOSE = @REPLACE_CLOSE@ +REPLACE_CLOSEDIR = @REPLACE_CLOSEDIR@ +REPLACE_COPY_FILE_RANGE = @REPLACE_COPY_FILE_RANGE@ +REPLACE_CREAT = @REPLACE_CREAT@ +REPLACE_CTIME = @REPLACE_CTIME@ +REPLACE_DIRFD = @REPLACE_DIRFD@ +REPLACE_DPRINTF = @REPLACE_DPRINTF@ +REPLACE_DUP = @REPLACE_DUP@ +REPLACE_DUP2 = @REPLACE_DUP2@ +REPLACE_DUP3 = @REPLACE_DUP3@ +REPLACE_DUPLOCALE = @REPLACE_DUPLOCALE@ +REPLACE_ERROR = @REPLACE_ERROR@ +REPLACE_ERROR_AT_LINE = @REPLACE_ERROR_AT_LINE@ +REPLACE_EXECL = @REPLACE_EXECL@ +REPLACE_EXECLE = @REPLACE_EXECLE@ +REPLACE_EXECLP = @REPLACE_EXECLP@ +REPLACE_EXECV = @REPLACE_EXECV@ +REPLACE_EXECVE = @REPLACE_EXECVE@ +REPLACE_EXECVP = @REPLACE_EXECVP@ +REPLACE_EXECVPE = @REPLACE_EXECVPE@ +REPLACE_FACCESSAT = @REPLACE_FACCESSAT@ +REPLACE_FCHMODAT = @REPLACE_FCHMODAT@ +REPLACE_FCHOWNAT = @REPLACE_FCHOWNAT@ +REPLACE_FCLOSE = @REPLACE_FCLOSE@ +REPLACE_FCNTL = @REPLACE_FCNTL@ +REPLACE_FDATASYNC = @REPLACE_FDATASYNC@ +REPLACE_FDOPEN = @REPLACE_FDOPEN@ +REPLACE_FDOPENDIR = @REPLACE_FDOPENDIR@ +REPLACE_FFLUSH = @REPLACE_FFLUSH@ +REPLACE_FFSLL = @REPLACE_FFSLL@ +REPLACE_FNMATCH = @REPLACE_FNMATCH@ +REPLACE_FOPEN = @REPLACE_FOPEN@ +REPLACE_FOPEN_FOR_FOPEN_GNU = @REPLACE_FOPEN_FOR_FOPEN_GNU@ +REPLACE_FPRINTF = @REPLACE_FPRINTF@ +REPLACE_FPURGE = @REPLACE_FPURGE@ +REPLACE_FREE = @REPLACE_FREE@ +REPLACE_FREELOCALE = @REPLACE_FREELOCALE@ +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_GETENTROPY = @REPLACE_GETENTROPY@ +REPLACE_GETGROUPS = @REPLACE_GETGROUPS@ +REPLACE_GETLINE = @REPLACE_GETLINE@ +REPLACE_GETLOADAVG = @REPLACE_GETLOADAVG@ +REPLACE_GETLOGIN_R = @REPLACE_GETLOGIN_R@ +REPLACE_GETPAGESIZE = @REPLACE_GETPAGESIZE@ +REPLACE_GETPASS = @REPLACE_GETPASS@ +REPLACE_GETPASS_FOR_GETPASS_GNU = @REPLACE_GETPASS_FOR_GETPASS_GNU@ +REPLACE_GETPROGNAME = @REPLACE_GETPROGNAME@ +REPLACE_GETRANDOM = @REPLACE_GETRANDOM@ +REPLACE_GETSUBOPT = @REPLACE_GETSUBOPT@ +REPLACE_GETTIMEOFDAY = @REPLACE_GETTIMEOFDAY@ +REPLACE_GLOB = @REPLACE_GLOB@ +REPLACE_GLOB_PATTERN_P = @REPLACE_GLOB_PATTERN_P@ +REPLACE_GMTIME = @REPLACE_GMTIME@ +REPLACE_IMAXABS = @REPLACE_IMAXABS@ +REPLACE_IMAXDIV = @REPLACE_IMAXDIV@ +REPLACE_INITSTATE = @REPLACE_INITSTATE@ +REPLACE_IOCTL = @REPLACE_IOCTL@ +REPLACE_ISATTY = @REPLACE_ISATTY@ +REPLACE_ISWBLANK = @REPLACE_ISWBLANK@ +REPLACE_ISWCNTRL = @REPLACE_ISWCNTRL@ +REPLACE_ISWDIGIT = @REPLACE_ISWDIGIT@ +REPLACE_ISWXDIGIT = @REPLACE_ISWXDIGIT@ +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_FOR_MALLOC_GNU = @REPLACE_MALLOC_FOR_MALLOC_GNU@ +REPLACE_MALLOC_FOR_MALLOC_POSIX = @REPLACE_MALLOC_FOR_MALLOC_POSIX@ +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_MBSTOWCS = @REPLACE_MBSTOWCS@ +REPLACE_MBTOWC = @REPLACE_MBTOWC@ +REPLACE_MB_CUR_MAX = @REPLACE_MB_CUR_MAX@ +REPLACE_MEMCHR = @REPLACE_MEMCHR@ +REPLACE_MEMMEM = @REPLACE_MEMMEM@ +REPLACE_MEMPCPY = @REPLACE_MEMPCPY@ +REPLACE_MKDIR = @REPLACE_MKDIR@ +REPLACE_MKFIFO = @REPLACE_MKFIFO@ +REPLACE_MKFIFOAT = @REPLACE_MKFIFOAT@ +REPLACE_MKNOD = @REPLACE_MKNOD@ +REPLACE_MKNODAT = @REPLACE_MKNODAT@ +REPLACE_MKOSTEMP = @REPLACE_MKOSTEMP@ +REPLACE_MKOSTEMPS = @REPLACE_MKOSTEMPS@ +REPLACE_MKSTEMP = @REPLACE_MKSTEMP@ +REPLACE_MKTIME = @REPLACE_MKTIME@ +REPLACE_NANOSLEEP = @REPLACE_NANOSLEEP@ +REPLACE_NEWLOCALE = @REPLACE_NEWLOCALE@ +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_PIPE2 = @REPLACE_PIPE2@ +REPLACE_POPEN = @REPLACE_POPEN@ +REPLACE_POSIX_MEMALIGN = @REPLACE_POSIX_MEMALIGN@ +REPLACE_POSIX_OPENPT = @REPLACE_POSIX_OPENPT@ +REPLACE_PREAD = @REPLACE_PREAD@ +REPLACE_PRINTF = @REPLACE_PRINTF@ +REPLACE_PSELECT = @REPLACE_PSELECT@ +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 = @REPLACE_RANDOM@ +REPLACE_RANDOM_R = @REPLACE_RANDOM_R@ +REPLACE_READ = @REPLACE_READ@ +REPLACE_READDIR = @REPLACE_READDIR@ +REPLACE_READLINK = @REPLACE_READLINK@ +REPLACE_READLINKAT = @REPLACE_READLINKAT@ +REPLACE_REALLOCARRAY = @REPLACE_REALLOCARRAY@ +REPLACE_REALLOC_FOR_REALLOC_GNU = @REPLACE_REALLOC_FOR_REALLOC_GNU@ +REPLACE_REALLOC_FOR_REALLOC_POSIX = @REPLACE_REALLOC_FOR_REALLOC_POSIX@ +REPLACE_REALPATH = @REPLACE_REALPATH@ +REPLACE_REMOVE = @REPLACE_REMOVE@ +REPLACE_RENAME = @REPLACE_RENAME@ +REPLACE_RENAMEAT = @REPLACE_RENAMEAT@ +REPLACE_REWINDDIR = @REPLACE_REWINDDIR@ +REPLACE_RMDIR = @REPLACE_RMDIR@ +REPLACE_SELECT = @REPLACE_SELECT@ +REPLACE_SETENV = @REPLACE_SETENV@ +REPLACE_SETHOSTNAME = @REPLACE_SETHOSTNAME@ +REPLACE_SETLOCALE = @REPLACE_SETLOCALE@ +REPLACE_SETSTATE = @REPLACE_SETSTATE@ +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_STPCPY = @REPLACE_STPCPY@ +REPLACE_STPNCPY = @REPLACE_STPNCPY@ +REPLACE_STRCASESTR = @REPLACE_STRCASESTR@ +REPLACE_STRCHRNUL = @REPLACE_STRCHRNUL@ +REPLACE_STRDUP = @REPLACE_STRDUP@ +REPLACE_STRERROR = @REPLACE_STRERROR@ +REPLACE_STRERRORNAME_NP = @REPLACE_STRERRORNAME_NP@ +REPLACE_STRERROR_R = @REPLACE_STRERROR_R@ +REPLACE_STRFTIME = @REPLACE_STRFTIME@ +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_STRTOL = @REPLACE_STRTOL@ +REPLACE_STRTOLD = @REPLACE_STRTOLD@ +REPLACE_STRTOLL = @REPLACE_STRTOLL@ +REPLACE_STRTOUL = @REPLACE_STRTOUL@ +REPLACE_STRTOULL = @REPLACE_STRTOULL@ +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_TIME = @REPLACE_TIME@ +REPLACE_TIMEGM = @REPLACE_TIMEGM@ +REPLACE_TIMESPEC_GET = @REPLACE_TIMESPEC_GET@ +REPLACE_TMPFILE = @REPLACE_TMPFILE@ +REPLACE_TOWLOWER = @REPLACE_TOWLOWER@ +REPLACE_TRUNCATE = @REPLACE_TRUNCATE@ +REPLACE_TTYNAME_R = @REPLACE_TTYNAME_R@ +REPLACE_TZSET = @REPLACE_TZSET@ +REPLACE_UNLINK = @REPLACE_UNLINK@ +REPLACE_UNLINKAT = @REPLACE_UNLINKAT@ +REPLACE_UNSETENV = @REPLACE_UNSETENV@ +REPLACE_USLEEP = @REPLACE_USLEEP@ +REPLACE_UTIME = @REPLACE_UTIME@ +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_WCSCMP = @REPLACE_WCSCMP@ +REPLACE_WCSFTIME = @REPLACE_WCSFTIME@ +REPLACE_WCSNCMP = @REPLACE_WCSNCMP@ +REPLACE_WCSNRTOMBS = @REPLACE_WCSNRTOMBS@ +REPLACE_WCSRTOMBS = @REPLACE_WCSRTOMBS@ +REPLACE_WCSSTR = @REPLACE_WCSSTR@ +REPLACE_WCSTOK = @REPLACE_WCSTOK@ +REPLACE_WCSWIDTH = @REPLACE_WCSWIDTH@ +REPLACE_WCTOB = @REPLACE_WCTOB@ +REPLACE_WCTOMB = @REPLACE_WCTOMB@ +REPLACE_WCWIDTH = @REPLACE_WCWIDTH@ +REPLACE_WMEMCMP = @REPLACE_WMEMCMP@ +REPLACE_WMEMPCPY = @REPLACE_WMEMPCPY@ +REPLACE_WRITE = @REPLACE_WRITE@ +REPLACE__EXIT = @REPLACE__EXIT@ +SCHED_YIELD_LIB = @SCHED_YIELD_LIB@ +SED = @SED@ +SELECT_LIB = @SELECT_LIB@ +SETLOCALE_NULL_LIB = @SETLOCALE_NULL_LIB@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +SIG_ATOMIC_T_SUFFIX = @SIG_ATOMIC_T_SUFFIX@ +SIZE_T_SUFFIX = @SIZE_T_SUFFIX@ +STDARG_H = @STDARG_H@ +STDCKDINT_H = @STDCKDINT_H@ +STDDEF_H = @STDDEF_H@ +STDINT_H = @STDINT_H@ +STRIP = @STRIP@ +SYSEXITS_H = @SYSEXITS_H@ +SYS_IOCTL_H_HAVE_WINSOCK2_H = @SYS_IOCTL_H_HAVE_WINSOCK2_H@ +SYS_IOCTL_H_HAVE_WINSOCK2_H_AND_USE_SOCKETS = @SYS_IOCTL_H_HAVE_WINSOCK2_H_AND_USE_SOCKETS@ +SYS_TIME_H_DEFINES_STRUCT_TIMESPEC = @SYS_TIME_H_DEFINES_STRUCT_TIMESPEC@ +TBL_X_FORMAT = @TBL_X_FORMAT@ +TIME_H_DEFINES_STRUCT_TIMESPEC = @TIME_H_DEFINES_STRUCT_TIMESPEC@ +TIME_H_DEFINES_TIME_UTC = @TIME_H_DEFINES_TIME_UTC@ +TRANS_APROPOS = @TRANS_APROPOS@ +TRANS_APROPOS_UPPER = @TRANS_APROPOS_UPPER@ +TRANS_CATMAN = @TRANS_CATMAN@ +TRANS_CATMAN_UPPER = @TRANS_CATMAN_UPPER@ +TRANS_LEXGROG = @TRANS_LEXGROG@ +TRANS_LEXGROG_UPPER = @TRANS_LEXGROG_UPPER@ +TRANS_MAN = @TRANS_MAN@ +TRANS_MANCONV = @TRANS_MANCONV@ +TRANS_MANCONV_UPPER = @TRANS_MANCONV_UPPER@ +TRANS_MANDB = @TRANS_MANDB@ +TRANS_MANDB_UPPER = @TRANS_MANDB_UPPER@ +TRANS_MANPATH = @TRANS_MANPATH@ +TRANS_MANPATH_UPPER = @TRANS_MANPATH_UPPER@ +TRANS_MAN_RECODE = @TRANS_MAN_RECODE@ +TRANS_MAN_RECODE_UPPER = @TRANS_MAN_RECODE_UPPER@ +TRANS_MAN_UPPER = @TRANS_MAN_UPPER@ +TRANS_WHATIS = @TRANS_WHATIS@ +TRANS_WHATIS_UPPER = @TRANS_WHATIS_UPPER@ +TRANS_ZSOELIM = @TRANS_ZSOELIM@ +TRANS_ZSOELIM_UPPER = @TRANS_ZSOELIM_UPPER@ +TROFF = @TROFF@ +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_SYS_RANDOM_H = @UNISTD_H_HAVE_SYS_RANDOM_H@ +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_NLS = @USE_NLS@ +VERSION = @VERSION@ +WARN_CFLAGS = @WARN_CFLAGS@ +WCHAR_T_SUFFIX = @WCHAR_T_SUFFIX@ +WINDOWS_64_BIT_OFF_T = @WINDOWS_64_BIT_OFF_T@ +WINDOWS_64_BIT_ST_SIZE = @WINDOWS_64_BIT_ST_SIZE@ +WINDOWS_STAT_INODES = @WINDOWS_STAT_INODES@ +WINDOWS_STAT_TIMESPEC = @WINDOWS_STAT_TIMESPEC@ +WINT_T_SUFFIX = @WINT_T_SUFFIX@ +XGETTEXT = @XGETTEXT@ +XGETTEXT_015 = @XGETTEXT_015@ +XGETTEXT_EXTRA_OPTIONS = @XGETTEXT_EXTRA_OPTIONS@ +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@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +browser = @browser@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +bzip2 = @bzip2@ +cache_top_owner = @cache_top_owner@ +cat = @cat@ +col = @col@ +compress = @compress@ +compressor = @compressor@ +config_file = @config_file@ +config_file_basename = @config_file_basename@ +config_file_dirname = @config_file_dirname@ +datadir = @datadir@ +datarootdir = @datarootdir@ +date = @date@ +docdir = @docdir@ +dvidir = @dvidir@ +eqn = @eqn@ +exec_prefix = @exec_prefix@ +gl_LIBOBJDEPS = @gl_LIBOBJDEPS@ +gl_LIBOBJS = @gl_LIBOBJS@ +gl_LTLIBOBJS = @gl_LTLIBOBJS@ +gltests_LIBOBJDEPS = @gltests_LIBOBJDEPS@ +gltests_LIBOBJS = @gltests_LIBOBJS@ +gltests_LTLIBOBJS = @gltests_LTLIBOBJS@ +gltests_WITNESS = @gltests_WITNESS@ +grap = @grap@ +grep = @grep@ +gzip = @gzip@ +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@ +libpipeline_CFLAGS = @libpipeline_CFLAGS@ +libpipeline_LIBS = @libpipeline_LIBS@ +libseccomp_CFLAGS = @libseccomp_CFLAGS@ +libseccomp_LIBS = @libseccomp_LIBS@ +localedir = @localedir@ +localstatedir = @localstatedir@ +lzip = @lzip@ +lzma = @lzma@ +man_mode = @man_mode@ +man_owner = @man_owner@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +neqn = @neqn@ +nroff = @nroff@ +oldincludedir = @oldincludedir@ +override_dir = @override_dir@ +pager = @pager@ +pdfdir = @pdfdir@ +pic = @pic@ +preconv = @preconv@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +refer = @refer@ +roff_version = @roff_version@ +runstatedir = @runstatedir@ +sbindir = @sbindir@ +sections = @sections@ +sharedstatedir = @sharedstatedir@ +snapdir = @snapdir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +systemdsystemunitdir = @systemdsystemunitdir@ +systemdtmpfilesdir = @systemdtmpfilesdir@ +target_alias = @target_alias@ +tbl = @tbl@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +tr = @tr@ +troff = @troff@ +troff_as_troff_input = @troff_as_troff_input@ +troff_is_groff = @troff_is_groff@ +vgrind = @vgrind@ +xz = @xz@ +zstd = @zstd@ +pkglib_LTLIBRARIES = libman.la +dist_noinst_DATA = README +AM_CFLAGS = $(WARN_CFLAGS) +libman_la_CPPFLAGS = \ + -I$(top_srcdir)/include \ + -I$(top_srcdir)/gl/lib \ + -I$(top_builddir)/gl/lib \ + -DLOCALEDIR=\"$(localedir)\" \ + $(libseccomp_CFLAGS) + +libman_la_SOURCES = \ + appendstr.c \ + appendstr.h \ + cleanup.c \ + cleanup.h \ + compression.c \ + compression.h \ + debug.c \ + debug.h \ + encodings.c \ + encodings.h \ + fatal.c \ + fatal.h \ + filenames.c \ + filenames.h \ + glcontainers.c \ + glcontainers.h \ + linelength.c \ + linelength.h \ + mp.h \ + orderfiles.c \ + orderfiles.h \ + pathsearch.c \ + pathsearch.h \ + sandbox.c \ + sandbox.h \ + security.c \ + security.h \ + tempfile.c \ + tempfile.h \ + util.c \ + util.h \ + wordfnmatch.c \ + wordfnmatch.h \ + xregcomp.c \ + xregcomp.h + +libman_la_LIBADD = ../gl/lib/libgnu.la $(LTLIBOBJS) \ + @LTLIBINTL@ + +libman_la_LDFLAGS = \ + -avoid-version -release $(VERSION) -rpath $(pkglibdir) \ + -no-undefined \ + $(LIBMAN_EXPORT_LDFLAGS) \ + $(libseccomp_LIBS) + +all: all-am + +.SUFFIXES: +.SUFFIXES: .c .lo .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) --foreign lib/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --foreign lib/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__maybe_remake_depfiles)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ + 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): + +install-pkglibLTLIBRARIES: $(pkglib_LTLIBRARIES) + @$(NORMAL_INSTALL) + @list='$(pkglib_LTLIBRARIES)'; test -n "$(pkglibdir)" || list=; \ + list2=; for p in $$list; do \ + if test -f $$p; then \ + list2="$$list2 $$p"; \ + else :; fi; \ + done; \ + test -z "$$list2" || { \ + echo " $(MKDIR_P) '$(DESTDIR)$(pkglibdir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(pkglibdir)" || exit 1; \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(pkglibdir)'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(pkglibdir)"; \ + } + +uninstall-pkglibLTLIBRARIES: + @$(NORMAL_UNINSTALL) + @list='$(pkglib_LTLIBRARIES)'; test -n "$(pkglibdir)" || list=; \ + for p in $$list; do \ + $(am__strip_dir) \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(pkglibdir)/$$f'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(pkglibdir)/$$f"; \ + done + +clean-pkglibLTLIBRARIES: + -test -z "$(pkglib_LTLIBRARIES)" || rm -f $(pkglib_LTLIBRARIES) + @list='$(pkglib_LTLIBRARIES)'; \ + locs=`for p in $$list; do echo $$p; done | \ + sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ + sort -u`; \ + test -z "$$locs" || { \ + echo rm -f $${locs}; \ + rm -f $${locs}; \ + } + +libman.la: $(libman_la_OBJECTS) $(libman_la_DEPENDENCIES) $(EXTRA_libman_la_DEPENDENCIES) + $(AM_V_CCLD)$(libman_la_LINK) -rpath $(pkglibdir) $(libman_la_OBJECTS) $(libman_la_LIBADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libman_la-appendstr.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libman_la-cleanup.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libman_la-compression.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libman_la-debug.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libman_la-encodings.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libman_la-fatal.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libman_la-filenames.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libman_la-glcontainers.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libman_la-linelength.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libman_la-orderfiles.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libman_la-pathsearch.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libman_la-sandbox.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libman_la-security.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libman_la-tempfile.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libman_la-util.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libman_la-wordfnmatch.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libman_la-xregcomp.Plo@am__quote@ # am--include-marker + +$(am__depfiles_remade): + @$(MKDIR_P) $(@D) + @echo '# dummy' >$@-t && $(am__mv) $@-t $@ + +am--depfiles: $(am__depfiles_remade) + +.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) '$<'` + +.c.lo: +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< + +libman_la-appendstr.lo: appendstr.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libman_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libman_la-appendstr.lo -MD -MP -MF $(DEPDIR)/libman_la-appendstr.Tpo -c -o libman_la-appendstr.lo `test -f 'appendstr.c' || echo '$(srcdir)/'`appendstr.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libman_la-appendstr.Tpo $(DEPDIR)/libman_la-appendstr.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='appendstr.c' object='libman_la-appendstr.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libman_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libman_la-appendstr.lo `test -f 'appendstr.c' || echo '$(srcdir)/'`appendstr.c + +libman_la-cleanup.lo: cleanup.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libman_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libman_la-cleanup.lo -MD -MP -MF $(DEPDIR)/libman_la-cleanup.Tpo -c -o libman_la-cleanup.lo `test -f 'cleanup.c' || echo '$(srcdir)/'`cleanup.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libman_la-cleanup.Tpo $(DEPDIR)/libman_la-cleanup.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cleanup.c' object='libman_la-cleanup.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libman_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libman_la-cleanup.lo `test -f 'cleanup.c' || echo '$(srcdir)/'`cleanup.c + +libman_la-compression.lo: compression.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libman_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libman_la-compression.lo -MD -MP -MF $(DEPDIR)/libman_la-compression.Tpo -c -o libman_la-compression.lo `test -f 'compression.c' || echo '$(srcdir)/'`compression.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libman_la-compression.Tpo $(DEPDIR)/libman_la-compression.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='compression.c' object='libman_la-compression.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libman_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libman_la-compression.lo `test -f 'compression.c' || echo '$(srcdir)/'`compression.c + +libman_la-debug.lo: debug.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libman_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libman_la-debug.lo -MD -MP -MF $(DEPDIR)/libman_la-debug.Tpo -c -o libman_la-debug.lo `test -f 'debug.c' || echo '$(srcdir)/'`debug.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libman_la-debug.Tpo $(DEPDIR)/libman_la-debug.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='debug.c' object='libman_la-debug.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libman_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libman_la-debug.lo `test -f 'debug.c' || echo '$(srcdir)/'`debug.c + +libman_la-encodings.lo: encodings.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libman_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libman_la-encodings.lo -MD -MP -MF $(DEPDIR)/libman_la-encodings.Tpo -c -o libman_la-encodings.lo `test -f 'encodings.c' || echo '$(srcdir)/'`encodings.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libman_la-encodings.Tpo $(DEPDIR)/libman_la-encodings.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='encodings.c' object='libman_la-encodings.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libman_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libman_la-encodings.lo `test -f 'encodings.c' || echo '$(srcdir)/'`encodings.c + +libman_la-fatal.lo: fatal.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libman_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libman_la-fatal.lo -MD -MP -MF $(DEPDIR)/libman_la-fatal.Tpo -c -o libman_la-fatal.lo `test -f 'fatal.c' || echo '$(srcdir)/'`fatal.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libman_la-fatal.Tpo $(DEPDIR)/libman_la-fatal.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='fatal.c' object='libman_la-fatal.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libman_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libman_la-fatal.lo `test -f 'fatal.c' || echo '$(srcdir)/'`fatal.c + +libman_la-filenames.lo: filenames.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libman_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libman_la-filenames.lo -MD -MP -MF $(DEPDIR)/libman_la-filenames.Tpo -c -o libman_la-filenames.lo `test -f 'filenames.c' || echo '$(srcdir)/'`filenames.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libman_la-filenames.Tpo $(DEPDIR)/libman_la-filenames.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='filenames.c' object='libman_la-filenames.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libman_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libman_la-filenames.lo `test -f 'filenames.c' || echo '$(srcdir)/'`filenames.c + +libman_la-glcontainers.lo: glcontainers.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libman_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libman_la-glcontainers.lo -MD -MP -MF $(DEPDIR)/libman_la-glcontainers.Tpo -c -o libman_la-glcontainers.lo `test -f 'glcontainers.c' || echo '$(srcdir)/'`glcontainers.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libman_la-glcontainers.Tpo $(DEPDIR)/libman_la-glcontainers.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='glcontainers.c' object='libman_la-glcontainers.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libman_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libman_la-glcontainers.lo `test -f 'glcontainers.c' || echo '$(srcdir)/'`glcontainers.c + +libman_la-linelength.lo: linelength.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libman_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libman_la-linelength.lo -MD -MP -MF $(DEPDIR)/libman_la-linelength.Tpo -c -o libman_la-linelength.lo `test -f 'linelength.c' || echo '$(srcdir)/'`linelength.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libman_la-linelength.Tpo $(DEPDIR)/libman_la-linelength.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='linelength.c' object='libman_la-linelength.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libman_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libman_la-linelength.lo `test -f 'linelength.c' || echo '$(srcdir)/'`linelength.c + +libman_la-orderfiles.lo: orderfiles.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libman_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libman_la-orderfiles.lo -MD -MP -MF $(DEPDIR)/libman_la-orderfiles.Tpo -c -o libman_la-orderfiles.lo `test -f 'orderfiles.c' || echo '$(srcdir)/'`orderfiles.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libman_la-orderfiles.Tpo $(DEPDIR)/libman_la-orderfiles.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='orderfiles.c' object='libman_la-orderfiles.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libman_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libman_la-orderfiles.lo `test -f 'orderfiles.c' || echo '$(srcdir)/'`orderfiles.c + +libman_la-pathsearch.lo: pathsearch.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libman_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libman_la-pathsearch.lo -MD -MP -MF $(DEPDIR)/libman_la-pathsearch.Tpo -c -o libman_la-pathsearch.lo `test -f 'pathsearch.c' || echo '$(srcdir)/'`pathsearch.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libman_la-pathsearch.Tpo $(DEPDIR)/libman_la-pathsearch.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pathsearch.c' object='libman_la-pathsearch.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libman_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libman_la-pathsearch.lo `test -f 'pathsearch.c' || echo '$(srcdir)/'`pathsearch.c + +libman_la-sandbox.lo: sandbox.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libman_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libman_la-sandbox.lo -MD -MP -MF $(DEPDIR)/libman_la-sandbox.Tpo -c -o libman_la-sandbox.lo `test -f 'sandbox.c' || echo '$(srcdir)/'`sandbox.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libman_la-sandbox.Tpo $(DEPDIR)/libman_la-sandbox.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='sandbox.c' object='libman_la-sandbox.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libman_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libman_la-sandbox.lo `test -f 'sandbox.c' || echo '$(srcdir)/'`sandbox.c + +libman_la-security.lo: security.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libman_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libman_la-security.lo -MD -MP -MF $(DEPDIR)/libman_la-security.Tpo -c -o libman_la-security.lo `test -f 'security.c' || echo '$(srcdir)/'`security.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libman_la-security.Tpo $(DEPDIR)/libman_la-security.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='security.c' object='libman_la-security.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libman_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libman_la-security.lo `test -f 'security.c' || echo '$(srcdir)/'`security.c + +libman_la-tempfile.lo: tempfile.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libman_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libman_la-tempfile.lo -MD -MP -MF $(DEPDIR)/libman_la-tempfile.Tpo -c -o libman_la-tempfile.lo `test -f 'tempfile.c' || echo '$(srcdir)/'`tempfile.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libman_la-tempfile.Tpo $(DEPDIR)/libman_la-tempfile.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='tempfile.c' object='libman_la-tempfile.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libman_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libman_la-tempfile.lo `test -f 'tempfile.c' || echo '$(srcdir)/'`tempfile.c + +libman_la-util.lo: util.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libman_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libman_la-util.lo -MD -MP -MF $(DEPDIR)/libman_la-util.Tpo -c -o libman_la-util.lo `test -f 'util.c' || echo '$(srcdir)/'`util.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libman_la-util.Tpo $(DEPDIR)/libman_la-util.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='util.c' object='libman_la-util.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libman_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libman_la-util.lo `test -f 'util.c' || echo '$(srcdir)/'`util.c + +libman_la-wordfnmatch.lo: wordfnmatch.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libman_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libman_la-wordfnmatch.lo -MD -MP -MF $(DEPDIR)/libman_la-wordfnmatch.Tpo -c -o libman_la-wordfnmatch.lo `test -f 'wordfnmatch.c' || echo '$(srcdir)/'`wordfnmatch.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libman_la-wordfnmatch.Tpo $(DEPDIR)/libman_la-wordfnmatch.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='wordfnmatch.c' object='libman_la-wordfnmatch.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libman_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libman_la-wordfnmatch.lo `test -f 'wordfnmatch.c' || echo '$(srcdir)/'`wordfnmatch.c + +libman_la-xregcomp.lo: xregcomp.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libman_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libman_la-xregcomp.lo -MD -MP -MF $(DEPDIR)/libman_la-xregcomp.Tpo -c -o libman_la-xregcomp.lo `test -f 'xregcomp.c' || echo '$(srcdir)/'`xregcomp.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libman_la-xregcomp.Tpo $(DEPDIR)/libman_la-xregcomp.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='xregcomp.c' object='libman_la-xregcomp.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libman_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libman_la-xregcomp.lo `test -f 'xregcomp.c' || echo '$(srcdir)/'`xregcomp.c + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +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: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) distdir-am + +distdir-am: $(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: check-am +all-am: Makefile $(LTLIBRARIES) $(DATA) +installdirs: + for dir in "$(DESTDIR)$(pkglibdir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +install: 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: + +clean-generic: + +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." +clean: clean-am + +clean-am: clean-generic clean-libtool clean-pkglibLTLIBRARIES \ + mostlyclean-am + +distclean: distclean-am + -rm -f ./$(DEPDIR)/libman_la-appendstr.Plo + -rm -f ./$(DEPDIR)/libman_la-cleanup.Plo + -rm -f ./$(DEPDIR)/libman_la-compression.Plo + -rm -f ./$(DEPDIR)/libman_la-debug.Plo + -rm -f ./$(DEPDIR)/libman_la-encodings.Plo + -rm -f ./$(DEPDIR)/libman_la-fatal.Plo + -rm -f ./$(DEPDIR)/libman_la-filenames.Plo + -rm -f ./$(DEPDIR)/libman_la-glcontainers.Plo + -rm -f ./$(DEPDIR)/libman_la-linelength.Plo + -rm -f ./$(DEPDIR)/libman_la-orderfiles.Plo + -rm -f ./$(DEPDIR)/libman_la-pathsearch.Plo + -rm -f ./$(DEPDIR)/libman_la-sandbox.Plo + -rm -f ./$(DEPDIR)/libman_la-security.Plo + -rm -f ./$(DEPDIR)/libman_la-tempfile.Plo + -rm -f ./$(DEPDIR)/libman_la-util.Plo + -rm -f ./$(DEPDIR)/libman_la-wordfnmatch.Plo + -rm -f ./$(DEPDIR)/libman_la-xregcomp.Plo + -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-pkglibLTLIBRARIES + +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 -f ./$(DEPDIR)/libman_la-appendstr.Plo + -rm -f ./$(DEPDIR)/libman_la-cleanup.Plo + -rm -f ./$(DEPDIR)/libman_la-compression.Plo + -rm -f ./$(DEPDIR)/libman_la-debug.Plo + -rm -f ./$(DEPDIR)/libman_la-encodings.Plo + -rm -f ./$(DEPDIR)/libman_la-fatal.Plo + -rm -f ./$(DEPDIR)/libman_la-filenames.Plo + -rm -f ./$(DEPDIR)/libman_la-glcontainers.Plo + -rm -f ./$(DEPDIR)/libman_la-linelength.Plo + -rm -f ./$(DEPDIR)/libman_la-orderfiles.Plo + -rm -f ./$(DEPDIR)/libman_la-pathsearch.Plo + -rm -f ./$(DEPDIR)/libman_la-sandbox.Plo + -rm -f ./$(DEPDIR)/libman_la-security.Plo + -rm -f ./$(DEPDIR)/libman_la-tempfile.Plo + -rm -f ./$(DEPDIR)/libman_la-util.Plo + -rm -f ./$(DEPDIR)/libman_la-wordfnmatch.Plo + -rm -f ./$(DEPDIR)/libman_la-xregcomp.Plo + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-pkglibLTLIBRARIES + +.MAKE: install-am install-strip + +.PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ + clean-generic clean-libtool clean-pkglibLTLIBRARIES \ + cscopelist-am ctags ctags-am distclean distclean-compile \ + distclean-generic distclean-libtool 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-pkglibLTLIBRARIES install-ps \ + install-ps-am install-strip installcheck installcheck-am \ + installdirs maintainer-clean maintainer-clean-generic \ + mostlyclean mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool pdf pdf-am ps ps-am tags tags-am uninstall \ + uninstall-am uninstall-pkglibLTLIBRARIES + +.PRECIOUS: Makefile + + +# 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/README b/lib/README new file mode 100644 index 0000000..6a99120 --- /dev/null +++ b/lib/README @@ -0,0 +1,23 @@ +These library source files have various authors and specific licenses, +but may all be used as part of a complete work that is distributed under +the terms of the GNU General Public License version 2 or later. + +See the files ../docs/COPYING.GPLv2 and ../docs/COPYING.LIB for relevant +information. + +appendstr.* author - Markus Armbruster +cleanup.* author - Markus Armbruster, Colin Watson +compression.* author - Wilf., Colin Watson +debug.* author - Colin Watson +encodings.* author - Colin Watson +glcontainers.* author - Colin Watson +linelength.* author - Martin Schulze, Jon Tombs, Colin Watson +mp.h author - Simon Tatham +orderfiles.* author - Colin Watson +pathsearch.* author - Colin Watson +sandbox.* author - Colin Watson +security.* author - John W. Eaton, Wilf., Colin Watson +tempfile.* author - Colin Watson +util.* author - John W. Eaton, Wilf., Colin Watson +wordfnmatch.* author - Colin Watson +xregcomp.* author - Colin Watson diff --git a/lib/appendstr.c b/lib/appendstr.c new file mode 100644 index 0000000..3be8bff --- /dev/null +++ b/lib/appendstr.c @@ -0,0 +1,59 @@ +/* appendstr.c -- append to a dynamically allocated string + Copyright (C) 1994 Markus Armbruster + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Library Public License + as published by the Free Software Foundation; either version 2, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; see the file docs/COPYING.LIB. If not, write + to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA + 02139, USA. */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif /* HAVE_CONFIG_H */ + +#include <string.h> +#include <stdarg.h> + +#include "xalloc.h" + +#include "manconfig.h" + +#include "appendstr.h" + +/* append strings to first argument, which is realloced to the correct size + first arg may be NULL */ +char *appendstr (char *str, ...) +{ + va_list ap; + size_t len, newlen; + char *next, *end; + + len = str ? strlen (str) : 0; + + va_start (ap, str); + newlen = len + 1; + while ((next = va_arg (ap, char *))) + newlen += strlen (next); + va_end (ap); + + str = xrealloc (str, newlen); + end = str + len; + + va_start (ap, str); + while ((next = va_arg (ap, char *))) { + strcpy (end, next); + end += strlen (next); + } + va_end (ap); + + return str; +} diff --git a/lib/appendstr.h b/lib/appendstr.h new file mode 100644 index 0000000..9875faa --- /dev/null +++ b/lib/appendstr.h @@ -0,0 +1,24 @@ +/* appendstr.h -- interface to appending to a dynamically allocated string + * + * Copyright (C) 1994 Markus Armbruster + * Copyright (C) 2022 Colin Watson + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Library Public License + * as published by the Free Software Foundation; either version 2, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file docs/COPYING.LIB. If not, write + * to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA + * 02139, USA. + */ + +#include "attribute.h" + +NODISCARD extern char *appendstr (char *, ...) ATTRIBUTE_SENTINEL (); diff --git a/lib/cleanup.c b/lib/cleanup.c new file mode 100644 index 0000000..02bef2a --- /dev/null +++ b/lib/cleanup.c @@ -0,0 +1,279 @@ +/* + * cleanup.c -- simple dynamic cleanup function management + * Copyright (C) 1995 Markus Armbruster. + * Copyright (C) 2007 Colin Watson. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; see the file docs/COPYING.LIB. If not, + * write to the Free Software Foundation, Inc., 51 Franklin St, Fifth + * Floor, Boston, MA 02110-1301 USA. +*/ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif /* HAVE_CONFIG_H */ + +#include <stdbool.h> +#include <stdlib.h> +#include <stdio.h> /* SunOS's losing assert.h needs it */ +#include <assert.h> +#include <signal.h> +#include <unistd.h> +#include <string.h> + +#include "xalloc.h" + +#include "manconfig.h" /* for FATAL */ +#include "cleanup.h" + + + +/* Dealing with signals */ + + +/* saved signal actions */ +#ifdef SIGHUP +static struct sigaction saved_hup_action; +#endif /* SIGHUP */ +static struct sigaction saved_int_action; +static struct sigaction saved_term_action; + + +/* Run cleanups, then reraise signal with default handler. */ +static _Noreturn void +sighandler (int signo) +{ + struct sigaction act; + sigset_t set; + + do_cleanups_sigsafe (true); + + /* set default signal action */ + memset (&act, 0, sizeof act); + act.sa_handler = SIG_DFL; + sigemptyset (&act.sa_mask); + act.sa_flags = 0; + if (sigaction (signo, &act, NULL)) { + /* should not happen */ + _exit (FATAL); /* exit() is taboo from signal handlers! */ + } + + /* unmask signo */ + if ( sigemptyset (&set) + || sigaddset (&set, signo) + || sigprocmask (SIG_UNBLOCK, &set, NULL)) { + /* shouldn't happen */ + _exit (FATAL); /* exit() is taboo from signal handlers! */ + } + + /* signal has now default action and is unmasked, + reraise it to terminate program abnormally */ + raise (signo); + abort(); +} + + +/* Save signo's current action to oldact, if its handler is SIG_DFL + install sighandler, return 0 on success, -1 on failure. */ +static int +trap_signal (int signo, struct sigaction *oldact) +{ + if (sigaction (signo, NULL, oldact)) { + return -1; + } + + if (oldact->sa_handler == SIG_DFL) { + struct sigaction act; + + memset (&act, 0, sizeof act); + act.sa_handler = sighandler; + sigemptyset (&act.sa_mask); + act.sa_flags = 0; + return sigaction (signo, &act, oldact); + } + + return 0; +} + + +/* Trap some abnormal exits to call do_cleanups(). */ +static int +trap_abnormal_exits (void) +{ +#ifdef SIGHUP + if (trap_signal (SIGHUP, &saved_hup_action)) + return -1; +#endif /* SIGHUP */ + if (trap_signal (SIGINT, &saved_int_action)) + return -1; + if (trap_signal (SIGTERM, &saved_term_action)) + return -1; + return 0; +} + + +/* Restore signo's action from oldact if its current handler is + sighandler, return 0 on success, -1 on failure. */ +static int +untrap_signal (int signo, struct sigaction *oldact) +{ + struct sigaction act; + if (sigaction (signo, NULL, &act)) { + return -1; + } + + if (act.sa_handler == sighandler) { + return sigaction (signo, oldact, NULL); + } + + return 0; +} + + +/* Undo a previous trap_abnormal_exits(). */ +static int +untrap_abnormal_exits (void) +{ +#ifdef SIGHUP + if (untrap_signal (SIGHUP, &saved_hup_action)) + return -1; +#endif /* SIGHUP */ + if (untrap_signal (SIGINT, &saved_int_action)) + return -1; + if (untrap_signal (SIGTERM, &saved_term_action)) + return -1; + return 0; +} + + + +typedef struct { + cleanup_fun fun; + void *arg; + int sigsafe; +} slot; + +static slot *stack = NULL; /* stack of cleanup functions */ +static unsigned nslots = 0; /* #slots in stack */ +static unsigned tos = 0; /* top of stack, 0 <= tos <= nslots */ + +/* Call cleanup functions in stack from from top to bottom, + * Automatically called on program termination via exit(3) or default + * action for SIGHUP, SIGINT or SIGTERM. + * Since this may be called from a signal handler, do not use free(). + * If in_sighandler is true, cleanup functions with sigsafe=0 will not be + * called. + */ +void +do_cleanups_sigsafe (bool in_sighandler) +{ + unsigned i; + + assert (tos <= nslots); + for (i = tos; i > 0; --i) + if (!in_sighandler || stack[i-1].sigsafe) + stack[i-1].fun (stack[i-1].arg); +} + +/* Call cleanup functions in stack from from top to bottom, + * Automatically called on program termination via exit(3). + */ +void +do_cleanups (void) +{ + do_cleanups_sigsafe (false); + tos = 0; + nslots = 0; + free (stack); + stack = NULL; +} + + +/* Push a cleanup function on the cleanup stack, + * return 0 on success, -1 on failure. + * Caution: the cleanup function may be called from signal handlers if + * sigsafe=1. If you just want a convenient atexit() wrapper, pass + * sigsafe=0. + */ +int +push_cleanup (cleanup_fun fun, void *arg, int sigsafe) +{ + static bool handler_installed = false; + + assert (tos <= nslots); + + if (!handler_installed) { + if (atexit (do_cleanups)) + return -1; + handler_installed = true; + } + + if (tos == nslots) { + /* stack is full, allocate another slot */ + /* stack is not expected to grow much, otherwise we would double it */ + slot *new_stack; + + if (stack) { + new_stack = xnrealloc (stack, nslots+1, sizeof (slot)); + } else { + new_stack = xnmalloc (nslots+1, sizeof (slot)); + } + + if (!new_stack) return -1; + stack = new_stack; + ++nslots; + } + + assert (tos < nslots); + stack[tos].fun = fun; + stack[tos].arg = arg; + stack[tos].sigsafe = sigsafe; + ++tos; + + + trap_abnormal_exits(); + + return 0; +} + + +/* Remove topmost cleanup function from the cleanup stack that matches the + * given values. + */ +void +pop_cleanup (cleanup_fun fun, void *arg) +{ + unsigned i, j; + + assert (tos > 0); + + for (i = tos; i > 0; --i) { + if (stack[i-1].fun == fun && stack[i-1].arg == arg) { + for (j = i; j < tos; ++j) + stack[j-1] = stack[j]; + --tos; + break; + } + } + + if (tos == 0) untrap_abnormal_exits(); +} + + +/* Pop all cleanup functions from the cleanup stack. */ +void +pop_all_cleanups (void) +{ + tos = 0; + untrap_abnormal_exits(); +} diff --git a/lib/cleanup.h b/lib/cleanup.h new file mode 100644 index 0000000..5415b7f --- /dev/null +++ b/lib/cleanup.h @@ -0,0 +1,35 @@ +/* + * cleanup.h -- simple dynamic cleanup function management + * Copyright (C) 1995 Markus Armbruster. + * Copyright (C) 2007 Colin Watson. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; see the file docs/COPYING.LIB. If not, + * write to the Free Software Foundation, Inc., 51 Franklin St, Fifth + * Floor, Boston, MA 02110-1301 USA. + */ + +#ifndef _CLEANUP_H +#define _CLEANUP_H + +#include <stdbool.h> + +typedef void (*cleanup_fun) (void *); + +extern void do_cleanups_sigsafe (bool); +extern void do_cleanups (void); +extern int push_cleanup (cleanup_fun, void *, int); +extern void pop_cleanup (cleanup_fun, void *); +extern void pop_all_cleanups (void); + +#endif /* _CLEANUP_H */ diff --git a/lib/compression.c b/lib/compression.c new file mode 100644 index 0000000..3057236 --- /dev/null +++ b/lib/compression.c @@ -0,0 +1,195 @@ +/* + * compression.c: code to find decompressor / compression extension + * + * Copyright (C) 1994, 1995 Graeme W. Wilford. (Wilf.) + * Copyright (C) 2001-2022 Colin Watson. + * + * This file is part of man-db. + * + * man-db is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * man-db 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 man-db; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + * Sat Aug 20 15:01:02 BST 1994 Wilf. (G.Wilford@ee.surrey.ac.uk) + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif /* HAVE_CONFIG_H */ + +#include <assert.h> +#include <stdbool.h> +#include <stdio.h> +#include <errno.h> +#include <signal.h> +#include <string.h> +#include <stdlib.h> +#include <unistd.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> + +#include "error.h" +#include "xstrndup.h" +#include "xvasprintf.h" + +#include "manconfig.h" + +#include "appendstr.h" +#include "compression.h" + +/*--------------------------------------------------------------------------*/ +/* This is where we define the decompressors used to decompress any nroff */ +/* source that we find. All cat pages are compressed with either gzip (if */ +/* available) or compress. This is not the place to define _the_ cat page */ +/* decompressor - see ./manconfig.h for that. */ +/* */ +/* To add a decompressor all you need to know is its name (preferably its */ +/* location), and the unique extension that it gives to files compressed */ +/* with it. Here is an example. You have a compressor named foobar and */ +/* compressed files have an extension of .fb . It is located in /usr/bin */ +/* and requires a -d option to be used as a decompressor. Add the following */ +/* line to the structure below. */ +/* */ +/* {"/usr/bin/foobar -d", "fb", NULL}, */ +/*--------------------------------------------------------------------------*/ + +struct compression comp_list[] = { + +/* If we have gzip, incorporate the following */ +#ifdef HAVE_GZIP + {PROG_GUNZIP, "gz", NULL}, + {PROG_GUNZIP, "z", NULL}, +#endif /* HAVE_GZIP */ + +/* If we have compress, incorporate the following */ +#ifdef HAVE_COMPRESS + {PROG_UNCOMPRESS, "Z", NULL}, +/* Else if we have gzip, incorporate the following */ +#elif defined (HAVE_GZIP) + {PROG_GUNZIP, "Z", NULL}, +#endif /* HAVE_COMPRESS || HAVE_GZIP */ + +/* If we have bzip2, incorporate the following */ +#ifdef HAVE_BZIP2 + {PROG_BUNZIP2, "bz2", NULL}, +#endif /* HAVE_BZIP2 */ + +/* If we have xz, incorporate the following */ +#ifdef HAVE_XZ + {PROG_UNXZ, "xz", NULL}, + {PROG_UNXZ, "lzma", NULL}, +/* Else if we have lzma, incorporate the following */ +#elif defined (HAVE_LZMA) + {PROG_UNLZMA, "lzma", NULL}, +#endif /* HAVE_XZ || HAVE_LZMA */ + +/* If we have lzip, incorporate the following */ +#ifdef HAVE_LZIP + {PROG_UNLZIP, "lz", NULL}, +#endif /* HAVE_LZIP */ + +/* If we have zstd, incorporate the following */ +#ifdef HAVE_ZSTD + {PROG_UNZSTD, "zst", NULL}, + {PROG_UNZSTD, "zstd", NULL}, +#endif /* HAVE_ZSTD */ + +/*------------------------------------------------------*/ +/* Add your decompressor(s) and extension(s) below here */ +/*------------------------------------------------------*/ + +/*----------------*/ +/* and above here */ +/*----------------*/ + +/* ... and the last structure is */ + {NULL, NULL, NULL} +}; + +/* Take filename as arg, return structure containing decompressor + and extension, or NULL if no comp extension found. + If want_stem, set comp->stem to the filename without extension, which + the caller should free. + + eg. + filename = /usr/man/man1/foo.1.gz + + comp->prog = "/usr/bin/gzip -dc"; + comp->ext = "gz"; + comp->stem = "/usr/man/man1/foo.1"; + */ +struct compression *comp_info (const char *filename, bool want_stem) +{ + const char *ext; + static struct compression hpux_comp = + {PROG_GUNZIP " -S \"\"", "", NULL}; + + ext = strrchr (filename, '.'); + + if (ext) { + struct compression *comp; + for (comp = comp_list; comp->ext; comp++) { + if (strcmp (comp->ext, ext + 1) == 0) { + if (want_stem) + comp->stem = xstrndup (filename, + ext - filename); + else + comp->stem = NULL; + return comp; + } + } + } + + if (*PROG_GUNZIP) { + ext = strstr (filename, ".Z/"); + if (ext) { + if (want_stem) + hpux_comp.stem = xstrndup (filename, + ext - filename); + else + hpux_comp.stem = NULL; + return &hpux_comp; + } + } + + return NULL; +} + +/* take filename w/o comp ext. as arg, return comp->stem as a relative + compressed file or NULL if none found */ +struct compression *comp_file (const char *filename) +{ + size_t len; + char *compfile; + struct compression *comp; + + compfile = xasprintf ("%s.", filename); + assert (compfile); + len = strlen (compfile); + + for (comp = comp_list; comp->ext; comp++) { + struct stat buf; + + compfile = appendstr (compfile, comp->ext, (void *) 0); + + if (stat (compfile, &buf) == 0) { + comp->stem = compfile; + return comp; + } + + *(compfile + len) = '\0'; + } + free (compfile); + return NULL; +} diff --git a/lib/compression.h b/lib/compression.h new file mode 100644 index 0000000..52ede35 --- /dev/null +++ b/lib/compression.h @@ -0,0 +1,42 @@ +/* + * compression.h: interface to finding decompressor / compression extension + * + * Copyright (C) 1994, 1995 Graeme W. Wilford. (Wilf.) + * Copyright (C) 2001-2022 Colin Watson. + * + * This file is part of man-db. + * + * man-db is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * man-db 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 man-db; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include <stdbool.h> + +struct compression { + /* The following are const because they should be pointers to parts + * of strings allocated elsewhere and should not be written through + * or freed themselves. + */ + const char *prog; + const char *ext; + /* The following should be freed when discarding an instance of this + * structure. + */ + char *stem; +}; + +extern struct compression comp_list[]; + +extern struct compression *comp_info (const char *filename, bool want_stem); +extern struct compression *comp_file (const char *filename); diff --git a/lib/debug.c b/lib/debug.c new file mode 100644 index 0000000..d55d810 --- /dev/null +++ b/lib/debug.c @@ -0,0 +1,78 @@ +/* + * debug.c: debugging messages + * + * Copyright (C) 2007 Colin Watson. + * + * This file is part of man-db. + * + * man-db is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * man-db 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 man-db; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include <stdbool.h> +#include <stdlib.h> +#include <stdio.h> +#include <stdarg.h> +#include <string.h> +#include <errno.h> + +#include "attribute.h" + +#include "manconfig.h" + +#include "debug.h" + +bool debug_level = false; + +void init_debug (void) +{ + const char *man_debug = getenv ("MAN_DEBUG"); + if (man_debug && STREQ (man_debug, "1")) + debug_level = true; +} + +static void ATTRIBUTE_FORMAT ((__printf__, 1, 0)) vdebug (const char *message, + va_list args) +{ + if (debug_level) + vfprintf (stderr, message, args); +} + +void debug (const char *message, ...) +{ + if (debug_level) { + va_list args; + + va_start (args, message); + vdebug (message, args); + va_end (args); + } +} + +void debug_error (const char *message, ...) +{ + if (debug_level) { + va_list args; + + va_start (args, message); + vdebug (message, args); + va_end (args); + + debug (": %s\n", strerror (errno)); + } +} diff --git a/lib/debug.h b/lib/debug.h new file mode 100644 index 0000000..1421eea --- /dev/null +++ b/lib/debug.h @@ -0,0 +1,32 @@ +/* + * debug.h: interface to debugging messages + * + * Copyright (C) 2007-2022 Colin Watson. + * + * This file is part of man-db. + * + * man-db is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * man-db 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 man-db; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include <stdbool.h> + +#include "attribute.h" + +extern bool debug_level; /* shows whether -d issued */ +extern void init_debug (void); +extern void debug (const char *message, ...) + ATTRIBUTE_FORMAT ((__printf__, 1, 2)); +extern void debug_error (const char *message, ...) + ATTRIBUTE_FORMAT ((__printf__, 1, 2)); diff --git a/lib/encodings.c b/lib/encodings.c new file mode 100644 index 0000000..68c06c6 --- /dev/null +++ b/lib/encodings.c @@ -0,0 +1,780 @@ +/* + * encodings.c: locale and encoding handling for man + * + * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 + * Colin Watson. + * + * This file is part of man-db. + * + * man-db is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * man-db 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 man-db; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif /* HAVE_CONFIG_H */ + +#include <stdbool.h> +#include <stdio.h> +#include <string.h> +#include <stdlib.h> +#include <unistd.h> +#include <locale.h> +#include <ctype.h> + +#include "attribute.h" +#include "gettext.h" +#include "localcharset.h" +#include "xalloc.h" +#include "xstrndup.h" + +#include "manconfig.h" + +#include "debug.h" +#include "encodings.h" +#include "pathsearch.h" + + +/* Due to historical limitations in groff (which may be removed in the + * future), there is no mechanism for a man page to specify its own + * encoding. This means that each national language directory needs to carry + * with it information about its encoding, and each groff device needs to + * have a default encoding associated with it. Out of the box, groff + * formally allows only ISO-8859-1 on input; however, patches originating + * with Debian and imported by many other GNU/Linux distributions change + * this somewhat. + * + * Eventually, groff will support proper Unicode input, and much of this + * horror can go away. + * + * Do *not* confuse source encoding with groff encoding. The encoding + * specified in this table is the encoding in which the source man pages in + * each language directory are expected to be written. The groff encoding is + * determined by the selected groff device and sometimes also by the user's + * locale. + * + * The standard output encoding is the encoding assumed for cat pages for + * each language directory. It must *not* be used to discover the actual + * output encoding displayed to the user; that is determined by the locale. + * TODO: it would be useful to be able to change the standard output + * encoding in the configuration file. + * + * This table is expected to change over time, particularly as man pages + * begin to move towards UTF-8. Feel free to patch this for your + * distribution; send me updates for languages I've missed. + * + * Explicit encodings in the directory name (e.g. de_DE.UTF-8) override this + * table. + */ +struct directory_entry { + const char *lang_dir; + const char *source_encoding; +}; + +static struct directory_entry directory_table[] = { + { "C", "ISO-8859-1" }, /* English */ + { "POSIX", "ISO-8859-1" }, /* English */ + { "da", "ISO-8859-1" }, /* Danish */ + { "de", "ISO-8859-1" }, /* German */ + { "en", "ISO-8859-1" }, /* English */ + { "es", "ISO-8859-1" }, /* Spanish */ + { "et", "ISO-8859-1" }, /* Estonian */ + { "fi", "ISO-8859-1" }, /* Finnish */ + { "fr", "ISO-8859-1" }, /* French */ + { "ga", "ISO-8859-1" }, /* Irish */ + { "gl", "ISO-8859-1" }, /* Galician */ + { "id", "ISO-8859-1" }, /* Indonesian */ + { "is", "ISO-8859-1" }, /* Icelandic */ + { "it", "ISO-8859-1" }, /* Italian */ + { "nb", "ISO-8859-1" }, /* Norwegian Bokmål */ + { "nl", "ISO-8859-1" }, /* Dutch */ + { "nn", "ISO-8859-1" }, /* Norwegian Nynorsk */ + { "no", "ISO-8859-1" }, /* Norwegian */ + { "pt", "ISO-8859-1" }, /* Portuguese */ + { "sv", "ISO-8859-1" }, /* Swedish */ + +#ifdef MULTIBYTE_GROFF + /* These languages require a patched version of groff with the + * ascii8 and nippon devices. + */ + { "be", "CP1251" }, /* Belarusian */ + { "bg", "CP1251" }, /* Bulgarian */ + { "cs", "ISO-8859-2" }, /* Czech */ + { "el", "ISO-8859-7" }, /* Greek */ + { "hr", "ISO-8859-2" }, /* Croatian */ + { "hu", "ISO-8859-2" }, /* Hungarian */ + { "ja", "EUC-JP" }, /* Japanese */ + { "ko", "EUC-KR" }, /* Korean */ + { "lt", "ISO-8859-13" }, /* Lithuanian */ + { "lv", "ISO-8859-13" }, /* Latvian */ + { "mk", "ISO-8859-5" }, /* Macedonian */ + { "pl", "ISO-8859-2" }, /* Polish */ + { "ro", "ISO-8859-2" }, /* Romanian */ + { "ru", "KOI8-R" }, /* Russian */ + { "sk", "ISO-8859-2" }, /* Slovak */ + { "sl", "ISO-8859-2" }, /* Slovenian */ + /* sr@latin must precede sr, due to top-down left-substring matching later */ + { "sr@latin", "ISO-8859-2" }, /* Serbian Latin */ + { "sr", "ISO-8859-5" }, /* Serbian */ + { "tr", "ISO-8859-9" }, /* Turkish */ + { "uk", "KOI8-U" }, /* Ukrainian */ + { "vi", "TCVN5712-1" }, /* Vietnamese */ + { "zh_CN", "GBK" }, /* Simplified Chinese */ + { "zh_SG", "GBK" }, /* Simplified Chinese, Singapore */ + { "zh_HK", "BIG5HKSCS" }, /* Traditional Chinese, Hong Kong */ + { "zh_TW", "BIG5" }, /* Traditional Chinese */ +#endif /* MULTIBYTE_GROFF */ + + { NULL, NULL } +}; + +static const char fallback_source_encoding[] = "ISO-8859-1"; + +/* Unfortunately, there is no portable way to inspect iconv's internal table + * of character set aliases. We copy the most interesting ones here so that + * we can deal with them if they appear in directory names. Note that all + * names will be converted to upper case before looking them up in this + * table. + */ +struct charset_alias_entry { + const char *alias; + const char *canonical_name; +}; + +static struct charset_alias_entry charset_alias_table[] = { + /* The FHS is silly and requires numeric-only aliases that iconv + * does not support. + */ + { "88591", "ISO-8859-1" }, + { "88592", "ISO-8859-2" }, + { "88593", "ISO-8859-3" }, + { "88594", "ISO-8859-4" }, + { "88595", "ISO-8859-5" }, + { "88596", "ISO-8859-6" }, + { "88597", "ISO-8859-7" }, + { "88598", "ISO-8859-8" }, + { "88599", "ISO-8859-9" }, + { "885910", "ISO-8859-10" }, + { "885911", "ISO-8859-11" }, + { "885913", "ISO-8859-13" }, + { "885914", "ISO-8859-14" }, + { "885915", "ISO-8859-15" }, + { "885916", "ISO-8859-16" }, + + { "ASCII", "ANSI_X3.4-1968" }, + { "BIG-5", "BIG5" }, + { "BIG5-HKSCS", "BIG5HKSCS" }, + { "EUCCN", "EUC-CN" }, + { "EUCJP", "EUC-JP" }, + { "EUCKR", "EUC-KR" }, + { "EUCTW", "EUC-TW" }, + { "GB2312", "EUC-CN" }, + { "ISO8859-1", "ISO-8859-1" }, + { "ISO8859-2", "ISO-8859-2" }, + { "ISO8859-3", "ISO-8859-3" }, + { "ISO8859-4", "ISO-8859-4" }, + { "ISO8859-5", "ISO-8859-5" }, + { "ISO8859-6", "ISO-8859-6" }, + { "ISO8859-7", "ISO-8859-7" }, + { "ISO8859-8", "ISO-8859-8" }, + { "ISO8859-9", "ISO-8859-9" }, + { "ISO8859-10", "ISO-8859-10" }, + { "ISO8859-11", "ISO-8859-11" }, + { "ISO8859-13", "ISO-8859-13" }, + { "ISO8859-14", "ISO-8859-14" }, + { "ISO8859-15", "ISO-8859-15" }, + { "ISO8859-16", "ISO-8859-16" }, + { "KOI8R", "KOI8-R" }, + { "KOI8U", "KOI8-U" }, + { "UJIS", "EUC-JP" }, + { "US-ASCII", "ANSI_X3.4-1968" }, + { "UTF8", "UTF-8" }, + + { NULL, NULL } +}; + +/* The default groff terminal output device to be used is determined based + * on locale_charset (), which returns the character set used by the current + * locale. + */ +struct charset_entry { + const char *charset_from_locale; + const char *default_device; +}; + +static struct charset_entry charset_table[] = { + { "ANSI_X3.4-1968", "ascii" }, +#ifndef HEIRLOOM_NROFF + { "ISO-8859-1", "latin1" }, +#endif /* HEIRLOOM_NROFF */ + { "UTF-8", "utf8" }, + +#ifndef HEIRLOOM_NROFF +# ifdef MULTIBYTE_GROFF + { "BIG5", "nippon" }, + { "BIG5HKSCS", "nippon" }, + { "EUC-CN", "nippon" }, + { "EUC-JP", "nippon" }, + { "EUC-TW", "nippon" }, + { "GBK", "nippon" }, +# else /* !MULTIBYTE_GROFF */ + /* If we have a smarter version of groff, this is better dealt with + * using either ascii8 (Debian multibyte patch) or preconv (as of + * groff 1.20). This is a not-quite-right stopgap in case we have + * neither. + */ + { "ISO-8859-15", "latin1" }, +# endif /* MULTIBYTE_GROFF */ +#endif /* HEIRLOOM_NROFF */ + + { NULL, NULL } +}; + +static const char *fallback_default_device = +#ifdef MULTIBYTE_GROFF + "ascii8" +#else /* !MULTIBYTE_GROFF */ + "ascii" +#endif /* MULTIBYTE_GROFF */ + ; + +/* The encoding used for the text passed to groff is a function of the + * selected groff device. Traditional devices expect ISO-8859-1 on input + * (yes, even the utf8 device); devices added in the Debian multibyte patch + * expect other encodings. The ascii8 device passes top-bit-set characters + * straight through so is (probably ...) encoding-agnostic. If this encoding + * does not match the source encoding, an iconv pipe is used (if available) + * to perform recoding. + */ +struct device_entry { + const char *roff_device; + const char *roff_encoding; + const char *output_encoding; +}; + +static struct device_entry device_table[] = { + /* nroff devices */ + { "ascii", "ANSI_X3.4-1968", "ANSI_X3.4-1968" }, + { "latin1", "ISO-8859-1", "ISO-8859-1" }, + { "utf8", "ISO-8859-1", "UTF-8" }, + +#ifdef MULTIBYTE_GROFF + { "ascii8", NULL, NULL }, + { "nippon", NULL, NULL }, +#endif /* MULTIBYTE_GROFF */ + +#ifdef HEIRLOOM_NROFF + /* Not strictly accurate, but we only use this in UTF-8 locales. */ + { "locale", "UTF-8", "UTF-8" }, +#endif /* HEIRLOOM_NROFF */ + + /* troff devices */ + { "X75", NULL, NULL }, + { "X75-12", NULL, NULL }, + { "X100", NULL, NULL }, + { "X100-12", NULL, NULL }, + { "dvi", NULL, NULL }, + { "html", NULL, NULL }, + { "lbp", NULL, NULL }, + { "lj4", NULL, NULL }, + { "ps", NULL, NULL }, + + { NULL, NULL, NULL } +}; + +static const char fallback_roff_encoding[] = "ISO-8859-1"; + +/* Setting less_charset to iso8859 tells the less pager that characters + * between 0xA0 and 0xFF are displayable, not that its input is encoded in + * ISO-8859-*. TODO: Perhaps using LESSCHARDEF would be better. + * + * Character set names compatible only with jless go in jless_charset. + */ +struct less_charset_entry { + const char *charset_from_locale; + const char *less_charset; + const char *jless_charset; +}; + +static struct less_charset_entry less_charset_table[] = { + { "ANSI_X3.4-1968", "ascii", NULL }, + { "ISO-8859-1", "iso8859", NULL }, + { "UTF-8", "utf-8", NULL }, + +#ifdef MULTIBYTE_GROFF + { "CP1251", "windows", NULL }, + { "EUC-JP", "iso8859", "japanese-ujis" }, + { "KOI8-R", "koi8-r", NULL }, + /* close enough? */ + { "KOI8-U", "koi8-r", NULL }, +#endif /* MULTIBYTE_GROFF */ + + { NULL, NULL, NULL } +}; + +static const char fallback_less_charset[] = "iso8859"; + +const char *groff_preconv = NULL; + +/* Is the groff "preconv" helper available? If so, return its name. + * Otherwise, return NULL. + */ +const char *get_groff_preconv (void) +{ + if (groff_preconv) { + if (*groff_preconv) + return groff_preconv; + else + return NULL; + } + + if (pathsearch_executable ("gpreconv")) + groff_preconv = "gpreconv"; + else if (pathsearch_executable ("preconv")) + groff_preconv = "preconv"; + else + groff_preconv = ""; + + if (*groff_preconv) + return groff_preconv; + else + return NULL; +} + +/* Return the assumed encoding of the source man page, based on the + * directory in which it was found. The caller should attempt to recode from + * this to whatever encoding is expected by groff. + * + * The caller should free the returned string when it is finished with it. + */ +char * ATTRIBUTE_MALLOC get_page_encoding (const char *lang) +{ + const struct directory_entry *entry; + const char *dot; + + if (!lang || !*lang) { + /* Guess based on the locale. */ + lang = setlocale (LC_MESSAGES, NULL); + if (!lang) + return xstrdup (fallback_source_encoding); + } + + dot = strchr (lang, '.'); + if (dot) { + /* The FHS has the worst specification of what's supposed to + * go after the dot here that I've ever seen. To quote from + * version 2.1: + * + * "It is recommended that this be a numeric representation + * if possible (ISO standards, especially), not include + * additional punctuation symbols, and that any letters be + * in lowercase." + * + * Any sane standard would use directory names like + * de_DE.ISO-8859-1; the examples in the FHS recommend + * de_DE.88591 instead. Considering that there is no other + * conceivable use for encodings in directory names other + * than to pass them to iconv or similar, this is quite + * startlingly useless. + * + * While we now support this thanks to + * get_canonical_charset_name, the FHS specification is + * obviously wrong and I plan to petition to have it + * changed. I recommend ignoring this part of the FHS. + */ + char *dir_encoding = + xstrndup (dot + 1, strcspn (dot + 1, ",@")); + char *canonical_dir_encoding = + xstrdup (get_canonical_charset_name (dir_encoding)); + free (dir_encoding); + return canonical_dir_encoding; + } + + for (entry = directory_table; entry->lang_dir; ++entry) + if (STRNEQ (entry->lang_dir, lang, strlen (entry->lang_dir))) + return xstrdup (entry->source_encoding); + + return xstrdup (fallback_source_encoding); +} + +/* Return the canonical encoding for source man pages in the specified + * language. This ignores any encoding specification in the language + * directory name. The source encoding should be used as a basis for + * determining the correct roff device to use: that is, the caller should + * behave as if it is recoding from the page encoding to the source encoding + * first, although in practice it should recode directly from the page + * encoding to the roff encoding. + * + * You should normally only call this function if the page encoding is + * UTF-8, in which case older versions of groff that lack preconv need to + * have the page recoded to some legacy encoding). If the page is in a + * legacy encoding, then attempting to recode from that to some other legacy + * encoding will probably do more harm than good. + * + * Here are a few concrete examples of why these distinctions are important: + * + * /usr/share/man/en_GB.UTF-8, locale C + * page encoding = UTF-8 + * source encoding = ISO-8859-1 + * roff encoding = ISO-8859-1 + * output encoding = UTF-8 + * UTF-8 -> iconv -> ISO-8859-1 -> groff -Tascii -> ANSI_X3.4-1968 + * + * /usr/share/man/pl_PL.UTF-8, locale pl_PL.UTF-8 + * page encoding = UTF-8 + * source encoding = ISO-8859-2 + * roff encoding = ISO-8859-2 + * output encoding = ISO-8859-2 + * UTF-8 -> iconv -> ISO-8859-2 -> groff -Tascii8 + * -> ISO-8859-2 -> iconv -> UTF-8 + * + * /usr/share/man/ja_JP.EUC-JP, locale ja_JP.UTF-8 + * page encoding = EUC-JP + * source encoding = EUC-JP + * roff encoding = UTF-8 + * output encoding = UTF-8 + * EUC-JP -> iconv -> UTF-8 -> groff -Tutf8 -> UTF-8 + * + * /usr/share/man/en_GB.ISO-8859-15, locale en_GB.UTF-8 + * page encoding = ISO-8859-15 + * source encoding = ISO-8859-15 + * roff encoding = ISO-8859-15 + * output encoding = ISO-8859-15 + * ISO-8859-15 -> groff -Tascii8 -> ISO-8859-15 -> iconv -> UTF-8 + */ +const char *get_source_encoding (const char *lang) +{ + const struct directory_entry *entry; + + if (!lang || !*lang) { + /* Guess based on the locale. */ + lang = setlocale (LC_MESSAGES, NULL); + if (!lang) + return fallback_source_encoding; + } + + for (entry = directory_table; entry->lang_dir; ++entry) + if (STRNEQ (entry->lang_dir, lang, strlen (entry->lang_dir))) + return entry->source_encoding; + + return fallback_source_encoding; +} + +const char * ATTRIBUTE_NONNULL ((1)) ATTRIBUTE_RETURNS_NONNULL + get_canonical_charset_name (const char *charset) +{ + const struct charset_alias_entry *entry; + char *charset_upper = xstrdup (charset); + char *p; + + for (p = charset_upper; *p; ++p) + *p = CTYPE (toupper, *p); + + for (entry = charset_alias_table; entry->alias; ++entry) + if (STREQ (entry->alias, charset_upper)) { + free (charset_upper); + return entry->canonical_name; + } + + free (charset_upper); + return charset; +} + +/* Return the current locale's character set. */ +const char * ATTRIBUTE_RETURNS_NONNULL get_locale_charset (void) +{ + const char *charset; + char *saved_locale; + + /* We need to modify LC_CTYPE temporarily in order to look at the + * codeset, so save it first. + */ + saved_locale = setlocale (LC_CTYPE, NULL); + if (saved_locale) + saved_locale = xstrdup (saved_locale); + + setlocale (LC_CTYPE, ""); + + charset = locale_charset (); + + /* Restore LC_CTYPE to its value on entry to this function. */ + setlocale (LC_CTYPE, saved_locale); + free (saved_locale); + + if (!charset || !*charset) + charset = "ANSI_X3.4-1968"; + return get_canonical_charset_name (charset); +} + +/* Find a locale with this character set. This is a non-portable operation, + * but required to make col(1) work correctly with -E. If no locale can be + * found, or if none needs to be set, return NULL. + * + * The caller should free the returned string when it is finished with it. + */ +char *find_charset_locale (const char *charset) +{ + const char *canonical_charset = get_canonical_charset_name (charset); + char *saved_locale; + const char supported_path[] = "/usr/share/i18n/SUPPORTED"; + FILE *supported = NULL; + char *line = NULL; + size_t n = 0; + char *locale = NULL; + + if (STREQ (charset, get_locale_charset ())) + return NULL; + + saved_locale = setlocale (LC_CTYPE, NULL); + if (saved_locale) + saved_locale = xstrdup (saved_locale); + + supported = fopen (supported_path, "r"); + while (supported && getline (&line, &n, supported) >= 0) { + const char *space = strchr (line, ' '); + if (space) { + char *encoding = xstrdup (space + 1); + char *newline = strchr (encoding, '\n'); + if (newline) + *newline = 0; + if (STREQ (canonical_charset, + get_canonical_charset_name (encoding))) { + locale = xstrndup (line, space - line); + /* Is this locale actually installed? */ + if (setlocale (LC_CTYPE, locale)) { + free (encoding); + goto out; + } else { + free (locale); + locale = NULL; + } + } + free (encoding); + } + free (line); + line = NULL; + } + + if (strlen (canonical_charset) >= 5 && + STRNEQ (canonical_charset, "UTF-8", 5)) { + locale = xstrdup ("C.UTF-8"); + if (setlocale (LC_CTYPE, locale)) + goto out; + free (locale); + locale = xstrdup ("en_US.UTF-8"); + if (setlocale (LC_CTYPE, locale)) + goto out; + free (locale); + locale = NULL; + } + +out: + free (line); + setlocale (LC_CTYPE, saved_locale); + free (saved_locale); + if (supported) + fclose (supported); + return locale; +} + +/* Can we take this input encoding and produce this output encoding, perhaps + * with the help of some iconv pipes? */ +static bool ATTRIBUTE_PURE compatible_encodings (const char *input, + const char *output) +{ + if (STREQ (input, output)) + return true; + + /* If the input is ASCII, recoding should be easy. Try it. */ + if (STREQ (input, "ANSI_X3.4-1968")) + return true; + + /* If the input is UTF-8, it's either a simple recoding of whatever + * we want or else it probably won't work at all no matter what we + * do. We might as well try it for now. + */ + if (STREQ (input, "UTF-8")) + return true; + + /* If the output is ASCII, this is probably because the caller + * explicitly asked for it, so we have little choice but to try. + */ + if (STREQ (output, "ANSI_X3.4-1968")) + return true; + +#ifdef MULTIBYTE_GROFF + /* Special case for some CJK UTF-8 locales, which take UTF-8 input + * recoded from EUC-JP (etc.) and produce UTF-8 output. This is + * rather filthy. + */ + if ((STREQ (input, "BIG5") || STREQ (input, "BIG5HKSCS") || + STREQ (input, "EUC-JP") || + STREQ (input, "EUC-CN") || STREQ (input, "GBK") || + STREQ (input, "EUC-KR") || + STREQ (input, "EUC-TW")) && + STREQ (output, "UTF-8")) + return true; +#endif /* MULTIBYTE_GROFF */ + + return false; +} + +/* Return the default groff device for the given character set. This may be + * overridden by the user. The page's source encoding is needed to ensure + * that the device is compatible: consider ru_RU.UTF-8, which needs ascii8 + * and a trailing iconv pipe to recode to UTF-8. + * + * All this encoding compatibility stuff feels like a slightly nasty hack, + * but I haven't yet come up with a cleaner way to do it. + */ +const char *get_default_device (const char *charset_from_locale, + const char *source_encoding) +{ + const struct charset_entry *entry; + + if (get_groff_preconv ()) { + /* ASCII is a special case, and the only way we can get + * things like bullet marks to come out right is by using + * the ascii device. People using such a basic locale + * probably don't want anything fancy anyway. + */ + if (charset_from_locale && + STREQ (charset_from_locale, "ANSI_X3.4-1968")) + return "ascii"; + else + return "utf8"; + } + + if (!charset_from_locale) + return fallback_default_device; + + for (entry = charset_table; entry->charset_from_locale; ++entry) { + if (STREQ (entry->charset_from_locale, charset_from_locale)) { + const char *roff_encoding = + get_roff_encoding (entry->default_device, + source_encoding); + if (compatible_encodings (source_encoding, + roff_encoding)) + return entry->default_device; + } + } + + return fallback_default_device; +} + +/* Is this a known *roff device name? */ +bool ATTRIBUTE_PURE is_roff_device (const char *device) +{ + const struct device_entry *entry; + + for (entry = device_table; entry->roff_device; ++entry) { + if (STREQ (entry->roff_device, device)) + return true; + } + + return false; +} + +/* Find the input encoding expected by groff, and set the LESSCHARSET + * environment variable appropriately. + */ +const char *get_roff_encoding (const char *device, const char *source_encoding) +{ + const struct device_entry *entry; + bool found = false; + const char *roff_encoding = NULL; + + if (device) { + for (entry = device_table; entry->roff_device; ++entry) { + if (STREQ (entry->roff_device, device)) { + found = true; + roff_encoding = entry->roff_encoding; + break; + } + } + } + + if (!found) + roff_encoding = fallback_roff_encoding; + +#ifdef MULTIBYTE_GROFF + /* An ugly special case is needed here. The utf8 device normally + * takes ISO-8859-1 input. However, with the multibyte patch, when + * recoding from CJK character sets it takes UTF-8 input instead. + * This is evil, but there's not much that can be done about it + * apart from waiting for groff 2.0. + */ + if (device && STREQ (device, "utf8") && !get_groff_preconv () && + STREQ (get_locale_charset (), "UTF-8")) { + const char *ctype = setlocale (LC_CTYPE, NULL); + if (STRNEQ (ctype, "ja_JP", 5) || + STRNEQ (ctype, "ko_KR", 5) || + STRNEQ (ctype, "zh_CN", 5) || + STRNEQ (ctype, "zh_HK", 5) || + STRNEQ (ctype, "zh_SG", 5) || + STRNEQ (ctype, "zh_TW", 5)) + roff_encoding = "UTF-8"; + } +#endif /* MULTIBYTE_GROFF */ + + return roff_encoding ? roff_encoding : source_encoding; +} + +/* Find the output encoding that this device will produce, or NULL if it + * will simply pass through the input encoding. + */ +const char * ATTRIBUTE_PURE get_output_encoding (const char *device) +{ + const struct device_entry *entry; + + for (entry = device_table; entry->roff_device; ++entry) + if (STREQ (entry->roff_device, device)) + return entry->output_encoding; + + return NULL; +} + +/* Return the value of LESSCHARSET appropriate for this locale. */ +const char * ATTRIBUTE_PURE get_less_charset (const char *charset_from_locale) +{ + const struct less_charset_entry *entry; + + if (charset_from_locale) { + for (entry = less_charset_table; entry->charset_from_locale; + ++entry) + if (STREQ (entry->charset_from_locale, + charset_from_locale)) + return entry->less_charset; + } + + return fallback_less_charset; +} + +/* Return the value of JLESSCHARSET appropriate for this locale. May return + * NULL. + */ +const char * ATTRIBUTE_PURE get_jless_charset (const char *charset_from_locale) +{ + const struct less_charset_entry *entry; + + if (charset_from_locale) { + for (entry = less_charset_table; entry->charset_from_locale; + ++entry) + if (STREQ (entry->charset_from_locale, + charset_from_locale)) + return entry->jless_charset; + } + + return NULL; +} diff --git a/lib/encodings.h b/lib/encodings.h new file mode 100644 index 0000000..6de48f7 --- /dev/null +++ b/lib/encodings.h @@ -0,0 +1,38 @@ +/* + * encodings.h: Interface to locale and encoding handling for man + * + * Copyright (C) 2003, 2004, 2006, 2007, 2008 Colin Watson. + * + * This file is part of man-db. + * + * man-db is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * man-db 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 man-db; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include <stdbool.h> + +const char *get_groff_preconv (void); +char *get_page_encoding (const char *lang); +const char *get_source_encoding (const char *lang); +const char *get_canonical_charset_name (const char *charset); +const char *get_locale_charset (void); +char *find_charset_locale (const char *charset); +const char *get_default_device (const char *locale_charset, + const char *source_encoding); +bool is_roff_device (const char *device); +const char *get_roff_encoding (const char *device, + const char *source_encoding); +const char *get_output_encoding (const char *device); +const char *get_less_charset (const char *locale_charset); +const char *get_jless_charset (const char *locale_charset); diff --git a/lib/fatal.c b/lib/fatal.c new file mode 100644 index 0000000..b2b7895 --- /dev/null +++ b/lib/fatal.c @@ -0,0 +1,48 @@ +/* + * fatal.c: fatal error helper + * + * Copyright (C) 2022 Colin Watson. + * + * This file is part of man-db. + * + * man-db is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * man-db 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 man-db; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif /* HAVE_CONFIG_H */ + +#include <stdarg.h> +#include <stdlib.h> + +#include "verror.h" + +#include "manconfig.h" + +#include "fatal.h" + +void fatal (int errnum, const char *format, ...) +{ + va_list ap; + + va_start (ap, format); + verror (FATAL, errnum, format, ap); + va_end (ap); + + /* Never reached, because verror exits if given a non-zero status, + * but the compiler may not be able to prove that. + */ + abort (); +} diff --git a/lib/fatal.h b/lib/fatal.h new file mode 100644 index 0000000..7cc299e --- /dev/null +++ b/lib/fatal.h @@ -0,0 +1,26 @@ +/* + * fatal.h: interface to fatal error helper + * + * Copyright (C) 2022 Colin Watson. + * + * This file is part of man-db. + * + * man-db is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * man-db 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 man-db; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "attribute.h" + +_Noreturn void fatal (int errnum, const char *format, ...) + ATTRIBUTE_FORMAT ((__printf__, 2, 3)); diff --git a/lib/filenames.c b/lib/filenames.c new file mode 100644 index 0000000..fb5f6b7 --- /dev/null +++ b/lib/filenames.c @@ -0,0 +1,165 @@ +/* + * filenames.c: compose and dissect man page file names + * + * Copyright (C) 1994, 1995 Graeme W. Wilford. (Wilf.) + * Copyright (C) 2001, 2002 Colin Watson. + * + * This file is part of man-db. + * + * man-db is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * man-db 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 man-db; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif /* HAVE_CONFIG_H */ + +#include <stdbool.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +#include "dirname.h" +#include "error.h" +#include "xalloc.h" +#include "xvasprintf.h" + +#include "gettext.h" +#define _(String) gettext (String) + +#include "manconfig.h" + +#include "appendstr.h" +#include "compression.h" +#include "debug.h" +#include "filenames.h" + +static void gripe_bogus_manpage (const char *manpage) +{ + error (0, 0, _("warning: %s: ignoring bogus filename"), manpage); +} + +char *make_filename (const char *path, const char *name, + struct mandata *in, const char *type) +{ + static char *file; + + if (!name) + name = in->name; /* comes from dblookup(), so non-NULL */ + + file = xasprintf ("%s/%s%s/%s.%s", path, type, in->sec, name, in->ext); + + if (in->comp && *in->comp != '-') /* Is there an extension? */ + file = appendstr (file, ".", in->comp, (void *) 0); + + debug ("Checking physical location: %s\n", file); + if (!CAN_ACCESS (file, R_OK)) { + free (file); + return NULL; + } + + return file; +} + +/* Fill in a mandata structure with information about a file name. + * file is the name to examine. info points to the structure to be filled + * in. + * + * Returns either a pointer to the buffer which the fields in info point + * into, to be freed by the caller, or NULL on error. The buffer will + * contain either three or four null-terminated strings: the directory name, + * the base of the file name in that directory, the section extension, and + * optionally the compression extension. + * + * Only the fields name, ext, sec, and comp are filled in by this function. + */ +struct mandata *filename_info (const char *file, bool warn_if_bogus) +{ + struct mandata *info; + char *basename, *dirname; + struct compression *comp; + + info = XZALLOC (struct mandata); + + basename = base_name (file); + + /* Bogus files either have (i) no period, ie no extension, (ii) + a compression extension, but no sectional extension, (iii) + a mismatch between the section they are under and the + sectional part of their extension. */ + + comp = comp_info (basename, true); + if (comp) { + info->comp = xstrdup (comp->ext); + *(basename + strlen (comp->stem)) = '\0'; + free (comp->stem); + } else + info->comp = NULL; + + { + char *ext = strrchr (basename, '.'); + if (!ext) { + /* no section extension */ + if (warn_if_bogus) + gripe_bogus_manpage (file); + free (basename); + free_mandata_struct (info); + return NULL; + } + *ext++ = '\0'; /* set section ext */ + info->ext = xstrdup (ext); + if (!*info->ext) { + /* zero-length section extension */ + if (warn_if_bogus) + gripe_bogus_manpage (file); + free (basename); + free_mandata_struct (info); + return NULL; + } + } + + /* Set section name. */ + dirname = dir_name (file); + info->sec = xstrdup (strrchr (dirname, '/') + 4); + free (dirname); + + if (strlen (info->sec) >= 1 && strlen (info->ext) >= 1 && + info->sec[0] != info->ext[0]) { + /* mismatch in section */ + if (warn_if_bogus) + gripe_bogus_manpage (file); + free (basename); + free_mandata_struct (info); + return NULL; + } + + info->name = xstrdup (basename); + + return info; +} + +/* Free a mandata structure and its elements. */ +void free_mandata_struct (struct mandata *pinfo) +{ + if (pinfo) { + free (pinfo->name); + free (pinfo->ext); + free (pinfo->sec); + free (pinfo->pointer); + free (pinfo->comp); + free (pinfo->filter); + free (pinfo->whatis); + } + free (pinfo); +} diff --git a/lib/filenames.h b/lib/filenames.h new file mode 100644 index 0000000..66bc48a --- /dev/null +++ b/lib/filenames.h @@ -0,0 +1,56 @@ +/* + * filenames.h: Interface to composing and dissecting man page file names + * + * Copyright (C) 2001-2022 Colin Watson. + * + * This file is part of man-db. + * + * man-db is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * man-db 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 man-db; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef MAN_FILENAMES_H +#define MAN_FILENAMES_H + +#include <stdbool.h> + +#include "timespec.h" + +struct mandata { + /* Name of page, if not equal to the key. */ + char *name; + /* Filename extension without compression extension. */ + char *ext; + /* Section name/number. */ + char *sec; + /* ID (i.e. type) of this entry. */ + char id; + /* ID-related file pointer. */ + char *pointer; + /* Compression extension. */ + char *comp; + /* Filters needed for the page. */ + char *filter; + /* Whatis description for the page. */ + char *whatis; + /* Modification time for file. */ + struct timespec mtime; +}; + +extern char *make_filename (const char *path, const char *name, + struct mandata *in, const char *type); +extern struct mandata *filename_info (const char *file, bool warn_if_bogus); +extern void free_mandata_struct (struct mandata *pinfo); + +#endif /* MAN_FILENAMES_H */ diff --git a/lib/glcontainers.c b/lib/glcontainers.c new file mode 100644 index 0000000..4cbe4ba --- /dev/null +++ b/lib/glcontainers.c @@ -0,0 +1,78 @@ +/* + * glcontainers.c: common Gnulib container helpers + * + * Copyright (C) 2019 Colin Watson. + * + * This file is part of man-db. + * + * man-db is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * man-db 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 man-db; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif /* HAVE_CONFIG_H */ + +#include <stdbool.h> +#include <stdlib.h> +#include <string.h> + +#include "attribute.h" +#include "gl_xlist.h" +#include "gl_xmap.h" +#include "gl_xset.h" +#include "hash-pjw-bare.h" + +#include "manconfig.h" + +#include "glcontainers.h" + +bool ATTRIBUTE_PURE string_equals (const void *s1, const void *s2) +{ + return STREQ ((const char *) s1, (const char *) s2); +} + +size_t ATTRIBUTE_PURE string_hash (const void *s) +{ + return hash_pjw_bare (s, strlen ((const char *) s)); +} + +void plain_free (const void *s) +{ + /* gl_list declares the argument as const, but there doesn't seem to + * be a good reason for this. + */ + free ((void *) s); +} + +gl_list_t new_string_list (gl_list_implementation_t implementation, + bool allow_duplicates) +{ + return gl_list_create_empty (implementation, string_equals, + string_hash, plain_free, + allow_duplicates); +} + +gl_map_t new_string_map (gl_map_implementation_t implementation, + gl_mapvalue_dispose_fn vdispose_fn) +{ + return gl_map_create_empty (implementation, string_equals, string_hash, + plain_free, vdispose_fn); +} + +gl_set_t new_string_set (gl_set_implementation_t implementation) +{ + return gl_set_create_empty (implementation, string_equals, string_hash, + plain_free); +} diff --git a/lib/glcontainers.h b/lib/glcontainers.h new file mode 100644 index 0000000..56ae099 --- /dev/null +++ b/lib/glcontainers.h @@ -0,0 +1,68 @@ +/* + * glcontainers.h: interface to common Gnulib container helpers + * + * Copyright (C) 2019 Colin Watson. + * + * This file is part of man-db. + * + * man-db is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * man-db 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 man-db; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef MAN_GLCONTAINERS_H +#define MAN_GLCONTAINERS_H + +#include <stdbool.h> +#include <stdlib.h> + +#include "gl_list.h" +#include "gl_map.h" +#include "gl_set.h" + +#include "mp.h" + +/* These types are compatible with those required by Gnulib container + * initialisation. + */ + +bool string_equals (const void *s1, const void *s2); +size_t string_hash (const void *s); +void plain_free (const void *s); + +/* Convenience functions. */ + +gl_list_t new_string_list (gl_list_implementation_t implementation, + bool allow_duplicates); +gl_map_t new_string_map (gl_map_implementation_t implementation, + gl_mapvalue_dispose_fn vdispose_fn); +gl_set_t new_string_set (gl_set_implementation_t implementation); + +/* Iterator macros. */ + +#define GL_LIST_FOREACH(list, item) \ + MPP_DECLARE (1, gl_list_iterator_t list##_iter = gl_list_iterator (list)) \ + MPP_DECLARE (2, gl_list_node_t list##_node) \ + MPP_WHILE (3, gl_list_iterator_next (&list##_iter, \ + (const void **) &item, \ + &list##_node)) \ + MPP_FINALLY (4, gl_list_iterator_free (&list##_iter)) + +#define GL_MAP_FOREACH(map, key, value) \ + MPP_DECLARE (1, gl_map_iterator_t map##_iter = gl_map_iterator (map)) \ + MPP_WHILE (2, gl_map_iterator_next (&map##_iter, \ + (const void **) &key, \ + (const void **) &value)) \ + MPP_FINALLY (3, gl_map_iterator_free (&map##_iter)) + +#endif /* MAN_GLCONTAINERS_H */ diff --git a/lib/linelength.c b/lib/linelength.c new file mode 100644 index 0000000..875000d --- /dev/null +++ b/lib/linelength.c @@ -0,0 +1,110 @@ +/* + * linelength.c: find the terminal line length + * Preferences: 1. MANWIDTH, 2. COLUMNS, 3. ioctl, 4. 80 + * + * Originally adapted from Andries Brouwer's man implementation, also + * released under the GPL: authors believed to include Martin Schulze and + * Jon Tombs, dated 1995/09/02. + * + * Changes for man-db copyright (C) 2001, 2003, 2007 Colin Watson. + * + * This file is part of man-db. + * + * man-db is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * man-db 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 man-db; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif /* HAVE_CONFIG_H */ + +#include <stdlib.h> +#include <stdio.h> +#include <unistd.h> +#include <termios.h> +#include <sys/ioctl.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> + +#include "linelength.h" + +#ifndef _PATH_TTY +# define _PATH_TTY "/dev/tty" +#endif /* _PATH_TTY */ + +static int line_length = -1; + +int get_line_length (void) +{ + const char *columns; + int width; +#ifdef TIOCGWINSZ + int dev_tty, tty_fd = -1; +#endif + + if (line_length != -1) + return line_length; + + line_length = 80; + + columns = getenv ("MANWIDTH"); + if (columns != NULL) { + width = atoi (columns); + if (width > 0) + return line_length = width; + } + + columns = getenv ("COLUMNS"); + if (columns != NULL) { + width = atoi (columns); + if (width > 0) + return line_length = width; + } + +#ifdef TIOCGWINSZ + /* Original TIOCGWINSZ approach was from Jon Tombs. + * We don't require both stdin and stdout to be a tty, and line + * length is primarily a property of output. However, if it happens + * that stdin is connected to a terminal but stdout isn't, then that + * may well be because the user is trying something like + * 'MAN_KEEP_STDERR=1 man foo >/dev/null' to see just the error + * messages, so use the window size from stdin as a fallback. + * In some cases we may have neither (e.g. if man is running inside + * lesspipe); /dev/tty should be a reliable way to get to the + * current tty if it exists. + */ + dev_tty = open (_PATH_TTY, O_RDONLY); + if (dev_tty >= 0) + tty_fd = dev_tty; + else if (isatty (STDOUT_FILENO)) + tty_fd = STDOUT_FILENO; + else if (isatty (STDIN_FILENO)) + tty_fd = STDIN_FILENO; + if (tty_fd >= 0) { + int ret; + struct winsize wsz; + + ret = ioctl (tty_fd, TIOCGWINSZ, &wsz); + if (dev_tty >= 0) + close (dev_tty); + if (ret) + perror ("TIOCGWINSZ failed"); + else if (wsz.ws_col) + return line_length = wsz.ws_col; + } +#endif + + return line_length = 80; +} diff --git a/lib/linelength.h b/lib/linelength.h new file mode 100644 index 0000000..49d958f --- /dev/null +++ b/lib/linelength.h @@ -0,0 +1,23 @@ +/* + * linelength.h: interface to find the terminal line length + * + * Copyright (C) 2007 Colin Watson. + * + * This file is part of man-db. + * + * man-db is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * man-db 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 man-db; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +int get_line_length (void); diff --git a/lib/mp.h b/lib/mp.h new file mode 100644 index 0000000..df31eae --- /dev/null +++ b/lib/mp.h @@ -0,0 +1,483 @@ +/* + * mp.h: header file providing macros for 'metaprogramming' custom + * loop constructions in standard C. + * + * Accompanies the article on the web at + * https://www.chiark.greenend.org.uk/~sgtatham/mp/ + */ + +/* + * mp.h is copyright 2012 Simon Tatham. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL SIMON TATHAM BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF + * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * $Id$ + */ + +/* + * Macros beginning with 'MPI_' are internal to this header file, and + * intended only to be used by other macros defined _in_ this header + * file. Do not refer to them externally. + */ + +/* Standard trickery to allow us to macro-expand and then token-paste */ +#define MPI_TOKPASTEINNER(x,y) x ## y +#define MPI_TOKPASTE(x,y) MPI_TOKPASTEINNER(x,y) + +/* Method of constructing line-unique labels */ +#define MPI_LABEL(id1,id2) \ + MPI_TOKPASTE(MPI_LABEL_ ## id1 ## _ ## id2 ## _, __LINE__) + +/* + * Macros beginning with 'MPP_' and 'MPS_' are building blocks + * intended for metaprogrammers to make useful control constructions + * from. + * + * The prefixes distinguish their syntactic role. MPP_ macros are + * statement _prefixes_; you would typically build a custom control + * structure by defining a macro expanding to a sequence of them. MPS_ + * macros are actual statements, which you might use in the various + * parameters of MPP_ macros that are expected to be statement-shaped. + */ + +/* + * Safety considerations: + * + * - All of these macros are C89-safe, except for MPP_DECLARE if you + * pass an actual declaration and not just an assignment, since + * that one relies on the C99 (and C++) extension of being able to + * write a declaration in the initialisation clause of a for + * statement. + * + * - None of these macros uses switch, so case labels from a switch + * outside the whole lot may be written inside the suffixed + * statement/block. + * + * - All of these constructions use 'goto' with labels constructed + * programmatically, using __LINE__ to make them unique between + * multiple invocations of the same loop macro. So don't put two + * loop macros defined using these building blocks on the same + * source line. + * + * - All of these constructions can be prefixed to something that is + * syntactically a single C statement, and generate something that + * is also a single C statement. So they're if-else safe - you can + * use an unbraced one of these constructs followed by an unbraced + * statement within the then-clause of an outer if, and the else + * will still bind to what it looks as if it ought to. + * + * - Controlling what happens if the user writes a 'break' in the + * suffixed statement is unavoidably rather fiddly. The macros + * below fall into a few categories: + * + * + naturally transparent to 'break' (MPP_BEFORE, MPP_IF). Macros + * of this type will not affect the semantics of 'break' in the + * suffixed statement at all - it will terminate the next + * innermost loop or switch outside the construction. + * + * + artificially transparent to 'break', by means of deliberately + * catching and 'rethrowing' it. (MPP_BREAK_{THROW,CATCH}; + * MPP_BREAK_HANDLER; MPP_FINALLY.) These macros will propagate + * a break outwards to the next containing loop, but in order to + * do so they require that there _be_ a next containing loop, + * since their expansion can't avoid including a break statement + * which they themselves do not wrap in a loop. So you should + * only use these when you know there is a containing loop (e.g. + * because MPP_WHILE or MPP_DO_WHILE precedes them in your + * construction). + * + * + loop constructions. (MPP_WHILE and MPP_DO_WHILE). These + * macros give 'break' the obvious semantics of terminating the + * loop they define. + * + * + break-unsafe macros, which have to include a C looping + * construction to do something not essentially loopy, and hence + * have the unfortunate side effect of causing 'break' to only + * terminate the suffixed statement itself. On the other hand, + * they can be used in contexts where there is no surrounding + * loop at all (which is why I don't just fix them to contain a + * built-in MPP_BREAK_{THROW,CATCH}). + * + * If you are using these macros to build a looping construct, then + * you will probably include an MPP_WHILE or MPP_DO_WHILE in your + * stack, and you'll want 'break' to terminate that. So you just + * need to be sure that break is correctly propagated from the + * suffixed statement back to that loop, which you can do by + * sticking to the break-transparent macros where possible and + * using MPP_BREAK_{THROW,CATCH} to bypass any break-unsafe macro + * such as MPP_DECLARE that you might need to use. Having done + * that, 'break' will do what the user expects. + * + * But if you're using the macros to wrap some context around a + * statement you still intend to be executed only once, there will + * be unavoidable side effects on 'break': you can't use the + * artificially break-unsafe macros because the user might use your + * construction in a context with no surrounding loop at all, so + * you must stick to the naturally break-transparent and the + * break-unsafe, and there aren't enough of the former to be really + * useful. So you must just live with 'break' acquiring unhelpful + * behaviour inside such a macro. + * + * - Almost none of these macros is transparent to 'continue'. The + * naturally break-transparent MPP_BEFORE is, but none of the rest + * can possibly be, because as soon as you include any loop + * construction in the stuff being prefixed to a statement, you + * introduce the invariant that 'continue' is equivalent to jumping + * to the end of the suffixed statement or block. This is not too + * bad if you're defining a custom loop construction (it was quite + * likely the behaviour you wanted for continue anyway), but if you + * were trying to use MPP_DECLARE and/or MPP_BEFORE_AND_AFTER to + * wrap a statement in some context but still only execute it once, + * you'd have to be aware of that limitation. + * + * - MPP_FINALLY and MPP_BREAK_HANDLER can only catch non-local exits + * from the block _by break_. They are not true C++ try/finally, so + * they can't catch other kinds of exit such as return, goto, + * longjmp or exit. + * + * - Finally, it almost goes without saying, but don't forget that + * snippets of code you use as parameters to these macros must + * avoid using commas not contained inside parentheses, or else the + * C preprocessor will consider the comma to end that macro + * parameter and start the next one. If there is any reason you + * really need an unbracketed comma, you can work around this by + * one of two methods: + * - define a macro that expands to a comma ('#define COMMA ,') + * and then use that macro in place of commas in your macro + * argument. It won't be expanded to an actual comma until after + * the argument-separation has finished. + * - if you're allowed to use C99, define a variadic macro that + * expands to its unmodified input argument list ('#define + * WRAP(...) __VA_ARGS__') and then enclose comma-using code in + * WRAP(). Again, this will protect the commas for just long + * enough. + */ + +/* + * MPP_BEFORE: run the code given in the argument 'before' and then + * the suffixed statement. + * + * 'before' should have the syntactic form of one or more declarations + * and statements, except that a trailing semicolon may be omitted. + * Any declarations will be in scope only within 'before', not within + * the suffixed statement. + * + * This macro, unusually among the collection, is naturally + * transparent to 'break' and also transparent to 'continue'. + */ +#define MPP_BEFORE(labid,before) \ + if (1) { \ + before; \ + goto MPI_LABEL(labid, body); \ + } else \ + MPI_LABEL(labid, body): + +/* + * MPP_AFTER: run the suffixed statement, and then the code given in + * the argument 'after'. + * + * 'after' should have the syntactic form of one or more declarations + * and statements, except that a trailing semicolon may be omitted. + * Any declaration in 'after' will be in scope only within 'after'. + * + * This macro is break-unsafe - it causes a 'break' to terminate the + * suffixed statement only. If you need different behaviour, you can + * use MPP_BREAK_CATCH and MPP_BREAK_THROW to pass a break past it - + * but beware that in that case the 'after' clause will not be + * executed, so MPP_FINALLY or MPP_BREAK_HANDLER may be useful too. + */ +#define MPP_AFTER(labid,after) \ + if (1) \ + goto MPI_LABEL(labid, body); \ + else \ + while (1) \ + if (1) { \ + after; \ + break; \ + } else \ + MPI_LABEL(labid, body): + +/* + * MPP_DECLARE: run the 'declaration' argument before the suffixed + * statement. The argument may have the form of either a C expression + * (e.g. an assignment) or a declaration; if the latter, it will be in + * scope within the suffixed statement. + * + * This macro is break-unsafe - it causes a 'break' to terminate the + * suffixed statement only. If you need different behaviour, you can + * use MPP_BREAK_CATCH and MPP_BREAK_THROW to pass a break past it. + */ +#define MPP_DECLARE(labid, declaration) \ + if (0) \ + ; \ + else \ + for (declaration;;) \ + if (1) { \ + goto MPI_LABEL(labid, body); \ + MPI_LABEL(labid, done): break; \ + } else \ + while (1) \ + if (1) \ + goto MPI_LABEL(labid, done); \ + else \ + MPI_LABEL(labid, body): +/* (The 'if(0) ; else' at the start of the above is just in case we + * encounter an old-style compiler that considers variables declared + * in for statements to have scope extending beyond the for statement. + * Putting another layer outside the 'for' ensures that the variable's + * scope is constrained to _that_ layer even if not to the for itself, + * and it doesn't leak into the calling scope. */ + +/* + * MPP_WHILE: run the suffixed statement within a 'while (condition)' + * loop. + * + * In fact, just writing 'while (condition)' works fine for this, but + * it's nice to make it look like the rest of these macros! + * + * This macro defines an actual loop, and 'break' in the suffixed + * statement terminates that loop as you would expect. + */ +#define MPP_WHILE(labid, condition) \ + while (condition) + +/* + * MPP_DO_WHILE: run the suffixed statement within a loop with the + * semantics of 'do suffixed-statement while (condition)'. + * + * This macro defines an actual loop, and 'break' in the suffixed + * statement terminates that loop as you would expect. + */ +#define MPP_DO_WHILE(labid, condition) \ + if (1) \ + goto MPI_LABEL(labid, body); \ + else \ + while (condition) \ + MPI_LABEL(labid, body): + +/* + * MPP_IF: run the suffixed statement only if 'condition' is true. + * + * This macro is naturally transparent to 'break' and also transparent + * to 'continue'. + */ +#define MPP_IF(labid, condition) \ + if (!(condition)) \ + ; \ + else + +/* + * MPP_BREAK_THROW and MPP_BREAK_CATCH: propagate 'break' control flow + * transfers past other prefixes that mess about with them. + * + * Write an MPP_BREAK_CATCH, then other metaprogramming prefixes from + * this collection, and then an MPP_BREAK_THROW with the same label + * id. If the statement following the MPP_BREAK_THROW terminates by + * 'break', then the effect will be as if the MPP_BREAK_CATCH had + * terminated by 'break', regardless of how the in-between prefixes + * would have handled a 'break'. + * + * These macros are artificially transparent to 'break': they pass + * break through, but include a 'break' statement at the top level of + * MPP_BREAK_CATCH, so that must always be contained inside some loop + * or switch construction. + * + * We also provide MPS_BREAK_THROW, which is a statement-type macro + * that manufactures a break event and passes it to a specified + * MPP_BREAK_CATCH. + */ +#define MPP_BREAK_CATCH(labid) \ + if (0) \ + MPI_LABEL(labid, catch): break; \ + else + +#define MPP_BREAK_THROW(labid) \ + if (1) { \ + goto MPI_LABEL(labid, body); \ + MPI_LABEL(labid, finish):; \ + } else \ + while (1) \ + if (1) \ + goto MPI_LABEL(labid, catch); \ + else \ + while (1) \ + if (1) \ + goto MPI_LABEL(labid, finish); \ + else \ + MPI_LABEL(labid, body): + +#define MPS_BREAK_THROW(labid) goto MPI_LABEL(labid, catch) + +/* + * MPP_BREAK_HANDLER: handle a 'break' in the suffixed statement by + * executing the provided handler code and then terminating as if by + * break. + * + * 'handler' should have the syntactic form of one or more + * declarations and statements, except that a trailing semicolon may + * be omitted. + * + * This macro is artificially transparent to 'break': it passes break + * through, but includes a 'break' statement at the top level, so it + * must always be contained inside some loop or switch construction. + */ +#define MPP_BREAK_HANDLER(labid, handler) \ + if (1) { \ + goto MPI_LABEL(labid, body); \ + MPI_LABEL(labid, break): \ + {handler;} \ + break; \ + MPI_LABEL(labid, finish):; \ + } else \ + while (1) \ + if (1) \ + goto MPI_LABEL(labid, break); \ + else \ + while (1) \ + if (1) \ + goto MPI_LABEL(labid, finish); \ + else \ + MPI_LABEL(labid, body): + +/* + * MPP_FINALLY: execute the suffixed statement, and execute the + * provided 'finally' clause after it finishes. If it terminates by + * 'break', execute the same 'finally' clause but propagate the break + * to the containing statement. + * + * 'finally' should have the syntactic form of one or more + * declarations and statements, except that a trailing semicolon may + * be omitted. + * + * The 'finally' argument will be double-expanded. Of course it'll + * only be executed once in any given run, so that's not a concern for + * function side effects, but don't do anything fiddly like declaring + * a static variable to which you return a pointer and then expecting + * the pointer to be the same no matter which copy of 'finally' it + * came from. + * + * This macro is artificially transparent to 'break': it passes break + * through, but includes a 'break' statement at the top level, so it + * must always be contained inside some loop or switch construction. + */ +#define MPP_FINALLY(labid, finally) \ + if (1) { \ + goto MPI_LABEL(labid, body); \ + MPI_LABEL(labid, break): \ + {finally;} \ + break; \ + MPI_LABEL(labid, finish): \ + {finally;} \ + } else \ + while (1) \ + if (1) \ + goto MPI_LABEL(labid, break); \ + else \ + while (1) \ + if (1) \ + goto MPI_LABEL(labid, finish); \ + else \ + MPI_LABEL(labid, body): + +/* + * MPP_BREAK_STOP: handle a 'break' in the suffixed statement by + * executing the provided handler code and then terminating as if + * normally. + * + * 'handler' should have the syntactic form of one or more + * declarations and statements, except that a trailing semicolon may + * be omitted. + */ +#define MPP_BREAK_STOP(labid, handler) \ + if (1) { \ + goto MPI_LABEL(labid, body); \ + MPI_LABEL(labid, break): \ + {handler;} \ + MPI_LABEL(labid, finish):; \ + } else \ + while (1) \ + if (1) \ + goto MPI_LABEL(labid, break); \ + else \ + while (1) \ + if (1) \ + goto MPI_LABEL(labid, finish); \ + else \ + MPI_LABEL(labid, body): + +/* + * MPP_ELSE_ACCEPT, MPS_MAIN_INVOKE, MPS_ELSE_INVOKE: arrange to + * accept an optional 'else' clause after the suffixed statement, and + * provide two statement macros which jump to the main clause and the + * else clause. The main (non-else) clause will be be executed in the + * default case, and can be invoked again using MPS_MAIN_INVOKE; + * MPS_ELSE_INVOKE will invoke the else clause. + * + * Like MPP_BREAK_THROW and MPP_BREAK_CATCH, these macros should be + * used in groups with the same label id, so as to match them up to + * each other. MPS_ELSE_INVOKE and MPS_MAIN_INVOKE will go to the + * appropriate clauses corresponding to the MPP_ELSE_ACCEPT with the + * same id. + */ +#define MPP_ELSE_ACCEPT(labid) \ + if (1) \ + goto MPI_LABEL(labid, body); \ + else \ + MPI_LABEL(labid, else): \ + if (0) \ + MPI_LABEL(labid, body): + +#define MPS_MAIN_INVOKE(labid) \ + goto MPI_LABEL(labid, body) + +#define MPS_ELSE_INVOKE(labid) \ + goto MPI_LABEL(labid, else) + +/* + * MPP_ELSE_GENERAL: like MPP_ELSE_ACCEPT, but also lets you provide a + * snippet of code that will be run after the else clause terminates + * and one which will be run after the else clause breaks. + * + * You can use MPS_MAIN_INVOKE and MPS_ELSE_INVOKE with this as well + * as with MPP_ELSE_ACCEPT. + * + * Will mess up what happens after the main body, so you'll probably + * want to follow this macro with others such as MPP_AFTER and + * something to catch break in the main body too. + */ +#define MPP_ELSE_GENERAL(labid, after, breakhandler) \ + if (1) \ + goto MPI_LABEL(labid, body); \ + else \ + while (1) \ + if (1) { \ + {breakhandler;} \ + break; \ + } else \ + while (1) \ + if (1) { \ + {after;} \ + break; \ + } else \ + MPI_LABEL(labid, else): \ + if (0) \ + MPI_LABEL(labid, body): diff --git a/lib/orderfiles.c b/lib/orderfiles.c new file mode 100644 index 0000000..05bafe9 --- /dev/null +++ b/lib/orderfiles.c @@ -0,0 +1,180 @@ +/* + * orderfiles.c: order file accesses to optimise disk load + * + * Copyright (C) 2014 Colin Watson. + * + * Inspired by and loosely based on dpkg/src/filesdb.c, which is: + * Copyright (C) 1995 Ian Jackson <ian@chiark.greenend.org.uk> + * Copyright (C) 2000,2001 Wichert Akkerman <wakkerma@debian.org> + * Copyright (C) 2008-2014 Guillem Jover <guillem@debian.org> + * + * This file is part of man-db. + * + * man-db is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * man-db 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 man-db; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif /* HAVE_CONFIG_H */ + +#ifdef HAVE_LINUX_FIEMAP_H +# include <linux/fiemap.h> +# include <linux/fs.h> +# include <sys/ioctl.h> +# include <sys/vfs.h> +#endif /* HAVE_LINUX_FIEMAP_H */ + +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <stdint.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +#include "attribute.h" +#include "gl_hash_map.h" +#include "gl_rbtree_list.h" +#include "gl_xlist.h" +#include "gl_xmap.h" +#include "xalloc.h" + +#include "manconfig.h" + +#include "glcontainers.h" +#include "orderfiles.h" + +#if defined(HAVE_LINUX_FIEMAP_H) +gl_map_t physical_offsets = NULL; + +static int compare_physical_offsets (const void *a, const void *b) +{ + const char *left = (const char *) a; + const char *right = (const char *) b; + const uint64_t *left_offset_p = gl_map_get (physical_offsets, left); + const uint64_t *right_offset_p = gl_map_get (physical_offsets, right); + uint64_t left_offset = left_offset_p ? *left_offset_p : UINT64_MAX; + uint64_t right_offset = right_offset_p ? *right_offset_p : UINT64_MAX; + + if (left_offset < right_offset) + return -1; + else if (left_offset > right_offset) + return 1; + else + return 0; +} + +void order_files (const char *dir, gl_list_t *basenamesp) +{ + gl_list_t basenames = *basenamesp, sorted_basenames; + int dir_fd_open_flags; + int dir_fd; + struct statfs fs; + const char *name; + + dir_fd_open_flags = O_SEARCH | O_DIRECTORY; +#ifdef O_PATH + dir_fd_open_flags |= O_PATH; +#endif + dir_fd = open (dir, dir_fd_open_flags); + if (dir_fd < 0) + return; + + if (fstatfs (dir_fd, &fs) < 0) { + close (dir_fd); + return; + } + + /* Sort files by the physical locations of their first blocks, in an + * attempt to minimise disk drive head movements. This assumes that + * files are small enough that they are likely to be in one block or + * a small number of contiguous blocks, which seems a reasonable + * assumption for manual pages. + */ + physical_offsets = gl_map_create_empty (GL_HASH_MAP, string_equals, + string_hash, NULL, plain_free); + sorted_basenames = new_string_list (GL_RBTREE_LIST, false); + GL_LIST_FOREACH (basenames, name) { + struct { + struct fiemap fiemap; + struct fiemap_extent extent; + } fm; + int fd; + + fd = openat (dir_fd, name, O_RDONLY); + if (fd < 0) + continue; + + memset (&fm, 0, sizeof (fm)); + fm.fiemap.fm_start = 0; + fm.fiemap.fm_length = fs.f_bsize; + fm.fiemap.fm_flags = 0; + fm.fiemap.fm_extent_count = 1; + + if (ioctl (fd, FS_IOC_FIEMAP, (unsigned long) &fm) == 0) { + uint64_t *offset = XMALLOC (uint64_t); + *offset = fm.extent.fe_physical; + /* Borrow the key from basenames; since + * physical_offsets has a shorter lifetime, we don't + * need to duplicate it. + */ + gl_map_put (physical_offsets, name, offset); + } + + close (fd); + gl_sortedlist_add (sorted_basenames, compare_physical_offsets, + xstrdup (name)); + } + gl_map_free (physical_offsets); + physical_offsets = NULL; + close (dir_fd); + gl_list_free (basenames); + *basenamesp = sorted_basenames; +} +#elif defined(HAVE_POSIX_FADVISE) +void order_files (const char *dir, gl_list_t *basenamesp) +{ + gl_list_t basenames = *basenamesp; + int dir_fd_open_flags; + int dir_fd; + const char *name; + + dir_fd_open_flags = O_SEARCH | O_DIRECTORY; +#ifdef O_PATH + dir_fd_open_flags |= O_PATH; +#endif + dir_fd = open (dir, dir_fd_open_flags); + if (dir_fd < 0) + return; + + /* While we can't actually order the files, we can at least ask the + * kernel to preload them. + */ + GL_LIST_FOREACH (basenames, name) { + int fd = openat (dir_fd, name, O_RDONLY | O_NONBLOCK); + if (fd >= 0) { + posix_fadvise (fd, 0, 0, POSIX_FADV_WILLNEED); + close (fd); + } + } + + close (dir_fd); +} +#else +void order_files (const char *dir MAYBE_UNUSED, + gl_list_t *basenamesp MAYBE_UNUSED) +{ +} +#endif diff --git a/lib/orderfiles.h b/lib/orderfiles.h new file mode 100644 index 0000000..dae41cc --- /dev/null +++ b/lib/orderfiles.h @@ -0,0 +1,25 @@ +/* + * orderfiles.h: interface to ordering file accesses to optimise disk load + * + * Copyright (C) 2014 Colin Watson. + * + * This file is part of man-db. + * + * man-db is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * man-db 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 man-db; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "gl_list.h" + +void order_files (const char *dir, gl_list_t *basenamesp); diff --git a/lib/pathsearch.c b/lib/pathsearch.c new file mode 100644 index 0000000..34eac08 --- /dev/null +++ b/lib/pathsearch.c @@ -0,0 +1,146 @@ +/* + * pathsearch.c: $PATH-searching functions. + * + * Copyright (C) 2004, 2007, 2008, 2009, 2011 Colin Watson. + * + * This file is part of man-db. + * + * man-db is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * man-db 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 man-db; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif /* HAVE_CONFIG_H */ + +#include <assert.h> +#include <errno.h> +#include <stdbool.h> +#include <string.h> +#include <stdlib.h> + +#include <sys/types.h> +#include <sys/stat.h> +#include <unistd.h> + +#include "gettext.h" +#define _(String) gettext (String) + +#include "xalloc.h" +#include "xgetcwd.h" +#include "xvasprintf.h" + +#include "manconfig.h" + +#include "fatal.h" +#include "pathsearch.h" + +static bool pathsearch (const char *name, const mode_t bits) +{ + char *cwd = NULL; + char *path = getenv ("PATH"); + char *pathtok; + const char *element; + struct stat st; + bool ret = false; + + if (!path) + /* Eh? Oh well. */ + return false; + + if (strchr (name, '/')) { + /* Qualified name; look directly. */ + if (stat (name, &st) == -1) + return false; + if (S_ISREG (st.st_mode) && (st.st_mode & bits)) + return true; + return false; + } + + pathtok = path = xstrdup (path); + + /* Unqualified name; iterate over $PATH looking for it. */ + for (element = strsep (&pathtok, ":"); element; + element = strsep (&pathtok, ":")) { + char *filename; + + if (!*element) { + if (!cwd) + cwd = xgetcwd (); + if (!cwd) + fatal (errno, + _("can't determine current directory")); + element = cwd; + } + + filename = xasprintf ("%s/%s", element, name); + assert (filename); + if (stat (filename, &st) == -1) { + free (filename); + continue; + } + + free (filename); + + if (S_ISREG (st.st_mode) && (st.st_mode & bits)) { + ret = true; + break; + } + } + + free (path); + free (cwd); + return ret; +} + +bool pathsearch_executable (const char *name) +{ + return pathsearch (name, 0111); +} + +bool directory_on_path (const char *dir) +{ + char *cwd = NULL; + char *path = getenv ("PATH"); + char *pathtok; + const char *element; + bool ret = false; + + if (!path) + /* Eh? Oh well. */ + return false; + + pathtok = path = xstrdup (path); + + for (element = strsep (&pathtok, ":"); element; + element = strsep (&pathtok, ":")) { + if (!*element) { + if (!cwd) + cwd = xgetcwd (); + if (!cwd) + fatal (errno, + _("can't determine current directory")); + element = cwd; + } + + if (STREQ (element, dir)) { + ret = true; + break; + } + } + + free (path); + free (cwd); + return ret; +} diff --git a/lib/pathsearch.h b/lib/pathsearch.h new file mode 100644 index 0000000..d9b024d --- /dev/null +++ b/lib/pathsearch.h @@ -0,0 +1,36 @@ +/* + * pathsearch.h: interface to $PATH-searching functions + * + * Copyright (C) 2004 Colin Watson. + * + * This file is part of man-db. + * + * man-db is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * man-db 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 man-db; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#ifndef PATHSEARCH_H +#define PATHSEARCH_H + +#include <stdbool.h> + +/* Return true if NAME is found as an executable regular file on the $PATH, + * otherwise false. + */ +bool pathsearch_executable (const char *name); + +/* Return true if DIR matches an entry on the $PATH, otherwise false. */ +bool directory_on_path (const char *dir); + +#endif /* PATHSEARCH_H */ diff --git a/lib/sandbox.c b/lib/sandbox.c new file mode 100644 index 0000000..ca218f5 --- /dev/null +++ b/lib/sandbox.c @@ -0,0 +1,688 @@ +/* + * sandbox.c: Process sandboxing + * + * Copyright (C) 2017 Colin Watson. + * + * This file is part of man-db. + * + * man-db is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * man-db 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 man-db; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + * Some of the syscall lists in this file come from systemd, whose + * copyright/licensing statement is as follows. Per LGPLv2.1 s. 3, I have + * altered the original references to LGPLv2.1 to refer to GPLv2 instead. + * + * Copyright 2014 Lennart Poettering + * + * systemd is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * systemd 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 systemd; If not, see <https://www.gnu.org/licenses/>. + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif /* HAVE_CONFIG_H */ + +#include <stdbool.h> +#include <errno.h> +#include <stdlib.h> +#include <string.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <unistd.h> + +#ifdef HAVE_LIBSECCOMP +# include <sys/ioctl.h> +# include <sys/ipc.h> +# include <sys/mman.h> +# include <sys/prctl.h> +# include <sys/shm.h> +# include <sys/socket.h> +# include <termios.h> +# include <seccomp.h> +#endif /* HAVE_LIBSECCOMP */ + +#include "attribute.h" +#include "xalloc.h" +#include "xstrndup.h" + +#include "manconfig.h" + +#include "debug.h" +#include "fatal.h" +#include "sandbox.h" + +struct man_sandbox { +#ifdef HAVE_LIBSECCOMP + scmp_filter_ctx ctx; + scmp_filter_ctx permissive_ctx; +#else /* !HAVE_LIBSECCOMP */ + char dummy; +#endif /* HAVE_LIBSECCOMP */ +}; + +#ifdef HAVE_LIBSECCOMP +static bool seccomp_filter_unavailable = false; + +static void gripe_seccomp_filter_unavailable (void) +{ + debug ("seccomp filtering requires a kernel configured with " + "CONFIG_SECCOMP_FILTER\n"); +} + +static bool search_ld_preload (const char *needle) +{ + const char *ld_preload_env; + static char *ld_preload_file = NULL; + + ld_preload_env = getenv ("LD_PRELOAD"); + if (ld_preload_env && strstr (ld_preload_env, needle) != NULL) + return true; + + if (!ld_preload_file) { + int fd; + struct stat st; + char *mapped = NULL; + + fd = open ("/etc/ld.so.preload", O_RDONLY); + if (fd >= 0 && fstat (fd, &st) >= 0 && st.st_size) + mapped = mmap (NULL, st.st_size, PROT_READ, + MAP_PRIVATE | MAP_FILE, fd, 0); + if (mapped) { + ld_preload_file = xstrndup (mapped, st.st_size); + munmap (mapped, st.st_size); + } else + ld_preload_file = xstrdup (""); + if (fd >= 0) + close (fd); + } + /* This isn't very accurate: /etc/ld.so.preload may contain + * comments. On the other hand, glibc says "it should only be used + * for emergencies and testing". File a bug if this is a problem + * for you. + */ + if (strstr (ld_preload_file, needle) != NULL) + return true; + + return false; +} + +/* Can we load a seccomp filter into this process? + * + * This guard allows us to call sandbox_load in code paths that may + * conditionally do so again. + */ +static bool can_load_seccomp (void) +{ + const char *man_disable_seccomp; + int seccomp_status; + + if (seccomp_filter_unavailable) { + gripe_seccomp_filter_unavailable (); + return false; + } + + man_disable_seccomp = getenv ("MAN_DISABLE_SECCOMP"); + if (man_disable_seccomp && *man_disable_seccomp) { + debug ("seccomp filter disabled by user request\n"); + return false; + } + + /* Valgrind causes the child process to make some system calls we + * don't want to allow in general, so disable seccomp when running + * on Valgrind. + * + * The correct approach seems to be to either require valgrind.h at + * build-time or copy valgrind.h into this project and then use the + * RUNNING_ON_VALGRIND macro, but I'd really rather not add a + * build-dependency for this or take a copy of a >6000-line header + * file. Since the goal of this is only to disable the seccomp + * filter under Valgrind, this will do for now. + */ + if (search_ld_preload ("/vgpreload")) { + debug ("seccomp filter disabled while running under " + "Valgrind\n"); + return false; + } + + seccomp_status = prctl (PR_GET_SECCOMP); + + if (seccomp_status == 0) + return true; + + if (seccomp_status == -1) { + if (errno == EINVAL) + debug ("running kernel does not support seccomp\n"); + else + debug ("unknown error getting seccomp status: %s\n", + strerror (errno)); + } else if (seccomp_status == 2) + debug ("seccomp already enabled\n"); + else + debug ("unknown return value from PR_GET_SECCOMP: %d\n", + seccomp_status); + return false; +} +#endif /* HAVE_LIBSECCOMP */ + +#ifdef HAVE_LIBSECCOMP + +#define SC_ALLOW(name) \ + do { \ + int nr = seccomp_syscall_resolve_name (name); \ + if (nr == __NR_SCMP_ERROR) \ + break; \ + if (seccomp_rule_add (ctx, SCMP_ACT_ALLOW, nr, 0) < 0) \ + fatal (errno, "can't add seccomp rule"); \ + } while (0) + +#define SC_ALLOW_PERMISSIVE(name) \ + do { \ + if (permissive) \ + SC_ALLOW (name); \ + } while (0) + +#define SC_ALLOW_ARG_1(name, cmp1) \ + do { \ + int nr = seccomp_syscall_resolve_name (name); \ + if (nr == __NR_SCMP_ERROR) \ + break; \ + if (seccomp_rule_add (ctx, SCMP_ACT_ALLOW, nr, 1, cmp1) < 0) \ + fatal (errno, "can't add seccomp rule"); \ + } while (0) + +#define SC_ALLOW_ARG_2(name, cmp1, cmp2) \ + do { \ + int nr = seccomp_syscall_resolve_name (name); \ + if (nr == __NR_SCMP_ERROR) \ + break; \ + if (seccomp_rule_add (ctx, SCMP_ACT_ALLOW, nr, \ + 2, cmp1, cmp2) < 0) \ + fatal (errno, "can't add seccomp rule"); \ + } while (0) + +/* Create a seccomp filter. + * + * If permissive is true, then the returned filter will allow limited file + * creation (although not making executable files). This obviously + * constitutes less effective confinement, but it's necessary for some + * subprocesses (such as groff) that need the ability to write to temporary + * files. Confining these further requires additional tools that can do + * path-based filtering or similar, such as AppArmor. + */ +static scmp_filter_ctx make_seccomp_filter (bool permissive) +{ + scmp_filter_ctx ctx; + mode_t mode_mask = S_ISUID | S_ISGID | S_IXUSR | S_IXGRP | S_IXOTH; + int create_mask = O_CREAT +#ifdef O_TMPFILE + | O_TMPFILE +#endif /* O_TMPFILE */ + ; + + if (!can_load_seccomp ()) + return NULL; + + debug ("initialising seccomp filter (permissive: %d)\n", + (int) permissive); + ctx = seccomp_init (SCMP_ACT_ERRNO (ENOSYS)); + if (!ctx) + fatal (errno, "can't initialise seccomp filter"); + + /* Allow sibling architectures for x86, since people sometimes mix + * and match architectures there for performance reasons. + */ + switch (seccomp_arch_native ()) { + case SCMP_ARCH_X86: + seccomp_arch_add (ctx, SCMP_ARCH_X86_64); + seccomp_arch_add (ctx, SCMP_ARCH_X32); + break; + case SCMP_ARCH_X86_64: + seccomp_arch_add (ctx, SCMP_ARCH_X86); + seccomp_arch_add (ctx, SCMP_ARCH_X32); + break; + case SCMP_ARCH_X32: + seccomp_arch_add (ctx, SCMP_ARCH_X86); + seccomp_arch_add (ctx, SCMP_ARCH_X86_64); + break; + } + + /* This sandbox is intended to allow operations that might + * reasonably be needed in simple data-transforming pipes: it should + * allow the process to do most reasonable things to itself, to read + * and write data from and to already-open file descriptors, to open + * files in read-only mode, and to fork new processes with the same + * restrictions. (If permissive is true, then it should also allow + * limited file creation; see the header comment above.) + * + * Since I currently know of no library with suitable syscall lists, + * the syscall lists here are taken from + * systemd:src/shared/seccomp-util.c, last updated from commit + * ab9617a76624c43a26de7e94424088ae171ebfef (2023-08-07). + */ + + /* systemd: SystemCallFilter=@default */ + SC_ALLOW ("arch_prctl"); + SC_ALLOW ("brk"); + SC_ALLOW ("cacheflush"); + SC_ALLOW ("clock_getres"); + SC_ALLOW ("clock_getres_time64"); + SC_ALLOW ("clock_gettime"); + SC_ALLOW ("clock_gettime64"); + SC_ALLOW ("clock_nanosleep"); + SC_ALLOW ("clock_nanosleep_time64"); + SC_ALLOW ("execve"); + SC_ALLOW ("exit"); + SC_ALLOW ("exit_group"); + SC_ALLOW ("futex"); + SC_ALLOW ("futex_time64"); + SC_ALLOW ("futex_waitv"); + SC_ALLOW ("get_robust_list"); + SC_ALLOW ("get_thread_area"); + SC_ALLOW ("getegid"); + SC_ALLOW ("getegid32"); + SC_ALLOW ("geteuid"); + SC_ALLOW ("geteuid32"); + SC_ALLOW ("getgid"); + SC_ALLOW ("getgid32"); + SC_ALLOW ("getgroups"); + SC_ALLOW ("getgroups32"); + SC_ALLOW ("getpgid"); + SC_ALLOW ("getpgrp"); + SC_ALLOW ("getpid"); + SC_ALLOW ("getppid"); + SC_ALLOW ("getrandom"); + SC_ALLOW ("getresgid"); + SC_ALLOW ("getresgid32"); + SC_ALLOW ("getresuid"); + SC_ALLOW ("getresuid32"); + SC_ALLOW ("getrlimit"); + SC_ALLOW ("getsid"); + SC_ALLOW ("gettid"); + SC_ALLOW ("gettimeofday"); + SC_ALLOW ("getuid"); + SC_ALLOW ("getuid32"); + SC_ALLOW ("membarrier"); + SC_ALLOW ("mmap"); + SC_ALLOW ("mmap2"); + SC_ALLOW ("mprotect"); + SC_ALLOW ("munmap"); + SC_ALLOW ("nanosleep"); + SC_ALLOW ("pause"); + SC_ALLOW ("prlimit64"); + SC_ALLOW ("restart_syscall"); + SC_ALLOW ("riscv_flush_icache"); + SC_ALLOW ("riscv_hwprobe"); + SC_ALLOW ("rseq"); + SC_ALLOW ("rt_sigreturn"); + SC_ALLOW ("sched_getaffinity"); + SC_ALLOW ("sched_yield"); + SC_ALLOW ("set_robust_list"); + SC_ALLOW ("set_thread_area"); + SC_ALLOW ("set_tid_address"); + SC_ALLOW ("set_tls"); + SC_ALLOW ("sigreturn"); + SC_ALLOW ("time"); + SC_ALLOW ("ugetrlimit"); + + /* systemd: SystemCallFilter=@basic-io */ + SC_ALLOW ("_llseek"); + SC_ALLOW ("close"); + SC_ALLOW ("close_range"); + SC_ALLOW ("dup"); + SC_ALLOW ("dup2"); + SC_ALLOW ("dup3"); + SC_ALLOW ("lseek"); + SC_ALLOW ("pread64"); + SC_ALLOW ("preadv"); + SC_ALLOW ("preadv2"); + SC_ALLOW ("pwrite64"); + SC_ALLOW ("pwritev"); + SC_ALLOW ("pwritev2"); + SC_ALLOW ("read"); + SC_ALLOW ("readv"); + SC_ALLOW ("write"); + SC_ALLOW ("writev"); + + /* systemd: SystemCallFilter=@file-system (subset) */ + SC_ALLOW ("access"); + SC_ALLOW ("chdir"); + if (permissive) { + SC_ALLOW_ARG_1 ("chmod", + SCMP_A1 (SCMP_CMP_MASKED_EQ, mode_mask, 0)); + SC_ALLOW_ARG_1 ("creat", + SCMP_A1 (SCMP_CMP_MASKED_EQ, mode_mask, 0)); + } + SC_ALLOW ("faccessat"); + SC_ALLOW ("faccessat2"); + SC_ALLOW ("fallocate"); + SC_ALLOW ("fchdir"); + if (permissive) { + SC_ALLOW_ARG_1 ("fchmod", + SCMP_A1 (SCMP_CMP_MASKED_EQ, mode_mask, 0)); + SC_ALLOW_ARG_1 ("fchmodat", + SCMP_A2 (SCMP_CMP_MASKED_EQ, mode_mask, 0)); + } + SC_ALLOW ("fcntl"); + SC_ALLOW ("fcntl64"); + SC_ALLOW ("fstat"); + SC_ALLOW ("fstat64"); + SC_ALLOW ("fstatat64"); + SC_ALLOW ("fstatfs"); + SC_ALLOW ("fstatfs64"); + SC_ALLOW ("ftruncate"); + SC_ALLOW ("ftruncate64"); + SC_ALLOW_PERMISSIVE ("futimesat"); + SC_ALLOW ("getcwd"); + SC_ALLOW ("getdents"); + SC_ALLOW ("getdents64"); + SC_ALLOW_PERMISSIVE ("link"); + SC_ALLOW_PERMISSIVE ("linkat"); + SC_ALLOW ("lstat"); + SC_ALLOW ("lstat64"); + SC_ALLOW_PERMISSIVE ("mkdir"); + SC_ALLOW_PERMISSIVE ("mkdirat"); + SC_ALLOW ("newfstatat"); + SC_ALLOW ("oldfstat"); + SC_ALLOW ("oldlstat"); + SC_ALLOW ("oldstat"); + if (permissive) { + SC_ALLOW_ARG_2 ("open", + SCMP_A1 (SCMP_CMP_MASKED_EQ, O_CREAT, O_CREAT), + SCMP_A2 (SCMP_CMP_MASKED_EQ, mode_mask, 0)); + SC_ALLOW_ARG_2 ("openat", + SCMP_A2 (SCMP_CMP_MASKED_EQ, O_CREAT, O_CREAT), + SCMP_A3 (SCMP_CMP_MASKED_EQ, mode_mask, 0)); +#ifdef O_TMPFILE + SC_ALLOW_ARG_2 ("open", + SCMP_A1 (SCMP_CMP_MASKED_EQ, + O_TMPFILE, O_TMPFILE), + SCMP_A2 (SCMP_CMP_MASKED_EQ, mode_mask, 0)); + SC_ALLOW_ARG_2 ("openat", + SCMP_A2 (SCMP_CMP_MASKED_EQ, + O_TMPFILE, O_TMPFILE), + SCMP_A3 (SCMP_CMP_MASKED_EQ, mode_mask, 0)); +#endif /* O_TMPFILE */ + SC_ALLOW_ARG_1 ("open", + SCMP_A1 (SCMP_CMP_MASKED_EQ, create_mask, 0)); + SC_ALLOW_ARG_1 ("openat", + SCMP_A2 (SCMP_CMP_MASKED_EQ, create_mask, 0)); + } else { + SC_ALLOW_ARG_1 ("open", + SCMP_A1 (SCMP_CMP_MASKED_EQ, O_ACCMODE, + O_RDONLY)); + SC_ALLOW_ARG_1 ("openat", + SCMP_A2 (SCMP_CMP_MASKED_EQ, O_ACCMODE, + O_RDONLY)); + } + SC_ALLOW ("readlink"); + SC_ALLOW ("readlinkat"); + SC_ALLOW_PERMISSIVE ("rename"); + SC_ALLOW_PERMISSIVE ("renameat"); + SC_ALLOW_PERMISSIVE ("renameat2"); + SC_ALLOW_PERMISSIVE ("rmdir"); + SC_ALLOW ("stat"); + SC_ALLOW ("stat64"); + SC_ALLOW ("statfs"); + SC_ALLOW ("statfs64"); + SC_ALLOW ("statx"); + SC_ALLOW_PERMISSIVE ("symlink"); + SC_ALLOW_PERMISSIVE ("symlinkat"); + SC_ALLOW_PERMISSIVE ("truncate"); + SC_ALLOW_PERMISSIVE ("truncateat"); + SC_ALLOW_PERMISSIVE ("unlink"); + SC_ALLOW_PERMISSIVE ("unlinkat"); + SC_ALLOW_PERMISSIVE ("utime"); + SC_ALLOW_PERMISSIVE ("utimensat"); + SC_ALLOW_PERMISSIVE ("utimensat_time64"); + SC_ALLOW_PERMISSIVE ("utimes"); + + /* systemd: SystemCallFilter=@io-event */ + SC_ALLOW ("_newselect"); + SC_ALLOW ("epoll_create"); + SC_ALLOW ("epoll_create1"); + SC_ALLOW ("epoll_ctl"); + SC_ALLOW ("epoll_ctl_old"); + SC_ALLOW ("epoll_pwait"); + SC_ALLOW ("epoll_pwait2"); + SC_ALLOW ("epoll_wait"); + SC_ALLOW ("epoll_wait_old"); + SC_ALLOW ("eventfd"); + SC_ALLOW ("eventfd2"); + SC_ALLOW ("poll"); + SC_ALLOW ("ppoll"); + SC_ALLOW ("ppoll_time64"); + SC_ALLOW ("pselect6"); + SC_ALLOW ("pselect6_time64"); + SC_ALLOW ("select"); + + /* systemd: SystemCallFilter=@ipc (subset) */ + SC_ALLOW ("pipe"); + SC_ALLOW ("pipe2"); + + /* systemd: SystemCallFilter=@process (subset) */ + SC_ALLOW ("capget"); + SC_ALLOW ("clone"); + SC_ALLOW ("clone3"); + SC_ALLOW ("execveat"); + SC_ALLOW ("fork"); + SC_ALLOW ("getrusage"); + SC_ALLOW ("pidfd_open"); + SC_ALLOW ("pidfd_send_signal"); + SC_ALLOW ("prctl"); + SC_ALLOW ("vfork"); + SC_ALLOW ("wait4"); + SC_ALLOW ("waitid"); + SC_ALLOW ("waitpid"); + + /* systemd: SystemCallFilter=@signal */ + SC_ALLOW ("rt_sigaction"); + SC_ALLOW ("rt_sigpending"); + SC_ALLOW ("rt_sigprocmask"); + SC_ALLOW ("rt_sigsuspend"); + SC_ALLOW ("rt_sigtimedwait"); + SC_ALLOW ("rt_sigtimedwait_time64"); + SC_ALLOW ("sigaction"); + SC_ALLOW ("sigaltstack"); + SC_ALLOW ("signal"); + SC_ALLOW ("signalfd"); + SC_ALLOW ("signalfd4"); + SC_ALLOW ("sigpending"); + SC_ALLOW ("sigprocmask"); + SC_ALLOW ("sigsuspend"); + + /* systemd: SystemCallFilter=@sync */ + SC_ALLOW ("fdatasync"); + SC_ALLOW ("fsync"); + SC_ALLOW ("msync"); + SC_ALLOW ("sync"); + SC_ALLOW ("sync_file_range"); + SC_ALLOW ("sync_file_range2"); + SC_ALLOW ("syncfs"); + + /* systemd: SystemCallFilter=@system-service (subset) */ + SC_ALLOW ("arm_fadvise64_64"); + SC_ALLOW ("fadvise64"); + SC_ALLOW ("fadvise64_64"); + if (permissive) + SC_ALLOW ("ioctl"); + else { + SC_ALLOW_ARG_1 ("ioctl", SCMP_A1 (SCMP_CMP_EQ, TCGETS)); + SC_ALLOW_ARG_1 ("ioctl", SCMP_A1 (SCMP_CMP_EQ, TIOCGWINSZ)); + } + SC_ALLOW ("madvise"); + SC_ALLOW ("mremap"); + SC_ALLOW ("sysinfo"); + SC_ALLOW ("uname"); + + /* Extra syscalls not in any of systemd's sets. */ + SC_ALLOW ("arm_fadvise64_64"); + SC_ALLOW ("arm_sync_file_range"); + + /* Allow killing processes and threads. This is unfortunate but + * unavoidable: groff uses kill to explicitly pass on SIGPIPE to its + * child processes, and we can't do any more sophisticated filtering + * in seccomp. + */ + SC_ALLOW ("kill"); + SC_ALLOW ("tgkill"); + + /* Allow some relatively harmless System V shared memory operations. + * These seem to be popular among the sort of program that wants to + * install itself in /etc/ld.so.preload or similar (e.g. antivirus + * programs and VPNs). + */ + SC_ALLOW_ARG_1 ("shmat", SCMP_A2 (SCMP_CMP_EQ, SHM_RDONLY)); + SC_ALLOW_ARG_1 ("shmctl", SCMP_A1 (SCMP_CMP_EQ, IPC_STAT)); + SC_ALLOW ("shmdt"); + SC_ALLOW ("shmget"); + + /* Some antivirus programs use an LD_PRELOAD wrapper that wants to + * talk to a private daemon using a Unix-domain socket. We really + * don't want to allow these syscalls in general, but if such a + * thing is in use we probably have no choice. + * + * Firebuild is a build accelerator that connects to its supervisor + * using a Unix-domain socket. + * + * snoopy is an execve monitoring tool that may log messages to + * /dev/log. + */ + if (search_ld_preload ("libesets_pac.so") || + search_ld_preload ("libfirebuild.so") || + search_ld_preload ("libscep_pac.so") || + search_ld_preload ("libsnoopy.so")) { + SC_ALLOW ("connect"); + SC_ALLOW ("recvmsg"); + SC_ALLOW ("sendmsg"); + SC_ALLOW ("sendto"); + SC_ALLOW ("setsockopt"); + SC_ALLOW_ARG_1 ("socket", SCMP_A0 (SCMP_CMP_EQ, AF_UNIX)); + } + /* ESET sends messages to a System V message queue. */ + if (search_ld_preload ("libesets_pac.so") || + search_ld_preload ("libscep_pac.so")) { + SC_ALLOW_ARG_1 ("msgget", SCMP_A1 (SCMP_CMP_EQ, 0)); + SC_ALLOW ("msgsnd"); + } + + return ctx; +} + +#undef SC_ALLOW_ARG_2 +#undef SC_ALLOW_ARG_1 +#undef SC_ALLOW + +#endif /* HAVE_LIBSECCOMP */ + +/* Create a sandbox for processing untrusted data. + * + * This only sets up data structures; the caller must call sandbox_load to + * actually enter the sandbox. + */ +man_sandbox *sandbox_init (void) +{ + man_sandbox *sandbox = XZALLOC (man_sandbox); + +#ifdef HAVE_LIBSECCOMP + sandbox->ctx = make_seccomp_filter (false); + sandbox->permissive_ctx = make_seccomp_filter (true); +#else /* !HAVE_LIBSECCOMP */ + sandbox->dummy = 0; +#endif /* HAVE_LIBSECCOMP */ + + return sandbox; +} + +#ifdef HAVE_LIBSECCOMP +static void _sandbox_load (man_sandbox *sandbox, bool permissive) { + if (can_load_seccomp ()) { + scmp_filter_ctx ctx; + + if (permissive) + ctx = sandbox->permissive_ctx; + else + ctx = sandbox->ctx; + if (!ctx) + return; + debug ("loading seccomp filter (permissive: %d)\n", + (int) permissive); + if (seccomp_load (ctx) < 0) { + if (errno == EINVAL || errno == EFAULT) { + /* The kernel doesn't give us particularly + * fine-grained errors. EINVAL could in + * theory be an invalid BPF program, but + * it's much more likely that the running + * kernel doesn't support seccomp filtering. + * EFAULT normally means a programming + * error, but it could also be returned here + * by some versions of qemu-user + * (https://bugs.launchpad.net/bugs/1726394). + */ + gripe_seccomp_filter_unavailable (); + /* Don't try this again. */ + seccomp_filter_unavailable = true; + } else + fatal (errno, "can't load seccomp filter"); + } + } +} +#else /* !HAVE_LIBSECCOMP */ +static void _sandbox_load (man_sandbox *sandbox MAYBE_UNUSED, + bool permissive MAYBE_UNUSED) +{ +} +#endif /* HAVE_LIBSECCOMP */ + +/* Enter a sandbox for processing untrusted data. */ +void sandbox_load (void *data) +{ + man_sandbox *sandbox = data; + + _sandbox_load (sandbox, false); +} + +/* Enter a sandbox for processing untrusted data, allowing limited file + * creation. + */ +void sandbox_load_permissive (void *data) +{ + man_sandbox *sandbox = data; + + _sandbox_load (sandbox, true); +} + +/* Free a sandbox for processing untrusted data. */ +void sandbox_free (void *data) { + man_sandbox *sandbox = data; + +#ifdef HAVE_LIBSECCOMP + if (sandbox->ctx) + seccomp_release (sandbox->ctx); + if (sandbox->permissive_ctx) + seccomp_release (sandbox->permissive_ctx); +#endif /* HAVE_LIBSECCOMP */ + + free (sandbox); +} diff --git a/lib/sandbox.h b/lib/sandbox.h new file mode 100644 index 0000000..cb482ec --- /dev/null +++ b/lib/sandbox.h @@ -0,0 +1,38 @@ +/* + * sandbox.h: Interface to process sandboxing + * + * Copyright (C) 2017 Colin Watson. + * + * This file is part of man-db. + * + * man-db is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * man-db 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 man-db; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef MAN_SANDBOX_H +#define MAN_SANDBOX_H + +struct man_sandbox; +typedef struct man_sandbox man_sandbox; + +extern man_sandbox *sandbox_init (void); + +/* These functions take a man_sandbox * argument, but have more generic + * types suitable for use with pipecmd_pre_exec. + */ +extern void sandbox_load (void *data); +extern void sandbox_load_permissive (void *data); +extern void sandbox_free (void *data); + +#endif /* MAN_SANDBOX_H */ diff --git a/lib/security.c b/lib/security.c new file mode 100644 index 0000000..92cccc3 --- /dev/null +++ b/lib/security.c @@ -0,0 +1,177 @@ +/* + * security.c: Routines to aid secure uid operations + * + * Copyright (C) 1994, 1995 Graeme W. Wilford. (Wilf.) + * Copyright (C) 2001, 2003, 2004, 2007, 2010, 2011 Colin Watson. + * + * This file is part of man-db. + * + * man-db is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * man-db 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 man-db; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + * Mon Aug 8 20:35:30 BST 1994 Wilf. (G.Wilford@ee.surrey.ac.uk) + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif /* HAVE_CONFIG_H */ + +#include <stdbool.h> +#include <string.h> +#include <stdlib.h> +#include <stdio.h> +#include <assert.h> +#include <errno.h> +#include <sys/types.h> + +#include "attribute.h" +#include "error.h" +#include "gettext.h" +#define _(String) gettext (String) + +#include "manconfig.h" + +#include "cleanup.h" +#include "debug.h" +#include "fatal.h" +#include "security.h" + +#ifdef MAN_OWNER + + /* + * This is the name of the user that the preformatted man pages belong to. + * If you are running man as a setuid program, you should make sure + * that all of the cat pages and the directories that + * they live in are writeable by this user. + */ + +# include <pwd.h> +# include <unistd.h> + +# include "idpriv.h" + +uid_t ruid; /* initial real user id */ +uid_t euid; /* initial effective user id */ +uid_t uid; /* current euid */ +gid_t rgid; /* initial real group id */ +gid_t egid; /* initial effective group id */ +gid_t gid; /* current egid */ + +static struct passwd *man_owner; + +/* Keep a count of how many times we've dropped privileges, and only regain + * them if regain_effective_privs() is called an equal number of times. + */ +static int priv_drop_count = 0; + +static void gripe_set_euid (void) +{ + fatal (errno, _("can't set effective uid")); +} + +#endif /* MAN_OWNER */ + +void init_security (void) +{ +#ifdef MAN_OWNER + ruid = getuid (); + uid = euid = geteuid (); + debug ("ruid=%d, euid=%d\n", (int) ruid, (int) euid); + rgid = getgid (); + gid = egid = getegid (); + debug ("rgid=%d, egid=%d\n", (int) rgid, (int) egid); + priv_drop_count = 0; + drop_effective_privs (); +#endif /* MAN_OWNER */ +} + +bool ATTRIBUTE_PURE running_setuid (void) +{ +#ifdef MAN_OWNER + return ruid != euid; +#else /* !MAN_OWNER */ + return false; +#endif +} + +#ifdef MAN_OWNER +/* Return a pointer to the password entry structure for MAN_OWNER. This + * structure will be statically stored. + */ +struct passwd *get_man_owner (void) +{ + if (man_owner) + return man_owner; + + man_owner = getpwnam (MAN_OWNER); + if (!man_owner) + error (FAIL, 0, _("the setuid man user \"%s\" does not exist"), + MAN_OWNER); + assert (man_owner); + return man_owner; +} +#endif /* MAN_OWNER */ + +/* + * function to gain user privs by either (a) dropping effective privs + * completely (saved ids) or (b) reversing euid w/ uid. + * Ignore if superuser. + */ +void drop_effective_privs (void) +{ +#ifdef MAN_OWNER + if (uid != ruid) { + debug ("drop_effective_privs()\n"); + if (idpriv_temp_drop ()) + gripe_set_euid (); + uid = ruid; + gid = rgid; + } + + priv_drop_count++; +#endif /* MAN_OWNER */ +} + +/* + * function to (re)gain setuid privs by (a) setting euid from suid or (b) + * (re)reversing uid w/ euid. Ignore if superuser. + */ +void regain_effective_privs (void) +{ +#ifdef MAN_OWNER + if (priv_drop_count) { + priv_drop_count--; + if (priv_drop_count) + return; + } + + if (uid != euid) { + debug ("regain_effective_privs()\n"); + if (idpriv_temp_restore ()) + gripe_set_euid (); + + uid = euid; + gid = egid; + } +#endif /* MAN_OWNER */ +} + +/* Pipeline command pre-exec hook to permanently drop privileges. */ +void drop_privs (void *data MAYBE_UNUSED) +{ +#ifdef MAN_OWNER + if (idpriv_drop ()) + gripe_set_euid (); +#endif /* MAN_OWNER */ +} diff --git a/lib/security.h b/lib/security.h new file mode 100644 index 0000000..3edf50b --- /dev/null +++ b/lib/security.h @@ -0,0 +1,38 @@ +/* + * security.h: Interface to secure uid operations + * + * Copyright (C) 1990, 1991 John W. Eaton. + * Copyright (C) 1994, 1995 Graeme W. Wilford. (Wilf.) + * Copyright (C) 2001, 2002, 2004, 2008, 2010, 2011 Colin Watson. + * + * This file is part of man-db. + * + * man-db is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * man-db 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 man-db; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include <stdbool.h> +#ifdef MAN_OWNER +# include <pwd.h> +#endif /* MAN_OWNER */ + +/* security.c */ +extern void drop_effective_privs (void); +extern void regain_effective_privs (void); +extern void drop_privs (void *data); +extern void init_security (void); +extern bool running_setuid (void); +#ifdef MAN_OWNER +extern struct passwd *get_man_owner (void); +#endif /* MAN_OWNER */ diff --git a/lib/tempfile.c b/lib/tempfile.c new file mode 100644 index 0000000..5d8847c --- /dev/null +++ b/lib/tempfile.c @@ -0,0 +1,94 @@ +/* tempfile.c: handle temporary directory creation (formerly also temporary + * files but this is no longer used). + * + * Copyright (C) 2001, 2003, 2007, 2009, 2011 Colin Watson. + * + * This file is part of man-db. + * + * man-db is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * man-db 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 man-db; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif /* HAVE_CONFIG_H */ + +#include <assert.h> +#include <stdbool.h> +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> + +#include "attribute.h" +#include "xvasprintf.h" + +#include "manconfig.h" + +#include "tempfile.h" + +static bool ATTRIBUTE_PURE running_setid (void) +{ +#ifdef HAVE_GETUID + return getuid () != geteuid () || getgid () != getegid (); +#else /* !HAVE_GETUID */ + return false; +#endif /* HAVE_GETUID */ +} + +static const char *path_search (void) +{ + const char *dir = NULL; + + if (running_setid ()) { + dir = getenv ("TMPDIR"); + if (!dir || !CAN_ACCESS (dir, W_OK)) + dir = NULL; + if (!dir) { + dir = getenv ("TMP"); + if (!dir || !CAN_ACCESS (dir, W_OK)) + dir = NULL; + } + } +#ifdef P_tmpdir + if (!dir) { + dir = P_tmpdir; + if (!dir || !CAN_ACCESS (dir, W_OK)) + dir = NULL; + } +#endif + if (!dir) { + dir = "/tmp"; + if (!CAN_ACCESS (dir, W_OK)) + dir = NULL; + } + + return dir; +} + +/* Get a sane temporary directory, looking in $TMPDIR, P_tmpdir, and finally + * /tmp. + */ +char *create_tempdir (const char *template) +{ + const char *dir = path_search (); + char *created_dirname; + + if (!dir) + return NULL; + created_dirname = xasprintf ("%s/%sXXXXXX", dir, template); + assert (created_dirname); + if (!mkdtemp (created_dirname)) + return NULL; + return created_dirname; +} diff --git a/lib/tempfile.h b/lib/tempfile.h new file mode 100644 index 0000000..1a4a64c --- /dev/null +++ b/lib/tempfile.h @@ -0,0 +1,24 @@ +/* tempfile.h: interface to temporary directory creation + * + * Copyright (C) 2001-2022 Colin Watson. + * + * This file is part of man-db. + * + * man-db is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * man-db 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 man-db; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "attribute.h" + +NODISCARD extern char *create_tempdir (const char *template); diff --git a/lib/util.c b/lib/util.c new file mode 100644 index 0000000..2f97182 --- /dev/null +++ b/lib/util.c @@ -0,0 +1,274 @@ +/* + * util.c + * + * Copyright (C) 1990, 1991 John W. Eaton. + * Copyright (C) 1994, 1995 Graeme W. Wilford. (Wilf.) + * Copyright (C) 2001, 2002, 2004, 2007, 2008, 2010 Colin Watson. + * + * This file is part of man-db. + * + * man-db is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * man-db 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 man-db; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + * John W. Eaton + * jwe@che.utexas.edu + * Department of Chemical Engineering + * The University of Texas at Austin + * Austin, Texas 78712 + * + * Wed May 4 15:44:47 BST 1994 Wilf. (G.Wilford@ee.surrey.ac.uk): slight + * changes to all routines, mainly cosmetic. + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif /* HAVE_CONFIG_H */ + +#include <assert.h> +#include <stdbool.h> +#include <string.h> +#include <stdlib.h> +#include <stdio.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <dirent.h> +#include <unistd.h> +#include <locale.h> + +#include "attribute.h" +#include "stat-time.h" +#include "timespec.h" +#include "xalloc.h" +#include "xstrndup.h" +#include "xvasprintf.h" + +#include "gettext.h" + +#include "manconfig.h" + +#include "debug.h" +#include "error.h" +#include "util.h" + +/* + * Does file a have a different timestamp to file b? + * + * case: + * + * a is man_page, b is cat_page + * + * a and b have different times returns 1/3 (ret & 1) == 1 + * a and b have same times returns 0/2 (!(ret & 1)) == 1 + * a is zero in length returns + 2 (for Wilf. and his stray cats) + * b is zero in length returns + 4 + * stat on a fails returns -1 + * stat on b fails returns -2 + * stat on a and b fails returns -3 + */ +int is_changed (const char *fa, const char *fb) +{ + struct stat fa_sb; + struct stat fb_sb; + int fa_stat; + int fb_stat; + int status = 0; + + debug ("is_changed: a=%s, b=%s", fa, fb); + + fa_stat = stat (fa, &fa_sb); + if (fa_stat != 0) + status = 1; + + fb_stat = stat (fb, &fb_sb); + if (fb_stat != 0) + status |= 2; + + if (status != 0) { + debug (" (%d)\n", -status); + return -status; + } + + if (fa_sb.st_size == 0) + status |= 2; + + if (fb_sb.st_size == 0) + status |= 4; + + status |= (timespec_cmp (get_stat_mtime (&fa_sb), + get_stat_mtime (&fb_sb)) != 0); + + debug (" (%d)\n", status); + return status; +} + +/* + * Is path a directory? + */ +int is_directory (const char *path) +{ + struct stat sb; + int status; + + status = stat (path, &sb); + + if (status != 0) + return status; + + return ((sb.st_mode & S_IFDIR) != 0); +} + +/* Escape dangerous metacharacters before dumping into a shell command. */ +char *escape_shell (const char *unesc) +{ + char *esc, *escp; + const char *unescp; + + if (!unesc) + return NULL; + + escp = esc = xmalloc (strlen (unesc) * 2 + 1); + for (unescp = unesc; *unescp; unescp++) + if ((*unescp >= '0' && *unescp <= '9') || + (*unescp >= 'A' && *unescp <= 'Z') || + (*unescp >= 'a' && *unescp <= 'z') || + strchr (",-./:@_", *unescp)) + *escp++ = *unescp; + else { + *escp++ = '\\'; + *escp++ = *unescp; + } + *escp = 0; + return esc; +} + +/* Remove a directory and all files in it. Only recurse beyond that if + * RECURSE is set. + */ +int remove_directory (const char *directory, bool recurse) +{ + DIR *handle = opendir (directory); + struct dirent *entry; + + if (!handle) + return -1; + while ((entry = readdir (handle)) != NULL) { + struct stat st; + char *path; + + if (STREQ (entry->d_name, ".") || STREQ (entry->d_name, "..")) + continue; + path = xasprintf ("%s/%s", directory, entry->d_name); + assert (path); + if (stat (path, &st) == -1) { + free (path); + closedir (handle); + return -1; + } + if (recurse && S_ISDIR (st.st_mode)) { + if (remove_directory (path, recurse) == -1) { + free (path); + closedir (handle); + return -1; + } + } else if (S_ISREG (st.st_mode)) { + if (unlink (path) == -1) { + free (path); + closedir (handle); + return -1; + } + } + free (path); + } + closedir (handle); + + if (rmdir (directory) == -1) + return -1; + return 0; +} + +/* Returns an allocated copy of s, with leading and trailing spaces + * removed. + */ +char * ATTRIBUTE_MALLOC trim_spaces (const char *s) +{ + int length; + while (*s == ' ') + ++s; + length = strlen (s); + while (length && s[length - 1] == ' ') + --length; + return xstrndup (s, length); +} + +char *lang_dir (const char *filename) +{ + char *ld; /* the lang dir: point to static data */ + const char *fm; /* the first "/man/" dir */ + const char *sm; /* the second "/man?/" dir */ + + ld = xstrdup (""); + if (!filename) + return ld; + + /* Check whether filename is in a man page hierarchy. */ + if (STRNEQ (filename, "man/", 4)) + fm = filename; + else { + fm = strstr (filename, "/man/"); + if (fm) + ++fm; + } + if (!fm) + return ld; + sm = strstr (fm + 2, "/man"); + if (!sm) + return ld; + if (sm[5] != '/') + return ld; + if (!strchr ("123456789lno", sm[4])) + return ld; + + /* If there's no lang dir element, it's an English man page. */ + if (sm == fm + 3) { + free (ld); + return xstrdup ("C"); + } + + /* found a lang dir */ + fm += 4; + sm = strchr (fm, '/'); + if (!sm) + return ld; + free (ld); + ld = xstrndup (fm, sm - fm); + debug ("found lang dir element %s\n", ld); + return ld; +} + +void init_locale (void) +{ + const char *locale = setlocale (LC_ALL, ""); + if (!locale && + !getenv ("MAN_NO_LOCALE_WARNING") && + !getenv ("DPKG_RUNNING_VERSION")) + /* Obviously can't translate this. */ + error (0, 0, "can't set the locale; make sure $LC_* and $LANG " + "are correct"); + setenv ("MAN_NO_LOCALE_WARNING", "1", 1); +#ifdef ENABLE_NLS + bindtextdomain (PACKAGE, LOCALEDIR); + bindtextdomain (PACKAGE "-gnulib", LOCALEDIR); + textdomain (PACKAGE); +#endif /* ENABLE_NLS */ +} diff --git a/lib/util.h b/lib/util.h new file mode 100644 index 0000000..aec8d17 --- /dev/null +++ b/lib/util.h @@ -0,0 +1,33 @@ +/* + * util.h + * + * Copyright (C) 1990, 1991 John W. Eaton. + * Copyright (C) 1994, 1995 Graeme W. Wilford. (Wilf.) + * Copyright (C) 2001-2022 Colin Watson. + * + * This file is part of man-db. + * + * man-db is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * man-db 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 man-db; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include <stdbool.h> + +extern int is_changed (const char *fa, const char *fb); +extern int is_directory (const char *path); +extern char *escape_shell (const char *unesc); +extern int remove_directory (const char *directory, bool recurse); +extern char *trim_spaces (const char *s); +extern char *lang_dir (const char *filename); +extern void init_locale (void); diff --git a/lib/wordfnmatch.c b/lib/wordfnmatch.c new file mode 100644 index 0000000..b073a88 --- /dev/null +++ b/lib/wordfnmatch.c @@ -0,0 +1,66 @@ +/* + * wordfnmatch.c: fnmatch on word boundaries + * + * Copyright (C) 2001, 2003, 2008 Colin Watson. + * + * This file is part of man-db. + * + * man-db is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * man-db 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 man-db; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif /* HAVE_CONFIG_H */ + +#include <stdbool.h> +#include <stdlib.h> +#include <ctype.h> + +#include "fnmatch.h" +#include "xalloc.h" + +#include "manconfig.h" + +#include "wordfnmatch.h" + +/* TODO: How on earth do we allow multiple-word matches without + * reimplementing fnmatch()? + */ +bool word_fnmatch (const char *pattern, const char *string) +{ + char *dupstring = xstrdup (string); + const char *begin = dupstring; + char *p; + + for (p = dupstring; *p; p++) { + if (CTYPE (isalpha, *p) || *p == '_') + continue; + + /* Check for multiple non-word characters in a row. */ + if (p <= begin + 1) + begin++; + else { + *p = '\0'; + if (fnmatch (pattern, begin, FNM_CASEFOLD) == 0) { + free (dupstring); + return true; + } + begin = p + 1; + } + } + + free (dupstring); + return false; +} diff --git a/lib/wordfnmatch.h b/lib/wordfnmatch.h new file mode 100644 index 0000000..82e7cf7 --- /dev/null +++ b/lib/wordfnmatch.h @@ -0,0 +1,25 @@ +/* + * wordfnmatch.h: interface to fnmatch on word boundaries + * + * Copyright (C) 2001, 2003, 2008 Colin Watson. + * + * This file is part of man-db. + * + * man-db is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * man-db 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 man-db; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include <stdbool.h> + +bool word_fnmatch (const char *lowpattern, const char *string); diff --git a/lib/xregcomp.c b/lib/xregcomp.c new file mode 100644 index 0000000..d8e1f18 --- /dev/null +++ b/lib/xregcomp.c @@ -0,0 +1,52 @@ +/* + * xregcomp.c: regcomp with error checking + * + * Copyright (C) 2008 Colin Watson. + * + * This file is part of man-db. + * + * man-db is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * man-db 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 man-db; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif /* HAVE_CONFIG_H */ + +#include <stddef.h> + +#include "regex.h" + +#include "gettext.h" +#include <locale.h> +#define _(String) gettext (String) + +#include "manconfig.h" + +#include "fatal.h" +#include "xalloc.h" +#include "xregcomp.h" + +void xregcomp (regex_t *preg, const char *regex, int cflags) +{ + int err = regcomp (preg, regex, cflags); + if (err) { + size_t errstrsize; + char *errstr; + errstrsize = regerror (err, preg, NULL, 0); + errstr = xmalloc (errstrsize); + regerror (err, preg, errstr, errstrsize); + fatal (0, _("fatal: regex `%s': %s"), regex, errstr); + } +} diff --git a/lib/xregcomp.h b/lib/xregcomp.h new file mode 100644 index 0000000..ca34b44 --- /dev/null +++ b/lib/xregcomp.h @@ -0,0 +1,25 @@ +/* + * xregcomp.h: interface to regcomp with error checking + * + * Copyright (C) 2008 Colin Watson. + * + * This file is part of man-db. + * + * man-db is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * man-db 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 man-db; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "regex.h" + +void xregcomp (regex_t *preg, const char *regex, int cflags); |