summaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/Makefile.am78
-rw-r--r--lib/Makefile.in2272
-rw-r--r--lib/README23
-rw-r--r--lib/appendstr.c59
-rw-r--r--lib/appendstr.h24
-rw-r--r--lib/cleanup.c279
-rw-r--r--lib/cleanup.h35
-rw-r--r--lib/compression.c195
-rw-r--r--lib/compression.h42
-rw-r--r--lib/debug.c78
-rw-r--r--lib/debug.h32
-rw-r--r--lib/encodings.c780
-rw-r--r--lib/encodings.h38
-rw-r--r--lib/fatal.c48
-rw-r--r--lib/fatal.h26
-rw-r--r--lib/filenames.c165
-rw-r--r--lib/filenames.h56
-rw-r--r--lib/glcontainers.c78
-rw-r--r--lib/glcontainers.h68
-rw-r--r--lib/linelength.c110
-rw-r--r--lib/linelength.h23
-rw-r--r--lib/mp.h483
-rw-r--r--lib/orderfiles.c180
-rw-r--r--lib/orderfiles.h25
-rw-r--r--lib/pathsearch.c146
-rw-r--r--lib/pathsearch.h36
-rw-r--r--lib/sandbox.c688
-rw-r--r--lib/sandbox.h38
-rw-r--r--lib/security.c177
-rw-r--r--lib/security.h38
-rw-r--r--lib/tempfile.c94
-rw-r--r--lib/tempfile.h24
-rw-r--r--lib/util.c274
-rw-r--r--lib/util.h33
-rw-r--r--lib/wordfnmatch.c66
-rw-r--r--lib/wordfnmatch.h25
-rw-r--r--lib/xregcomp.c52
-rw-r--r--lib/xregcomp.h25
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);