summaryrefslogtreecommitdiff
path: root/find
diff options
context:
space:
mode:
authorLorry Tar Creator <lorry-tar-importer@lorry>2015-12-28 21:37:38 +0000
committerLorry Tar Creator <lorry-tar-importer@lorry>2015-12-28 21:37:38 +0000
commitd7fdaf4d3a9795a294e93cad6f7d8238ba3754a6 (patch)
tree9bff05ea75330b7d8e2ade183cdcd1e4282f27d9 /find
downloadfindutils-tarball-master.tar.gz
Diffstat (limited to 'find')
-rw-r--r--find/Makefile.am39
-rw-r--r--find/Makefile.in2193
-rw-r--r--find/defs.h677
-rw-r--r--find/exec.c390
-rw-r--r--find/find.12220
-rw-r--r--find/finddata.c33
-rw-r--r--find/fstype.c326
-rw-r--r--find/ftsfind.c757
-rw-r--r--find/oldfind.c1581
-rw-r--r--find/parser.c3424
-rw-r--r--find/pred.c1388
-rw-r--r--find/print.c1327
-rw-r--r--find/print.h32
-rw-r--r--find/sharefile.c203
-rw-r--r--find/sharefile.h31
-rw-r--r--find/testsuite/Makefile.am283
-rw-r--r--find/testsuite/Makefile.in2433
-rw-r--r--find/testsuite/binary_locations.sh34
-rw-r--r--find/testsuite/checklists.py107
-rw-r--r--find/testsuite/config/unix.exp306
-rw-r--r--find/testsuite/find.gnu/access.exp14
-rw-r--r--find/testsuite/find.gnu/access.xo11
-rw-r--r--find/testsuite/find.gnu/comma.exp1
-rw-r--r--find/testsuite/find.gnu/comma.xo1
-rw-r--r--find/testsuite/find.gnu/delete.exp7
-rw-r--r--find/testsuite/find.gnu/delete.xo4
-rw-r--r--find/testsuite/find.gnu/deletedir.exp9
-rw-r--r--find/testsuite/find.gnu/deletedir.xo1
-rw-r--r--find/testsuite/find.gnu/deletefile.exp9
-rw-r--r--find/testsuite/find.gnu/deletefile.xo1
-rw-r--r--find/testsuite/find.gnu/depth-d.exp8
-rw-r--r--find/testsuite/find.gnu/depth-d.xo1
-rw-r--r--find/testsuite/find.gnu/depth.exp8
-rw-r--r--find/testsuite/find.gnu/depth.xo1
-rw-r--r--find/testsuite/find.gnu/empty.exp7
-rw-r--r--find/testsuite/find.gnu/empty.xo1
-rw-r--r--find/testsuite/find.gnu/exec-many-rtn-failure.exp4
-rw-r--r--find/testsuite/find.gnu/exec-many-rtn-failure.xo1
-rw-r--r--find/testsuite/find.gnu/exec-many-rtn-success.exp4
-rw-r--r--find/testsuite/find.gnu/exec-many-rtn-success.xo1
-rw-r--r--find/testsuite/find.gnu/exec-one-rtn-fail.exp4
-rw-r--r--find/testsuite/find.gnu/exec-one-rtn-fail.xo1
-rw-r--r--find/testsuite/find.gnu/exec-one-rtn-success.exp3
-rw-r--r--find/testsuite/find.gnu/exec-one-rtn-success.xo1
-rw-r--r--find/testsuite/find.gnu/execdir-hier.exp8
-rw-r--r--find/testsuite/find.gnu/execdir-hier.xo2
-rw-r--r--find/testsuite/find.gnu/execdir-in-unreadable.exp11
-rw-r--r--find/testsuite/find.gnu/execdir-multiple.exp58
-rw-r--r--find/testsuite/find.gnu/execdir-multiple.xo24
-rw-r--r--find/testsuite/find.gnu/execdir-one.exp7
-rw-r--r--find/testsuite/find.gnu/execdir-one.xo1
-rw-r--r--find/testsuite/find.gnu/execdir-pwd.exp20
-rw-r--r--find/testsuite/find.gnu/execdir-pwd1.exp20
-rw-r--r--find/testsuite/find.gnu/execdir-root-only.exp21
-rw-r--r--find/testsuite/find.gnu/execdir-root-only.xo1
-rw-r--r--find/testsuite/find.gnu/false.exp5
-rw-r--r--find/testsuite/find.gnu/false.xo3
-rw-r--r--find/testsuite/find.gnu/follow-arg-parent-symlink.exp6
-rw-r--r--find/testsuite/find.gnu/follow-arg-parent-symlink.xo1
-rw-r--r--find/testsuite/find.gnu/follow-basic.exp10
-rw-r--r--find/testsuite/find.gnu/follow-basic.xo5
-rw-r--r--find/testsuite/find.gnu/fprint-unwritable.exp9
-rw-r--r--find/testsuite/find.gnu/fprint0_stdout.exp5
-rw-r--r--find/testsuite/find.gnu/fprint0_stdout.xobin0 -> 5 bytes
-rw-r--r--find/testsuite/find.gnu/fprintf-samefile.exp26
-rw-r--r--find/testsuite/find.gnu/gnu-or.exp5
-rw-r--r--find/testsuite/find.gnu/gnu-or.xo6
-rw-r--r--find/testsuite/find.gnu/gnuand.exp5
-rw-r--r--find/testsuite/find.gnu/gnuand.xo1
-rw-r--r--find/testsuite/find.gnu/gnunot.exp5
-rw-r--r--find/testsuite/find.gnu/gnunot.xo2
-rw-r--r--find/testsuite/find.gnu/ilname.exp7
-rw-r--r--find/testsuite/find.gnu/ilname.xo1
-rw-r--r--find/testsuite/find.gnu/iname.exp5
-rw-r--r--find/testsuite/find.gnu/iname.xo1
-rw-r--r--find/testsuite/find.gnu/inum.exp7
-rw-r--r--find/testsuite/find.gnu/inum.xo1
-rw-r--r--find/testsuite/find.gnu/ipath.exp5
-rw-r--r--find/testsuite/find.gnu/ipath.xo1
-rw-r--r--find/testsuite/find.gnu/iregex1.exp5
-rw-r--r--find/testsuite/find.gnu/iregex1.xo4
-rw-r--r--find/testsuite/find.gnu/iwholename.exp5
-rw-r--r--find/testsuite/find.gnu/iwholename.xo1
-rw-r--r--find/testsuite/find.gnu/lname.exp7
-rw-r--r--find/testsuite/find.gnu/lname.xo1
-rw-r--r--find/testsuite/find.gnu/mindepth-arg.exp9
-rw-r--r--find/testsuite/find.gnu/mindepth-arg.xo1
-rw-r--r--find/testsuite/find.gnu/mindepth-badarg.exp12
-rw-r--r--find/testsuite/find.gnu/name-opt.exp8
-rw-r--r--find/testsuite/find.gnu/name-opt.xo0
-rw-r--r--find/testsuite/find.gnu/name-period.exp10
-rw-r--r--find/testsuite/find.gnu/name-period.xo2
-rw-r--r--find/testsuite/find.gnu/name-slash.exp2
-rw-r--r--find/testsuite/find.gnu/name-slash.xo2
-rw-r--r--find/testsuite/find.gnu/no-fdleak-test.exp13
-rw-r--r--find/testsuite/find.gnu/no-fdleak-test.xo1
-rw-r--r--find/testsuite/find.gnu/path.exp5
-rw-r--r--find/testsuite/find.gnu/path.xo1
-rw-r--r--find/testsuite/find.gnu/perm-slash.exp19
-rw-r--r--find/testsuite/find.gnu/perm-slash.xo4
-rw-r--r--find/testsuite/find.gnu/perm.exp7
-rw-r--r--find/testsuite/find.gnu/perm.xo1
-rw-r--r--find/testsuite/find.gnu/perm000.exp7
-rw-r--r--find/testsuite/find.gnu/perm000.xo3
-rw-r--r--find/testsuite/find.gnu/posix-dflt.exp10
-rw-r--r--find/testsuite/find.gnu/posix-dflt.xo5
-rw-r--r--find/testsuite/find.gnu/posix-h.exp13
-rw-r--r--find/testsuite/find.gnu/posix-h.xo5
-rw-r--r--find/testsuite/find.gnu/posix-l.exp10
-rw-r--r--find/testsuite/find.gnu/posix-l.xo5
-rw-r--r--find/testsuite/find.gnu/posix-perminvalid.exp16
-rw-r--r--find/testsuite/find.gnu/print0.exp5
-rw-r--r--find/testsuite/find.gnu/print0.xobin0 -> 4 bytes
-rw-r--r--find/testsuite/find.gnu/print_stdout.exp5
-rw-r--r--find/testsuite/find.gnu/print_stdout.xo1
-rw-r--r--find/testsuite/find.gnu/printf-h.exp5
-rw-r--r--find/testsuite/find.gnu/printf-h.xo1
-rw-r--r--find/testsuite/find.gnu/printf-nonlocal-symlink.exp7
-rw-r--r--find/testsuite/find.gnu/printf-nonlocal-symlink.xo1
-rw-r--r--find/testsuite/find.gnu/printf-reserved.exp3
-rw-r--r--find/testsuite/find.gnu/printf-slash.exp1
-rw-r--r--find/testsuite/find.gnu/printf-slash.xo2
-rw-r--r--find/testsuite/find.gnu/printf-symlink.exp6
-rw-r--r--find/testsuite/find.gnu/printf-symlink.xo2
-rw-r--r--find/testsuite/find.gnu/printf.exp6
-rw-r--r--find/testsuite/find.gnu/printf.xo19
-rw-r--r--find/testsuite/find.gnu/printfHdfl.exp2
-rw-r--r--find/testsuite/find.gnu/printfHdfl.xo1
-rw-r--r--find/testsuite/find.gnu/prune-default-print.exp5
-rw-r--r--find/testsuite/find.gnu/prune-default-print.xo1
-rw-r--r--find/testsuite/find.gnu/quit.exp5
-rw-r--r--find/testsuite/find.gnu/quit.xo2
-rw-r--r--find/testsuite/find.gnu/regex1.exp5
-rw-r--r--find/testsuite/find.gnu/regex1.xo4
-rw-r--r--find/testsuite/find.gnu/regex2.exp5
-rw-r--r--find/testsuite/find.gnu/regex2.xo4
-rw-r--r--find/testsuite/find.gnu/samefile-copy.exp8
-rw-r--r--find/testsuite/find.gnu/samefile-copy.xo0
-rw-r--r--find/testsuite/find.gnu/samefile-link.exp9
-rw-r--r--find/testsuite/find.gnu/samefile-link.xo1
-rw-r--r--find/testsuite/find.gnu/samefile-missing.exp2
-rw-r--r--find/testsuite/find.gnu/samefile-p-brokenlink.exp11
-rw-r--r--find/testsuite/find.gnu/samefile-p-brokenlink.xo2
-rw-r--r--find/testsuite/find.gnu/samefile-same.exp6
-rw-r--r--find/testsuite/find.gnu/samefile-same.xo2
-rw-r--r--find/testsuite/find.gnu/samefile-symlink.exp10
-rw-r--r--find/testsuite/find.gnu/samefile-symlink.xo2
-rw-r--r--find/testsuite/find.gnu/sv-bug-12230.exp14
-rw-r--r--find/testsuite/find.gnu/sv-bug-17477.exp2
-rw-r--r--find/testsuite/find.gnu/sv-bug-17490.exp4
-rw-r--r--find/testsuite/find.gnu/sv-bug-17782.exp15
-rw-r--r--find/testsuite/find.gnu/sv-bug-17782.xo1
-rw-r--r--find/testsuite/find.gnu/sv-bug-18222.exp8
-rw-r--r--find/testsuite/find.gnu/sv-bug-18222.xo2
-rw-r--r--find/testsuite/find.gnu/sv-bug-24169.exp47
-rw-r--r--find/testsuite/find.gnu/sv-bug-27563-execdir.exp6
-rw-r--r--find/testsuite/find.gnu/sv-bug-27563-execdir.xo1
-rw-r--r--find/testsuite/find.gnu/true.exp5
-rw-r--r--find/testsuite/find.gnu/true.xo6
-rw-r--r--find/testsuite/find.gnu/used-invarg.exp2
-rw-r--r--find/testsuite/find.gnu/used-missing.exp2
-rw-r--r--find/testsuite/find.gnu/user-invalid.exp4
-rw-r--r--find/testsuite/find.gnu/wholename.exp5
-rw-r--r--find/testsuite/find.gnu/wholename.xo1
-rw-r--r--find/testsuite/find.gnu/xtype-symlink.exp6
-rw-r--r--find/testsuite/find.gnu/xtype-symlink.xo1
-rw-r--r--find/testsuite/find.gnu/xtype.exp8
-rw-r--r--find/testsuite/find.gnu/xtype.xo5
-rw-r--r--find/testsuite/find.posix/and.exp5
-rw-r--r--find/testsuite/find.posix/and.xo1
-rw-r--r--find/testsuite/find.posix/bracket-depth.exp4
-rw-r--r--find/testsuite/find.posix/depth1.exp7
-rw-r--r--find/testsuite/find.posix/depth1.xo11
-rw-r--r--find/testsuite/find.posix/dotdotfiles.exp8
-rw-r--r--find/testsuite/find.posix/dotdotfiles.xo2
-rw-r--r--find/testsuite/find.posix/empty-parens.exp2
-rw-r--r--find/testsuite/find.posix/exec-nogaps.exp34
-rw-r--r--find/testsuite/find.posix/exec-nogaps.xo7200
-rw-r--r--find/testsuite/find.posix/exec-one.exp5
-rw-r--r--find/testsuite/find.posix/exec-one.xo1
-rw-r--r--find/testsuite/find.posix/files-not-expressions1.exp8
-rw-r--r--find/testsuite/find.posix/files-not-expressions1.xo1
-rw-r--r--find/testsuite/find.posix/files-not-expressions2.exp8
-rw-r--r--find/testsuite/find.posix/files-not-expressions2.xo1
-rw-r--r--find/testsuite/find.posix/files-not-expressions3.exp8
-rw-r--r--find/testsuite/find.posix/files-not-expressions3.xo1
-rw-r--r--find/testsuite/find.posix/group-empty.exp2
-rw-r--r--find/testsuite/find.posix/group-missing.exp5
-rw-r--r--find/testsuite/find.posix/grouping.exp5
-rw-r--r--find/testsuite/find.posix/grouping.xo1
-rw-r--r--find/testsuite/find.posix/links.exp25
-rw-r--r--find/testsuite/find.posix/links.xo3
-rw-r--r--find/testsuite/find.posix/mtime0.exp10
-rw-r--r--find/testsuite/find.posix/mtime0.xo1
-rw-r--r--find/testsuite/find.posix/name-missing.exp5
-rw-r--r--find/testsuite/find.posix/name.exp5
-rw-r--r--find/testsuite/find.posix/name.xo1
-rw-r--r--find/testsuite/find.posix/nameslash.exp7
-rw-r--r--find/testsuite/find.posix/nameslash.xo1
-rw-r--r--find/testsuite/find.posix/parent.exp7
-rw-r--r--find/testsuite/find.posix/parent.xo1
-rw-r--r--find/testsuite/find.posix/perm-X.exp12
-rw-r--r--find/testsuite/find.posix/perm-X.xo3
-rw-r--r--find/testsuite/find.posix/perm-vanilla.exp18
-rw-r--r--find/testsuite/find.posix/perm-vanilla.xo4
-rw-r--r--find/testsuite/find.posix/posixnot.exp5
-rw-r--r--find/testsuite/find.posix/posixnot.xo2
-rw-r--r--find/testsuite/find.posix/prune-result.exp7
-rw-r--r--find/testsuite/find.posix/prune-result.xo2
-rw-r--r--find/testsuite/find.posix/prune-stat.exp7
-rw-r--r--find/testsuite/find.posix/prune-stat.xo3
-rw-r--r--find/testsuite/find.posix/prune.exp5
-rw-r--r--find/testsuite/find.posix/prune.xo3
-rw-r--r--find/testsuite/find.posix/size-invalid.exp7
-rw-r--r--find/testsuite/find.posix/size-missing.exp5
-rw-r--r--find/testsuite/find.posix/sizes.exp15
-rw-r--r--find/testsuite/find.posix/sizes.xo10
-rw-r--r--find/testsuite/find.posix/sizetype.exp6
-rw-r--r--find/testsuite/find.posix/sizetype.xo1
-rw-r--r--find/testsuite/find.posix/sv-bug-11175.exp10
-rw-r--r--find/testsuite/find.posix/sv-bug-11175.xo1
-rw-r--r--find/testsuite/find.posix/sv-bug-12181.exp6
-rw-r--r--find/testsuite/find.posix/sv-bug-12181.xo1
-rw-r--r--find/testsuite/find.posix/sv-bug-15235.exp6
-rw-r--r--find/testsuite/find.posix/sv-bug-15235.xo8
-rw-r--r--find/testsuite/find.posix/sv-bug-19605.exp7
-rw-r--r--find/testsuite/find.posix/sv-bug-19613.exp14
-rw-r--r--find/testsuite/find.posix/sv-bug-19613.xo1
-rw-r--r--find/testsuite/find.posix/sv-bug-19617.exp7
-rw-r--r--find/testsuite/find.posix/sv-bug-25359.exp10
-rw-r--r--find/testsuite/find.posix/sv-bug-25359.xo1
-rw-r--r--find/testsuite/find.posix/sv-bug-27563-exec.exp6
-rw-r--r--find/testsuite/find.posix/sv-bug-27563-exec.xo1
-rw-r--r--find/testsuite/find.posix/sv-bug-30777.exp6
-rw-r--r--find/testsuite/find.posix/typearg.exp4
-rw-r--r--find/testsuite/find.posix/typesize.exp6
-rw-r--r--find/testsuite/find.posix/typesize.xo1
-rw-r--r--find/testsuite/find.posix/user-empty.exp2
-rw-r--r--find/testsuite/find.posix/user-missing.exp2
-rwxr-xr-xfind/testsuite/sv-34079.sh78
-rwxr-xr-xfind/testsuite/sv-34976-execdir-fd-leak.sh80
-rwxr-xr-xfind/testsuite/sv-bug-32043.sh48
-rwxr-xr-xfind/testsuite/test_escape_c.sh43
-rw-r--r--find/testsuite/test_escapechars.golden13
-rwxr-xr-xfind/testsuite/test_escapechars.sh59
-rwxr-xr-xfind/testsuite/test_inode.sh62
-rw-r--r--find/tree.c1747
-rw-r--r--find/util.c1173
248 files changed, 29576 insertions, 0 deletions
diff --git a/find/Makefile.am b/find/Makefile.am
new file mode 100644
index 0000000..3431787
--- /dev/null
+++ b/find/Makefile.am
@@ -0,0 +1,39 @@
+AUTOMAKE_OPTIONS = std-options
+AM_CFLAGS = $(WARN_CFLAGS)
+localedir = $(datadir)/locale
+
+noinst_LIBRARIES = libfindtools.a
+libfindtools_a_SOURCES = finddata.c fstype.c parser.c pred.c exec.c tree.c util.c sharefile.c print.c
+
+# We always build two versions of find, one with fts (called "find"),
+# one without (called "oldfind"). The oldfind binary is no longer
+# installed.
+bin_PROGRAMS = find
+check_PROGRAMS = oldfind
+find_SOURCES = ftsfind.c
+oldfind_SOURCES = oldfind.c
+man_MANS = find.1
+
+EXTRA_DIST = defs.h sharefile.h print.h $(man_MANS)
+AM_CPPFLAGS = -I../gl/lib -I$(top_srcdir)/lib -I$(top_srcdir)/gl/lib -I../intl -DLOCALEDIR=\"$(localedir)\"
+LDADD = ./libfindtools.a ../lib/libfind.a ../gl/lib/libgnulib.a $(LIBINTL) $(LIB_CLOCK_GETTIME) $(LIB_EACCESS) $(LIB_SELINUX) $(LIB_CLOSE) $(MODF_LIBM) $(FINDLIBS) $(GETHOSTNAME_LIB) $(LIB_EACCESS)
+# gnulib advises we link against <first> because we use <second>:
+# $(GETHOSTNAME_LIB) uname
+# $(LIB_CLOCK_GETTIME) (some indirect dependency)
+# $(LIB_EACCESS) faccessat
+# $(LIB_SELINUX) selinux-h
+# $(MODF_LIBM) modf
+
+SUBDIRS = . testsuite
+
+dist-hook: findutils-check-manpages
+
+# Clean coverage files generated by running binaries built with
+# gcc -fprofile-arcs -ftest-coverage
+coverage-clean:
+ $(RM) *.gcno *.gcda *.gcov *.lcov
+
+clean-local: coverage-clean
+
+findutils-check-manpages:
+ $(top_srcdir)/build-aux/man-lint.sh $(srcdir) $(man_MANS)
diff --git a/find/Makefile.in b/find/Makefile.in
new file mode 100644
index 0000000..aa7bbed
--- /dev/null
+++ b/find/Makefile.in
@@ -0,0 +1,2193 @@
+# Makefile.in generated by automake 1.14.1 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2013 Free Software Foundation, Inc.
+
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+
+VPATH = @srcdir@
+am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
+am__make_running_with_option = \
+ case $${target_option-} in \
+ ?) ;; \
+ *) echo "am__make_running_with_option: internal error: invalid" \
+ "target option '$${target_option-}' specified" >&2; \
+ exit 1;; \
+ esac; \
+ has_opt=no; \
+ sane_makeflags=$$MAKEFLAGS; \
+ if $(am__is_gnu_make); then \
+ sane_makeflags=$$MFLAGS; \
+ else \
+ case $$MAKEFLAGS in \
+ *\\[\ \ ]*) \
+ bs=\\; \
+ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \
+ esac; \
+ fi; \
+ skip_next=no; \
+ strip_trailopt () \
+ { \
+ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+ }; \
+ for flg in $$sane_makeflags; do \
+ test $$skip_next = yes && { skip_next=no; continue; }; \
+ case $$flg in \
+ *=*|--*) continue;; \
+ -*I) strip_trailopt 'I'; skip_next=yes;; \
+ -*I?*) strip_trailopt 'I';; \
+ -*O) strip_trailopt 'O'; skip_next=yes;; \
+ -*O?*) strip_trailopt 'O';; \
+ -*l) strip_trailopt 'l'; skip_next=yes;; \
+ -*l?*) strip_trailopt 'l';; \
+ -[dEDm]) skip_next=yes;; \
+ -[JT]) skip_next=yes;; \
+ esac; \
+ case $$flg in \
+ *$$target_option*) has_opt=yes; break;; \
+ esac; \
+ done; \
+ test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+bin_PROGRAMS = find$(EXEEXT)
+check_PROGRAMS = oldfind$(EXEEXT)
+subdir = find
+DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
+ $(top_srcdir)/build-aux/mkinstalldirs \
+ $(top_srcdir)/build-aux/depcomp
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/findlib.m4 \
+ $(top_srcdir)/m4/mkinstalldirs.m4 $(top_srcdir)/m4/noreturn.m4 \
+ $(top_srcdir)/m4/nullsort.m4 $(top_srcdir)/m4/withfts.m4 \
+ $(top_srcdir)/gl/m4/00gnulib.m4 \
+ $(top_srcdir)/gl/m4/absolute-header.m4 \
+ $(top_srcdir)/gl/m4/alloca.m4 \
+ $(top_srcdir)/gl/m4/arpa_inet_h.m4 \
+ $(top_srcdir)/gl/m4/assert.m4 $(top_srcdir)/gl/m4/bison.m4 \
+ $(top_srcdir)/gl/m4/btowc.m4 $(top_srcdir)/gl/m4/byteswap.m4 \
+ $(top_srcdir)/gl/m4/canonicalize.m4 \
+ $(top_srcdir)/gl/m4/chdir-long.m4 \
+ $(top_srcdir)/gl/m4/check-math-lib.m4 \
+ $(top_srcdir)/gl/m4/clock_time.m4 \
+ $(top_srcdir)/gl/m4/close-stream.m4 \
+ $(top_srcdir)/gl/m4/close.m4 $(top_srcdir)/gl/m4/closedir.m4 \
+ $(top_srcdir)/gl/m4/closein.m4 $(top_srcdir)/gl/m4/closeout.m4 \
+ $(top_srcdir)/gl/m4/codeset.m4 \
+ $(top_srcdir)/gl/m4/configmake.m4 $(top_srcdir)/gl/m4/ctype.m4 \
+ $(top_srcdir)/gl/m4/cycle-check.m4 \
+ $(top_srcdir)/gl/m4/d-ino.m4 $(top_srcdir)/gl/m4/d-type.m4 \
+ $(top_srcdir)/gl/m4/dirent-safer.m4 \
+ $(top_srcdir)/gl/m4/dirent_h.m4 $(top_srcdir)/gl/m4/dirfd.m4 \
+ $(top_srcdir)/gl/m4/dirname.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/euidaccess.m4 \
+ $(top_srcdir)/gl/m4/exponentd.m4 \
+ $(top_srcdir)/gl/m4/exponentf.m4 \
+ $(top_srcdir)/gl/m4/exponentl.m4 \
+ $(top_srcdir)/gl/m4/extensions.m4 \
+ $(top_srcdir)/gl/m4/extern-inline.m4 \
+ $(top_srcdir)/gl/m4/faccessat.m4 $(top_srcdir)/gl/m4/fchdir.m4 \
+ $(top_srcdir)/gl/m4/fcntl-o.m4 \
+ $(top_srcdir)/gl/m4/fcntl-safer.m4 \
+ $(top_srcdir)/gl/m4/fcntl.m4 $(top_srcdir)/gl/m4/fcntl_h.m4 \
+ $(top_srcdir)/gl/m4/fdopen.m4 $(top_srcdir)/gl/m4/fdopendir.m4 \
+ $(top_srcdir)/gl/m4/fflush.m4 \
+ $(top_srcdir)/gl/m4/fileblocks.m4 \
+ $(top_srcdir)/gl/m4/filemode.m4 \
+ $(top_srcdir)/gl/m4/filenamecat.m4 \
+ $(top_srcdir)/gl/m4/flexmember.m4 \
+ $(top_srcdir)/gl/m4/float_h.m4 $(top_srcdir)/gl/m4/fnmatch.m4 \
+ $(top_srcdir)/gl/m4/fopen.m4 $(top_srcdir)/gl/m4/fpending.m4 \
+ $(top_srcdir)/gl/m4/fpieee.m4 $(top_srcdir)/gl/m4/fpurge.m4 \
+ $(top_srcdir)/gl/m4/freadahead.m4 \
+ $(top_srcdir)/gl/m4/freading.m4 $(top_srcdir)/gl/m4/fseek.m4 \
+ $(top_srcdir)/gl/m4/fseeko.m4 $(top_srcdir)/gl/m4/fstat.m4 \
+ $(top_srcdir)/gl/m4/fstatat.m4 \
+ $(top_srcdir)/gl/m4/fstypename.m4 $(top_srcdir)/gl/m4/ftell.m4 \
+ $(top_srcdir)/gl/m4/ftello.m4 $(top_srcdir)/gl/m4/ftruncate.m4 \
+ $(top_srcdir)/gl/m4/fts.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/getgroups.m4 \
+ $(top_srcdir)/gl/m4/gethostname.m4 \
+ $(top_srcdir)/gl/m4/getline.m4 $(top_srcdir)/gl/m4/getopt.m4 \
+ $(top_srcdir)/gl/m4/getpagesize.m4 \
+ $(top_srcdir)/gl/m4/gettext.m4 $(top_srcdir)/gl/m4/gettime.m4 \
+ $(top_srcdir)/gl/m4/gettimeofday.m4 \
+ $(top_srcdir)/gl/m4/glibc21.m4 \
+ $(top_srcdir)/gl/m4/gnulib-common.m4 \
+ $(top_srcdir)/gl/m4/gnulib-comp.m4 \
+ $(top_srcdir)/gl/m4/group-member.m4 \
+ $(top_srcdir)/gl/m4/human.m4 $(top_srcdir)/gl/m4/i-ring.m4 \
+ $(top_srcdir)/gl/m4/iconv.m4 $(top_srcdir)/gl/m4/idcache.m4 \
+ $(top_srcdir)/gl/m4/include_next.m4 \
+ $(top_srcdir)/gl/m4/inet_pton.m4 $(top_srcdir)/gl/m4/inline.m4 \
+ $(top_srcdir)/gl/m4/intlmacosx.m4 \
+ $(top_srcdir)/gl/m4/intmax_t.m4 \
+ $(top_srcdir)/gl/m4/inttostr.m4 \
+ $(top_srcdir)/gl/m4/inttypes-pri.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/isfinite.m4 \
+ $(top_srcdir)/gl/m4/isinf.m4 $(top_srcdir)/gl/m4/isnand.m4 \
+ $(top_srcdir)/gl/m4/isnanf.m4 $(top_srcdir)/gl/m4/isnanl.m4 \
+ $(top_srcdir)/gl/m4/iswblank.m4 \
+ $(top_srcdir)/gl/m4/langinfo_h.m4 \
+ $(top_srcdir)/gl/m4/largefile.m4 \
+ $(top_srcdir)/gl/m4/lcmessage.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/libunistring-base.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-tr.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/localename.m4 $(top_srcdir)/gl/m4/lock.m4 \
+ $(top_srcdir)/gl/m4/longlong.m4 \
+ $(top_srcdir)/gl/m4/ls-mntd-fs.m4 $(top_srcdir)/gl/m4/lseek.m4 \
+ $(top_srcdir)/gl/m4/lstat.m4 $(top_srcdir)/gl/m4/malloc.m4 \
+ $(top_srcdir)/gl/m4/malloca.m4 \
+ $(top_srcdir)/gl/m4/manywarnings.m4 \
+ $(top_srcdir)/gl/m4/math_h.m4 $(top_srcdir)/gl/m4/mathfunc.m4 \
+ $(top_srcdir)/gl/m4/mbchar.m4 $(top_srcdir)/gl/m4/mbiter.m4 \
+ $(top_srcdir)/gl/m4/mbrtowc.m4 $(top_srcdir)/gl/m4/mbsinit.m4 \
+ $(top_srcdir)/gl/m4/mbslen.m4 $(top_srcdir)/gl/m4/mbsrtowcs.m4 \
+ $(top_srcdir)/gl/m4/mbstate_t.m4 \
+ $(top_srcdir)/gl/m4/mbswidth.m4 $(top_srcdir)/gl/m4/mbtowc.m4 \
+ $(top_srcdir)/gl/m4/memchr.m4 $(top_srcdir)/gl/m4/mempcpy.m4 \
+ $(top_srcdir)/gl/m4/memrchr.m4 $(top_srcdir)/gl/m4/mktime.m4 \
+ $(top_srcdir)/gl/m4/mmap-anon.m4 $(top_srcdir)/gl/m4/mode_t.m4 \
+ $(top_srcdir)/gl/m4/modechange.m4 $(top_srcdir)/gl/m4/modf.m4 \
+ $(top_srcdir)/gl/m4/mountlist.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/nanosleep.m4 \
+ $(top_srcdir)/gl/m4/netinet_in_h.m4 \
+ $(top_srcdir)/gl/m4/nl_langinfo.m4 $(top_srcdir)/gl/m4/nls.m4 \
+ $(top_srcdir)/gl/m4/nocrash.m4 $(top_srcdir)/gl/m4/off_t.m4 \
+ $(top_srcdir)/gl/m4/onceonly.m4 $(top_srcdir)/gl/m4/open.m4 \
+ $(top_srcdir)/gl/m4/openat.m4 $(top_srcdir)/gl/m4/opendir.m4 \
+ $(top_srcdir)/gl/m4/parse-datetime.m4 \
+ $(top_srcdir)/gl/m4/pathmax.m4 $(top_srcdir)/gl/m4/perror.m4 \
+ $(top_srcdir)/gl/m4/pipe.m4 $(top_srcdir)/gl/m4/po.m4 \
+ $(top_srcdir)/gl/m4/printf.m4 $(top_srcdir)/gl/m4/priv-set.m4 \
+ $(top_srcdir)/gl/m4/progtest.m4 $(top_srcdir)/gl/m4/putenv.m4 \
+ $(top_srcdir)/gl/m4/quote.m4 $(top_srcdir)/gl/m4/quotearg.m4 \
+ $(top_srcdir)/gl/m4/raise.m4 $(top_srcdir)/gl/m4/read.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/regex.m4 \
+ $(top_srcdir)/gl/m4/rewinddir.m4 $(top_srcdir)/gl/m4/rmdir.m4 \
+ $(top_srcdir)/gl/m4/rpmatch.m4 \
+ $(top_srcdir)/gl/m4/safe-read.m4 $(top_srcdir)/gl/m4/same.m4 \
+ $(top_srcdir)/gl/m4/save-cwd.m4 $(top_srcdir)/gl/m4/savedir.m4 \
+ $(top_srcdir)/gl/m4/select.m4 \
+ $(top_srcdir)/gl/m4/selinux-context-h.m4 \
+ $(top_srcdir)/gl/m4/selinux-selinux-h.m4 \
+ $(top_srcdir)/gl/m4/setenv.m4 $(top_srcdir)/gl/m4/setlocale.m4 \
+ $(top_srcdir)/gl/m4/sigaction.m4 \
+ $(top_srcdir)/gl/m4/signal_h.m4 \
+ $(top_srcdir)/gl/m4/signalblocking.m4 \
+ $(top_srcdir)/gl/m4/size_max.m4 $(top_srcdir)/gl/m4/sleep.m4 \
+ $(top_srcdir)/gl/m4/snprintf.m4 \
+ $(top_srcdir)/gl/m4/socketlib.m4 \
+ $(top_srcdir)/gl/m4/sockets.m4 $(top_srcdir)/gl/m4/socklen.m4 \
+ $(top_srcdir)/gl/m4/sockpfaf.m4 $(top_srcdir)/gl/m4/ssize_t.m4 \
+ $(top_srcdir)/gl/m4/st_dm_mode.m4 \
+ $(top_srcdir)/gl/m4/stat-size.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/stdbool.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/strdup.m4 $(top_srcdir)/gl/m4/strerror.m4 \
+ $(top_srcdir)/gl/m4/strerror_r.m4 \
+ $(top_srcdir)/gl/m4/strftime.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/strstr.m4 $(top_srcdir)/gl/m4/strtoull.m4 \
+ $(top_srcdir)/gl/m4/strtoumax.m4 \
+ $(top_srcdir)/gl/m4/symlink.m4 \
+ $(top_srcdir)/gl/m4/symlinkat.m4 \
+ $(top_srcdir)/gl/m4/sys_ioctl_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/sys_utsname_h.m4 \
+ $(top_srcdir)/gl/m4/sys_wait_h.m4 \
+ $(top_srcdir)/gl/m4/thread.m4 $(top_srcdir)/gl/m4/threadlib.m4 \
+ $(top_srcdir)/gl/m4/time_h.m4 $(top_srcdir)/gl/m4/time_r.m4 \
+ $(top_srcdir)/gl/m4/time_rz.m4 $(top_srcdir)/gl/m4/timegm.m4 \
+ $(top_srcdir)/gl/m4/timespec.m4 \
+ $(top_srcdir)/gl/m4/tm_gmtoff.m4 $(top_srcdir)/gl/m4/trunc.m4 \
+ $(top_srcdir)/gl/m4/uname.m4 $(top_srcdir)/gl/m4/ungetc.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/unlinkdir.m4 \
+ $(top_srcdir)/gl/m4/vasnprintf.m4 \
+ $(top_srcdir)/gl/m4/version-etc.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/wctob.m4 $(top_srcdir)/gl/m4/wctomb.m4 \
+ $(top_srcdir)/gl/m4/wctype_h.m4 $(top_srcdir)/gl/m4/wcwidth.m4 \
+ $(top_srcdir)/gl/m4/wint_t.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/xstrtod.m4 \
+ $(top_srcdir)/gl/m4/xstrtol.m4 $(top_srcdir)/gl/m4/yesno.m4 \
+ $(top_srcdir)/gl/m4/yield.m4 $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+mkinstalldirs = $(SHELL) $(top_srcdir)/build-aux/mkinstalldirs
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+LIBRARIES = $(noinst_LIBRARIES)
+AM_V_AR = $(am__v_AR_@AM_V@)
+am__v_AR_ = $(am__v_AR_@AM_DEFAULT_V@)
+am__v_AR_0 = @echo " AR " $@;
+am__v_AR_1 =
+libfindtools_a_AR = $(AR) $(ARFLAGS)
+libfindtools_a_LIBADD =
+am_libfindtools_a_OBJECTS = finddata.$(OBJEXT) fstype.$(OBJEXT) \
+ parser.$(OBJEXT) pred.$(OBJEXT) exec.$(OBJEXT) tree.$(OBJEXT) \
+ util.$(OBJEXT) sharefile.$(OBJEXT) print.$(OBJEXT)
+libfindtools_a_OBJECTS = $(am_libfindtools_a_OBJECTS)
+am__installdirs = "$(DESTDIR)$(bindir)" "$(DESTDIR)$(man1dir)"
+PROGRAMS = $(bin_PROGRAMS)
+am_find_OBJECTS = ftsfind.$(OBJEXT)
+find_OBJECTS = $(am_find_OBJECTS)
+find_LDADD = $(LDADD)
+am__DEPENDENCIES_1 =
+find_DEPENDENCIES = ./libfindtools.a ../lib/libfind.a \
+ ../gl/lib/libgnulib.a $(am__DEPENDENCIES_1) \
+ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+ $(am__DEPENDENCIES_1)
+am_oldfind_OBJECTS = oldfind.$(OBJEXT)
+oldfind_OBJECTS = $(am_oldfind_OBJECTS)
+oldfind_LDADD = $(LDADD)
+oldfind_DEPENDENCIES = ./libfindtools.a ../lib/libfind.a \
+ ../gl/lib/libgnulib.a $(am__DEPENDENCIES_1) \
+ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+ $(am__DEPENDENCIES_1)
+AM_V_P = $(am__v_P_@AM_V@)
+am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_@AM_V@)
+am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
+am__v_GEN_0 = @echo " GEN " $@;
+am__v_GEN_1 =
+AM_V_at = $(am__v_at_@AM_V@)
+am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 =
+DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
+depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp
+am__depfiles_maybe = depfiles
+am__mv = mv -f
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+AM_V_CC = $(am__v_CC_@AM_V@)
+am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@)
+am__v_CC_0 = @echo " CC " $@;
+am__v_CC_1 =
+CCLD = $(CC)
+LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
+AM_V_CCLD = $(am__v_CCLD_@AM_V@)
+am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@)
+am__v_CCLD_0 = @echo " CCLD " $@;
+am__v_CCLD_1 =
+SOURCES = $(libfindtools_a_SOURCES) $(find_SOURCES) $(oldfind_SOURCES)
+DIST_SOURCES = $(libfindtools_a_SOURCES) $(find_SOURCES) \
+ $(oldfind_SOURCES)
+RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \
+ ctags-recursive dvi-recursive html-recursive info-recursive \
+ install-data-recursive install-dvi-recursive \
+ install-exec-recursive install-html-recursive \
+ install-info-recursive install-pdf-recursive \
+ install-ps-recursive install-recursive installcheck-recursive \
+ installdirs-recursive pdf-recursive ps-recursive \
+ tags-recursive uninstall-recursive
+am__can_run_installinfo = \
+ case $$AM_UPDATE_INFO_DIR in \
+ n|no|NO) false;; \
+ *) (install-info --version) >/dev/null 2>&1;; \
+ esac
+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; }; \
+ }
+man1dir = $(mandir)/man1
+NROFF = nroff
+MANS = $(man_MANS)
+RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \
+ distclean-recursive maintainer-clean-recursive
+am__recursive_targets = \
+ $(RECURSIVE_TARGETS) \
+ $(RECURSIVE_CLEAN_TARGETS) \
+ $(am__extra_recursive_targets)
+AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \
+ distdir
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
+# Read a list of newline-separated strings from the standard input,
+# and print each of them once, without duplicates. Input order is
+# *not* preserved.
+am__uniquify_input = $(AWK) '\
+ BEGIN { nonempty = 0; } \
+ { items[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in items) print i; }; } \
+'
+# Make sure the list of sources is unique. This is necessary because,
+# e.g., the same source file might be shared among _SOURCES variables
+# for different programs/libraries.
+am__define_uniq_tagged_files = \
+ list='$(am__tagged_files)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | $(am__uniquify_input)`
+ETAGS = etags
+CTAGS = ctags
+DIST_SUBDIRS = $(SUBDIRS)
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+am__relativize = \
+ dir0=`pwd`; \
+ sed_first='s,^\([^/]*\)/.*$$,\1,'; \
+ sed_rest='s,^[^/]*/*,,'; \
+ sed_last='s,^.*/\([^/]*\)$$,\1,'; \
+ sed_butlast='s,/*[^/]*$$,,'; \
+ while test -n "$$dir1"; do \
+ first=`echo "$$dir1" | sed -e "$$sed_first"`; \
+ if test "$$first" != "."; then \
+ if test "$$first" = ".."; then \
+ dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \
+ dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \
+ else \
+ first2=`echo "$$dir2" | sed -e "$$sed_first"`; \
+ if test "$$first2" = "$$first"; then \
+ dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \
+ else \
+ dir2="../$$dir2"; \
+ fi; \
+ dir0="$$dir0"/"$$first"; \
+ fi; \
+ fi; \
+ dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \
+ done; \
+ reldir="$$dir2"
+pkglibexecdir = @pkglibexecdir@
+ACLOCAL = @ACLOCAL@
+ALLOCA = @ALLOCA@
+ALLOCA_H = @ALLOCA_H@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+APPLE_UNIVERSAL_BUILD = @APPLE_UNIVERSAL_BUILD@
+AR = @AR@
+ARFLAGS = @ARFLAGS@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AUXDIR = @AUXDIR@
+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@
+BYTESWAP_H = @BYTESWAP_H@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CONFIG_INCLUDE = @CONFIG_INCLUDE@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFAULT_ARG_SIZE = @DEFAULT_ARG_SIZE@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EMULTIHOP_HIDDEN = @EMULTIHOP_HIDDEN@
+EMULTIHOP_VALUE = @EMULTIHOP_VALUE@
+ENOLINK_HIDDEN = @ENOLINK_HIDDEN@
+ENOLINK_VALUE = @ENOLINK_VALUE@
+EOVERFLOW_HIDDEN = @EOVERFLOW_HIDDEN@
+EOVERFLOW_VALUE = @EOVERFLOW_VALUE@
+ERRNO_H = @ERRNO_H@
+EXEEXT = @EXEEXT@
+FAKETIME = @FAKETIME@
+FINDLIBOBJS = @FINDLIBOBJS@
+FINDLIBS = @FINDLIBS@
+FLOAT_H = @FLOAT_H@
+FNMATCH_H = @FNMATCH_H@
+GETHOSTNAME_LIB = @GETHOSTNAME_LIB@
+GETOPT_H = @GETOPT_H@
+GETTEXT_MACRO_VERSION = @GETTEXT_MACRO_VERSION@
+GLIBC21 = @GLIBC21@
+GMSGFMT = @GMSGFMT@
+GMSGFMT_015 = @GMSGFMT_015@
+GNULIB_ACCEPT = @GNULIB_ACCEPT@
+GNULIB_ACCEPT4 = @GNULIB_ACCEPT4@
+GNULIB_ACOSF = @GNULIB_ACOSF@
+GNULIB_ACOSL = @GNULIB_ACOSL@
+GNULIB_ALPHASORT = @GNULIB_ALPHASORT@
+GNULIB_ASINF = @GNULIB_ASINF@
+GNULIB_ASINL = @GNULIB_ASINL@
+GNULIB_ATAN2F = @GNULIB_ATAN2F@
+GNULIB_ATANF = @GNULIB_ATANF@
+GNULIB_ATANL = @GNULIB_ATANL@
+GNULIB_ATOLL = @GNULIB_ATOLL@
+GNULIB_BIND = @GNULIB_BIND@
+GNULIB_BTOWC = @GNULIB_BTOWC@
+GNULIB_CALLOC_POSIX = @GNULIB_CALLOC_POSIX@
+GNULIB_CANONICALIZE_FILE_NAME = @GNULIB_CANONICALIZE_FILE_NAME@
+GNULIB_CBRT = @GNULIB_CBRT@
+GNULIB_CBRTF = @GNULIB_CBRTF@
+GNULIB_CBRTL = @GNULIB_CBRTL@
+GNULIB_CEIL = @GNULIB_CEIL@
+GNULIB_CEILF = @GNULIB_CEILF@
+GNULIB_CEILL = @GNULIB_CEILL@
+GNULIB_CHDIR = @GNULIB_CHDIR@
+GNULIB_CHOWN = @GNULIB_CHOWN@
+GNULIB_CLOSE = @GNULIB_CLOSE@
+GNULIB_CLOSEDIR = @GNULIB_CLOSEDIR@
+GNULIB_CONNECT = @GNULIB_CONNECT@
+GNULIB_COPYSIGN = @GNULIB_COPYSIGN@
+GNULIB_COPYSIGNF = @GNULIB_COPYSIGNF@
+GNULIB_COPYSIGNL = @GNULIB_COPYSIGNL@
+GNULIB_COSF = @GNULIB_COSF@
+GNULIB_COSHF = @GNULIB_COSHF@
+GNULIB_COSL = @GNULIB_COSL@
+GNULIB_DIRFD = @GNULIB_DIRFD@
+GNULIB_DPRINTF = @GNULIB_DPRINTF@
+GNULIB_DUP = @GNULIB_DUP@
+GNULIB_DUP2 = @GNULIB_DUP2@
+GNULIB_DUP3 = @GNULIB_DUP3@
+GNULIB_DUPLOCALE = @GNULIB_DUPLOCALE@
+GNULIB_ENVIRON = @GNULIB_ENVIRON@
+GNULIB_EUIDACCESS = @GNULIB_EUIDACCESS@
+GNULIB_EXP2 = @GNULIB_EXP2@
+GNULIB_EXP2F = @GNULIB_EXP2F@
+GNULIB_EXP2L = @GNULIB_EXP2L@
+GNULIB_EXPF = @GNULIB_EXPF@
+GNULIB_EXPL = @GNULIB_EXPL@
+GNULIB_EXPM1 = @GNULIB_EXPM1@
+GNULIB_EXPM1F = @GNULIB_EXPM1F@
+GNULIB_EXPM1L = @GNULIB_EXPM1L@
+GNULIB_FABSF = @GNULIB_FABSF@
+GNULIB_FABSL = @GNULIB_FABSL@
+GNULIB_FACCESSAT = @GNULIB_FACCESSAT@
+GNULIB_FCHDIR = @GNULIB_FCHDIR@
+GNULIB_FCHMODAT = @GNULIB_FCHMODAT@
+GNULIB_FCHOWNAT = @GNULIB_FCHOWNAT@
+GNULIB_FCLOSE = @GNULIB_FCLOSE@
+GNULIB_FCNTL = @GNULIB_FCNTL@
+GNULIB_FDATASYNC = @GNULIB_FDATASYNC@
+GNULIB_FDOPEN = @GNULIB_FDOPEN@
+GNULIB_FDOPENDIR = @GNULIB_FDOPENDIR@
+GNULIB_FFLUSH = @GNULIB_FFLUSH@
+GNULIB_FFS = @GNULIB_FFS@
+GNULIB_FFSL = @GNULIB_FFSL@
+GNULIB_FFSLL = @GNULIB_FFSLL@
+GNULIB_FGETC = @GNULIB_FGETC@
+GNULIB_FGETS = @GNULIB_FGETS@
+GNULIB_FLOOR = @GNULIB_FLOOR@
+GNULIB_FLOORF = @GNULIB_FLOORF@
+GNULIB_FLOORL = @GNULIB_FLOORL@
+GNULIB_FMA = @GNULIB_FMA@
+GNULIB_FMAF = @GNULIB_FMAF@
+GNULIB_FMAL = @GNULIB_FMAL@
+GNULIB_FMOD = @GNULIB_FMOD@
+GNULIB_FMODF = @GNULIB_FMODF@
+GNULIB_FMODL = @GNULIB_FMODL@
+GNULIB_FOPEN = @GNULIB_FOPEN@
+GNULIB_FPRINTF = @GNULIB_FPRINTF@
+GNULIB_FPRINTF_POSIX = @GNULIB_FPRINTF_POSIX@
+GNULIB_FPURGE = @GNULIB_FPURGE@
+GNULIB_FPUTC = @GNULIB_FPUTC@
+GNULIB_FPUTS = @GNULIB_FPUTS@
+GNULIB_FREAD = @GNULIB_FREAD@
+GNULIB_FREOPEN = @GNULIB_FREOPEN@
+GNULIB_FREXP = @GNULIB_FREXP@
+GNULIB_FREXPF = @GNULIB_FREXPF@
+GNULIB_FREXPL = @GNULIB_FREXPL@
+GNULIB_FSCANF = @GNULIB_FSCANF@
+GNULIB_FSEEK = @GNULIB_FSEEK@
+GNULIB_FSEEKO = @GNULIB_FSEEKO@
+GNULIB_FSTAT = @GNULIB_FSTAT@
+GNULIB_FSTATAT = @GNULIB_FSTATAT@
+GNULIB_FSYNC = @GNULIB_FSYNC@
+GNULIB_FTELL = @GNULIB_FTELL@
+GNULIB_FTELLO = @GNULIB_FTELLO@
+GNULIB_FTRUNCATE = @GNULIB_FTRUNCATE@
+GNULIB_FUTIMENS = @GNULIB_FUTIMENS@
+GNULIB_FWRITE = @GNULIB_FWRITE@
+GNULIB_GETC = @GNULIB_GETC@
+GNULIB_GETCHAR = @GNULIB_GETCHAR@
+GNULIB_GETCWD = @GNULIB_GETCWD@
+GNULIB_GETDELIM = @GNULIB_GETDELIM@
+GNULIB_GETDOMAINNAME = @GNULIB_GETDOMAINNAME@
+GNULIB_GETDTABLESIZE = @GNULIB_GETDTABLESIZE@
+GNULIB_GETGROUPS = @GNULIB_GETGROUPS@
+GNULIB_GETHOSTNAME = @GNULIB_GETHOSTNAME@
+GNULIB_GETLINE = @GNULIB_GETLINE@
+GNULIB_GETLOADAVG = @GNULIB_GETLOADAVG@
+GNULIB_GETLOGIN = @GNULIB_GETLOGIN@
+GNULIB_GETLOGIN_R = @GNULIB_GETLOGIN_R@
+GNULIB_GETPAGESIZE = @GNULIB_GETPAGESIZE@
+GNULIB_GETPEERNAME = @GNULIB_GETPEERNAME@
+GNULIB_GETSOCKNAME = @GNULIB_GETSOCKNAME@
+GNULIB_GETSOCKOPT = @GNULIB_GETSOCKOPT@
+GNULIB_GETSUBOPT = @GNULIB_GETSUBOPT@
+GNULIB_GETTIMEOFDAY = @GNULIB_GETTIMEOFDAY@
+GNULIB_GETUSERSHELL = @GNULIB_GETUSERSHELL@
+GNULIB_GL_UNISTD_H_GETOPT = @GNULIB_GL_UNISTD_H_GETOPT@
+GNULIB_GRANTPT = @GNULIB_GRANTPT@
+GNULIB_GROUP_MEMBER = @GNULIB_GROUP_MEMBER@
+GNULIB_HYPOT = @GNULIB_HYPOT@
+GNULIB_HYPOTF = @GNULIB_HYPOTF@
+GNULIB_HYPOTL = @GNULIB_HYPOTL@
+GNULIB_ILOGB = @GNULIB_ILOGB@
+GNULIB_ILOGBF = @GNULIB_ILOGBF@
+GNULIB_ILOGBL = @GNULIB_ILOGBL@
+GNULIB_IMAXABS = @GNULIB_IMAXABS@
+GNULIB_IMAXDIV = @GNULIB_IMAXDIV@
+GNULIB_INET_NTOP = @GNULIB_INET_NTOP@
+GNULIB_INET_PTON = @GNULIB_INET_PTON@
+GNULIB_IOCTL = @GNULIB_IOCTL@
+GNULIB_ISATTY = @GNULIB_ISATTY@
+GNULIB_ISBLANK = @GNULIB_ISBLANK@
+GNULIB_ISFINITE = @GNULIB_ISFINITE@
+GNULIB_ISINF = @GNULIB_ISINF@
+GNULIB_ISNAN = @GNULIB_ISNAN@
+GNULIB_ISNAND = @GNULIB_ISNAND@
+GNULIB_ISNANF = @GNULIB_ISNANF@
+GNULIB_ISNANL = @GNULIB_ISNANL@
+GNULIB_ISWBLANK = @GNULIB_ISWBLANK@
+GNULIB_ISWCTYPE = @GNULIB_ISWCTYPE@
+GNULIB_LCHMOD = @GNULIB_LCHMOD@
+GNULIB_LCHOWN = @GNULIB_LCHOWN@
+GNULIB_LDEXPF = @GNULIB_LDEXPF@
+GNULIB_LDEXPL = @GNULIB_LDEXPL@
+GNULIB_LINK = @GNULIB_LINK@
+GNULIB_LINKAT = @GNULIB_LINKAT@
+GNULIB_LISTEN = @GNULIB_LISTEN@
+GNULIB_LOCALECONV = @GNULIB_LOCALECONV@
+GNULIB_LOG = @GNULIB_LOG@
+GNULIB_LOG10 = @GNULIB_LOG10@
+GNULIB_LOG10F = @GNULIB_LOG10F@
+GNULIB_LOG10L = @GNULIB_LOG10L@
+GNULIB_LOG1P = @GNULIB_LOG1P@
+GNULIB_LOG1PF = @GNULIB_LOG1PF@
+GNULIB_LOG1PL = @GNULIB_LOG1PL@
+GNULIB_LOG2 = @GNULIB_LOG2@
+GNULIB_LOG2F = @GNULIB_LOG2F@
+GNULIB_LOG2L = @GNULIB_LOG2L@
+GNULIB_LOGB = @GNULIB_LOGB@
+GNULIB_LOGBF = @GNULIB_LOGBF@
+GNULIB_LOGBL = @GNULIB_LOGBL@
+GNULIB_LOGF = @GNULIB_LOGF@
+GNULIB_LOGL = @GNULIB_LOGL@
+GNULIB_LSEEK = @GNULIB_LSEEK@
+GNULIB_LSTAT = @GNULIB_LSTAT@
+GNULIB_MALLOC_POSIX = @GNULIB_MALLOC_POSIX@
+GNULIB_MBRLEN = @GNULIB_MBRLEN@
+GNULIB_MBRTOWC = @GNULIB_MBRTOWC@
+GNULIB_MBSCASECMP = @GNULIB_MBSCASECMP@
+GNULIB_MBSCASESTR = @GNULIB_MBSCASESTR@
+GNULIB_MBSCHR = @GNULIB_MBSCHR@
+GNULIB_MBSCSPN = @GNULIB_MBSCSPN@
+GNULIB_MBSINIT = @GNULIB_MBSINIT@
+GNULIB_MBSLEN = @GNULIB_MBSLEN@
+GNULIB_MBSNCASECMP = @GNULIB_MBSNCASECMP@
+GNULIB_MBSNLEN = @GNULIB_MBSNLEN@
+GNULIB_MBSNRTOWCS = @GNULIB_MBSNRTOWCS@
+GNULIB_MBSPBRK = @GNULIB_MBSPBRK@
+GNULIB_MBSPCASECMP = @GNULIB_MBSPCASECMP@
+GNULIB_MBSRCHR = @GNULIB_MBSRCHR@
+GNULIB_MBSRTOWCS = @GNULIB_MBSRTOWCS@
+GNULIB_MBSSEP = @GNULIB_MBSSEP@
+GNULIB_MBSSPN = @GNULIB_MBSSPN@
+GNULIB_MBSSTR = @GNULIB_MBSSTR@
+GNULIB_MBSTOK_R = @GNULIB_MBSTOK_R@
+GNULIB_MBTOWC = @GNULIB_MBTOWC@
+GNULIB_MEMCHR = @GNULIB_MEMCHR@
+GNULIB_MEMMEM = @GNULIB_MEMMEM@
+GNULIB_MEMPCPY = @GNULIB_MEMPCPY@
+GNULIB_MEMRCHR = @GNULIB_MEMRCHR@
+GNULIB_MKDIRAT = @GNULIB_MKDIRAT@
+GNULIB_MKDTEMP = @GNULIB_MKDTEMP@
+GNULIB_MKFIFO = @GNULIB_MKFIFO@
+GNULIB_MKFIFOAT = @GNULIB_MKFIFOAT@
+GNULIB_MKNOD = @GNULIB_MKNOD@
+GNULIB_MKNODAT = @GNULIB_MKNODAT@
+GNULIB_MKOSTEMP = @GNULIB_MKOSTEMP@
+GNULIB_MKOSTEMPS = @GNULIB_MKOSTEMPS@
+GNULIB_MKSTEMP = @GNULIB_MKSTEMP@
+GNULIB_MKSTEMPS = @GNULIB_MKSTEMPS@
+GNULIB_MKTIME = @GNULIB_MKTIME@
+GNULIB_MODF = @GNULIB_MODF@
+GNULIB_MODFF = @GNULIB_MODFF@
+GNULIB_MODFL = @GNULIB_MODFL@
+GNULIB_NANOSLEEP = @GNULIB_NANOSLEEP@
+GNULIB_NL_LANGINFO = @GNULIB_NL_LANGINFO@
+GNULIB_NONBLOCKING = @GNULIB_NONBLOCKING@
+GNULIB_OBSTACK_PRINTF = @GNULIB_OBSTACK_PRINTF@
+GNULIB_OBSTACK_PRINTF_POSIX = @GNULIB_OBSTACK_PRINTF_POSIX@
+GNULIB_OPEN = @GNULIB_OPEN@
+GNULIB_OPENAT = @GNULIB_OPENAT@
+GNULIB_OPENDIR = @GNULIB_OPENDIR@
+GNULIB_PCLOSE = @GNULIB_PCLOSE@
+GNULIB_PERROR = @GNULIB_PERROR@
+GNULIB_PIPE = @GNULIB_PIPE@
+GNULIB_PIPE2 = @GNULIB_PIPE2@
+GNULIB_POPEN = @GNULIB_POPEN@
+GNULIB_POSIX_OPENPT = @GNULIB_POSIX_OPENPT@
+GNULIB_POWF = @GNULIB_POWF@
+GNULIB_PREAD = @GNULIB_PREAD@
+GNULIB_PRINTF = @GNULIB_PRINTF@
+GNULIB_PRINTF_POSIX = @GNULIB_PRINTF_POSIX@
+GNULIB_PSELECT = @GNULIB_PSELECT@
+GNULIB_PTHREAD_SIGMASK = @GNULIB_PTHREAD_SIGMASK@
+GNULIB_PTSNAME = @GNULIB_PTSNAME@
+GNULIB_PTSNAME_R = @GNULIB_PTSNAME_R@
+GNULIB_PUTC = @GNULIB_PUTC@
+GNULIB_PUTCHAR = @GNULIB_PUTCHAR@
+GNULIB_PUTENV = @GNULIB_PUTENV@
+GNULIB_PUTS = @GNULIB_PUTS@
+GNULIB_PWRITE = @GNULIB_PWRITE@
+GNULIB_QSORT_R = @GNULIB_QSORT_R@
+GNULIB_RAISE = @GNULIB_RAISE@
+GNULIB_RANDOM = @GNULIB_RANDOM@
+GNULIB_RANDOM_R = @GNULIB_RANDOM_R@
+GNULIB_RAWMEMCHR = @GNULIB_RAWMEMCHR@
+GNULIB_READ = @GNULIB_READ@
+GNULIB_READDIR = @GNULIB_READDIR@
+GNULIB_READLINK = @GNULIB_READLINK@
+GNULIB_READLINKAT = @GNULIB_READLINKAT@
+GNULIB_REALLOC_POSIX = @GNULIB_REALLOC_POSIX@
+GNULIB_REALPATH = @GNULIB_REALPATH@
+GNULIB_RECV = @GNULIB_RECV@
+GNULIB_RECVFROM = @GNULIB_RECVFROM@
+GNULIB_REMAINDER = @GNULIB_REMAINDER@
+GNULIB_REMAINDERF = @GNULIB_REMAINDERF@
+GNULIB_REMAINDERL = @GNULIB_REMAINDERL@
+GNULIB_REMOVE = @GNULIB_REMOVE@
+GNULIB_RENAME = @GNULIB_RENAME@
+GNULIB_RENAMEAT = @GNULIB_RENAMEAT@
+GNULIB_REWINDDIR = @GNULIB_REWINDDIR@
+GNULIB_RINT = @GNULIB_RINT@
+GNULIB_RINTF = @GNULIB_RINTF@
+GNULIB_RINTL = @GNULIB_RINTL@
+GNULIB_RMDIR = @GNULIB_RMDIR@
+GNULIB_ROUND = @GNULIB_ROUND@
+GNULIB_ROUNDF = @GNULIB_ROUNDF@
+GNULIB_ROUNDL = @GNULIB_ROUNDL@
+GNULIB_RPMATCH = @GNULIB_RPMATCH@
+GNULIB_SCANDIR = @GNULIB_SCANDIR@
+GNULIB_SCANF = @GNULIB_SCANF@
+GNULIB_SECURE_GETENV = @GNULIB_SECURE_GETENV@
+GNULIB_SELECT = @GNULIB_SELECT@
+GNULIB_SEND = @GNULIB_SEND@
+GNULIB_SENDTO = @GNULIB_SENDTO@
+GNULIB_SETENV = @GNULIB_SETENV@
+GNULIB_SETHOSTNAME = @GNULIB_SETHOSTNAME@
+GNULIB_SETLOCALE = @GNULIB_SETLOCALE@
+GNULIB_SETSOCKOPT = @GNULIB_SETSOCKOPT@
+GNULIB_SHUTDOWN = @GNULIB_SHUTDOWN@
+GNULIB_SIGACTION = @GNULIB_SIGACTION@
+GNULIB_SIGNAL_H_SIGPIPE = @GNULIB_SIGNAL_H_SIGPIPE@
+GNULIB_SIGNBIT = @GNULIB_SIGNBIT@
+GNULIB_SIGPROCMASK = @GNULIB_SIGPROCMASK@
+GNULIB_SINF = @GNULIB_SINF@
+GNULIB_SINHF = @GNULIB_SINHF@
+GNULIB_SINL = @GNULIB_SINL@
+GNULIB_SLEEP = @GNULIB_SLEEP@
+GNULIB_SNPRINTF = @GNULIB_SNPRINTF@
+GNULIB_SOCKET = @GNULIB_SOCKET@
+GNULIB_SPRINTF_POSIX = @GNULIB_SPRINTF_POSIX@
+GNULIB_SQRTF = @GNULIB_SQRTF@
+GNULIB_SQRTL = @GNULIB_SQRTL@
+GNULIB_STAT = @GNULIB_STAT@
+GNULIB_STDIO_H_NONBLOCKING = @GNULIB_STDIO_H_NONBLOCKING@
+GNULIB_STDIO_H_SIGPIPE = @GNULIB_STDIO_H_SIGPIPE@
+GNULIB_STPCPY = @GNULIB_STPCPY@
+GNULIB_STPNCPY = @GNULIB_STPNCPY@
+GNULIB_STRCASESTR = @GNULIB_STRCASESTR@
+GNULIB_STRCHRNUL = @GNULIB_STRCHRNUL@
+GNULIB_STRDUP = @GNULIB_STRDUP@
+GNULIB_STRERROR = @GNULIB_STRERROR@
+GNULIB_STRERROR_R = @GNULIB_STRERROR_R@
+GNULIB_STRNCAT = @GNULIB_STRNCAT@
+GNULIB_STRNDUP = @GNULIB_STRNDUP@
+GNULIB_STRNLEN = @GNULIB_STRNLEN@
+GNULIB_STRPBRK = @GNULIB_STRPBRK@
+GNULIB_STRPTIME = @GNULIB_STRPTIME@
+GNULIB_STRSEP = @GNULIB_STRSEP@
+GNULIB_STRSIGNAL = @GNULIB_STRSIGNAL@
+GNULIB_STRSTR = @GNULIB_STRSTR@
+GNULIB_STRTOD = @GNULIB_STRTOD@
+GNULIB_STRTOIMAX = @GNULIB_STRTOIMAX@
+GNULIB_STRTOK_R = @GNULIB_STRTOK_R@
+GNULIB_STRTOLL = @GNULIB_STRTOLL@
+GNULIB_STRTOULL = @GNULIB_STRTOULL@
+GNULIB_STRTOUMAX = @GNULIB_STRTOUMAX@
+GNULIB_STRVERSCMP = @GNULIB_STRVERSCMP@
+GNULIB_SYMLINK = @GNULIB_SYMLINK@
+GNULIB_SYMLINKAT = @GNULIB_SYMLINKAT@
+GNULIB_SYSTEM_POSIX = @GNULIB_SYSTEM_POSIX@
+GNULIB_TANF = @GNULIB_TANF@
+GNULIB_TANHF = @GNULIB_TANHF@
+GNULIB_TANL = @GNULIB_TANL@
+GNULIB_TIMEGM = @GNULIB_TIMEGM@
+GNULIB_TIME_R = @GNULIB_TIME_R@
+GNULIB_TIME_RZ = @GNULIB_TIME_RZ@
+GNULIB_TMPFILE = @GNULIB_TMPFILE@
+GNULIB_TOWCTRANS = @GNULIB_TOWCTRANS@
+GNULIB_TRUNC = @GNULIB_TRUNC@
+GNULIB_TRUNCF = @GNULIB_TRUNCF@
+GNULIB_TRUNCL = @GNULIB_TRUNCL@
+GNULIB_TTYNAME_R = @GNULIB_TTYNAME_R@
+GNULIB_UNAME = @GNULIB_UNAME@
+GNULIB_UNISTD_H_NONBLOCKING = @GNULIB_UNISTD_H_NONBLOCKING@
+GNULIB_UNISTD_H_SIGPIPE = @GNULIB_UNISTD_H_SIGPIPE@
+GNULIB_UNLINK = @GNULIB_UNLINK@
+GNULIB_UNLINKAT = @GNULIB_UNLINKAT@
+GNULIB_UNLOCKPT = @GNULIB_UNLOCKPT@
+GNULIB_UNSETENV = @GNULIB_UNSETENV@
+GNULIB_USLEEP = @GNULIB_USLEEP@
+GNULIB_UTIMENSAT = @GNULIB_UTIMENSAT@
+GNULIB_VASPRINTF = @GNULIB_VASPRINTF@
+GNULIB_VDPRINTF = @GNULIB_VDPRINTF@
+GNULIB_VFPRINTF = @GNULIB_VFPRINTF@
+GNULIB_VFPRINTF_POSIX = @GNULIB_VFPRINTF_POSIX@
+GNULIB_VFSCANF = @GNULIB_VFSCANF@
+GNULIB_VPRINTF = @GNULIB_VPRINTF@
+GNULIB_VPRINTF_POSIX = @GNULIB_VPRINTF_POSIX@
+GNULIB_VSCANF = @GNULIB_VSCANF@
+GNULIB_VSNPRINTF = @GNULIB_VSNPRINTF@
+GNULIB_VSPRINTF_POSIX = @GNULIB_VSPRINTF_POSIX@
+GNULIB_WAITPID = @GNULIB_WAITPID@
+GNULIB_WCPCPY = @GNULIB_WCPCPY@
+GNULIB_WCPNCPY = @GNULIB_WCPNCPY@
+GNULIB_WCRTOMB = @GNULIB_WCRTOMB@
+GNULIB_WCSCASECMP = @GNULIB_WCSCASECMP@
+GNULIB_WCSCAT = @GNULIB_WCSCAT@
+GNULIB_WCSCHR = @GNULIB_WCSCHR@
+GNULIB_WCSCMP = @GNULIB_WCSCMP@
+GNULIB_WCSCOLL = @GNULIB_WCSCOLL@
+GNULIB_WCSCPY = @GNULIB_WCSCPY@
+GNULIB_WCSCSPN = @GNULIB_WCSCSPN@
+GNULIB_WCSDUP = @GNULIB_WCSDUP@
+GNULIB_WCSLEN = @GNULIB_WCSLEN@
+GNULIB_WCSNCASECMP = @GNULIB_WCSNCASECMP@
+GNULIB_WCSNCAT = @GNULIB_WCSNCAT@
+GNULIB_WCSNCMP = @GNULIB_WCSNCMP@
+GNULIB_WCSNCPY = @GNULIB_WCSNCPY@
+GNULIB_WCSNLEN = @GNULIB_WCSNLEN@
+GNULIB_WCSNRTOMBS = @GNULIB_WCSNRTOMBS@
+GNULIB_WCSPBRK = @GNULIB_WCSPBRK@
+GNULIB_WCSRCHR = @GNULIB_WCSRCHR@
+GNULIB_WCSRTOMBS = @GNULIB_WCSRTOMBS@
+GNULIB_WCSSPN = @GNULIB_WCSSPN@
+GNULIB_WCSSTR = @GNULIB_WCSSTR@
+GNULIB_WCSTOK = @GNULIB_WCSTOK@
+GNULIB_WCSWIDTH = @GNULIB_WCSWIDTH@
+GNULIB_WCSXFRM = @GNULIB_WCSXFRM@
+GNULIB_WCTOB = @GNULIB_WCTOB@
+GNULIB_WCTOMB = @GNULIB_WCTOMB@
+GNULIB_WCTRANS = @GNULIB_WCTRANS@
+GNULIB_WCTYPE = @GNULIB_WCTYPE@
+GNULIB_WCWIDTH = @GNULIB_WCWIDTH@
+GNULIB_WMEMCHR = @GNULIB_WMEMCHR@
+GNULIB_WMEMCMP = @GNULIB_WMEMCMP@
+GNULIB_WMEMCPY = @GNULIB_WMEMCPY@
+GNULIB_WMEMMOVE = @GNULIB_WMEMMOVE@
+GNULIB_WMEMSET = @GNULIB_WMEMSET@
+GNULIB_WRITE = @GNULIB_WRITE@
+GNULIB__EXIT = @GNULIB__EXIT@
+GREP = @GREP@
+HAVE_ACCEPT4 = @HAVE_ACCEPT4@
+HAVE_ACOSF = @HAVE_ACOSF@
+HAVE_ACOSL = @HAVE_ACOSL@
+HAVE_ALPHASORT = @HAVE_ALPHASORT@
+HAVE_ARPA_INET_H = @HAVE_ARPA_INET_H@
+HAVE_ASINF = @HAVE_ASINF@
+HAVE_ASINL = @HAVE_ASINL@
+HAVE_ATAN2F = @HAVE_ATAN2F@
+HAVE_ATANF = @HAVE_ATANF@
+HAVE_ATANL = @HAVE_ATANL@
+HAVE_ATOLL = @HAVE_ATOLL@
+HAVE_ATTRIBUTE_NORETURN = @HAVE_ATTRIBUTE_NORETURN@
+HAVE_BTOWC = @HAVE_BTOWC@
+HAVE_CANONICALIZE_FILE_NAME = @HAVE_CANONICALIZE_FILE_NAME@
+HAVE_CBRT = @HAVE_CBRT@
+HAVE_CBRTF = @HAVE_CBRTF@
+HAVE_CBRTL = @HAVE_CBRTL@
+HAVE_CHOWN = @HAVE_CHOWN@
+HAVE_CLOSEDIR = @HAVE_CLOSEDIR@
+HAVE_COPYSIGN = @HAVE_COPYSIGN@
+HAVE_COPYSIGNL = @HAVE_COPYSIGNL@
+HAVE_COSF = @HAVE_COSF@
+HAVE_COSHF = @HAVE_COSHF@
+HAVE_COSL = @HAVE_COSL@
+HAVE_DECL_ACOSL = @HAVE_DECL_ACOSL@
+HAVE_DECL_ASINL = @HAVE_DECL_ASINL@
+HAVE_DECL_ATANL = @HAVE_DECL_ATANL@
+HAVE_DECL_CBRTF = @HAVE_DECL_CBRTF@
+HAVE_DECL_CBRTL = @HAVE_DECL_CBRTL@
+HAVE_DECL_CEILF = @HAVE_DECL_CEILF@
+HAVE_DECL_CEILL = @HAVE_DECL_CEILL@
+HAVE_DECL_COPYSIGNF = @HAVE_DECL_COPYSIGNF@
+HAVE_DECL_COSL = @HAVE_DECL_COSL@
+HAVE_DECL_DIRFD = @HAVE_DECL_DIRFD@
+HAVE_DECL_ENVIRON = @HAVE_DECL_ENVIRON@
+HAVE_DECL_EXP2 = @HAVE_DECL_EXP2@
+HAVE_DECL_EXP2F = @HAVE_DECL_EXP2F@
+HAVE_DECL_EXP2L = @HAVE_DECL_EXP2L@
+HAVE_DECL_EXPL = @HAVE_DECL_EXPL@
+HAVE_DECL_EXPM1L = @HAVE_DECL_EXPM1L@
+HAVE_DECL_FCHDIR = @HAVE_DECL_FCHDIR@
+HAVE_DECL_FDATASYNC = @HAVE_DECL_FDATASYNC@
+HAVE_DECL_FDOPENDIR = @HAVE_DECL_FDOPENDIR@
+HAVE_DECL_FLOORF = @HAVE_DECL_FLOORF@
+HAVE_DECL_FLOORL = @HAVE_DECL_FLOORL@
+HAVE_DECL_FPURGE = @HAVE_DECL_FPURGE@
+HAVE_DECL_FREXPL = @HAVE_DECL_FREXPL@
+HAVE_DECL_FSEEKO = @HAVE_DECL_FSEEKO@
+HAVE_DECL_FTELLO = @HAVE_DECL_FTELLO@
+HAVE_DECL_GETDELIM = @HAVE_DECL_GETDELIM@
+HAVE_DECL_GETDOMAINNAME = @HAVE_DECL_GETDOMAINNAME@
+HAVE_DECL_GETLINE = @HAVE_DECL_GETLINE@
+HAVE_DECL_GETLOADAVG = @HAVE_DECL_GETLOADAVG@
+HAVE_DECL_GETLOGIN_R = @HAVE_DECL_GETLOGIN_R@
+HAVE_DECL_GETPAGESIZE = @HAVE_DECL_GETPAGESIZE@
+HAVE_DECL_GETUSERSHELL = @HAVE_DECL_GETUSERSHELL@
+HAVE_DECL_IMAXABS = @HAVE_DECL_IMAXABS@
+HAVE_DECL_IMAXDIV = @HAVE_DECL_IMAXDIV@
+HAVE_DECL_INET_NTOP = @HAVE_DECL_INET_NTOP@
+HAVE_DECL_INET_PTON = @HAVE_DECL_INET_PTON@
+HAVE_DECL_LDEXPL = @HAVE_DECL_LDEXPL@
+HAVE_DECL_LOCALTIME_R = @HAVE_DECL_LOCALTIME_R@
+HAVE_DECL_LOG10L = @HAVE_DECL_LOG10L@
+HAVE_DECL_LOG2 = @HAVE_DECL_LOG2@
+HAVE_DECL_LOG2F = @HAVE_DECL_LOG2F@
+HAVE_DECL_LOG2L = @HAVE_DECL_LOG2L@
+HAVE_DECL_LOGB = @HAVE_DECL_LOGB@
+HAVE_DECL_LOGL = @HAVE_DECL_LOGL@
+HAVE_DECL_MEMMEM = @HAVE_DECL_MEMMEM@
+HAVE_DECL_MEMRCHR = @HAVE_DECL_MEMRCHR@
+HAVE_DECL_OBSTACK_PRINTF = @HAVE_DECL_OBSTACK_PRINTF@
+HAVE_DECL_REMAINDER = @HAVE_DECL_REMAINDER@
+HAVE_DECL_REMAINDERL = @HAVE_DECL_REMAINDERL@
+HAVE_DECL_RINTF = @HAVE_DECL_RINTF@
+HAVE_DECL_ROUND = @HAVE_DECL_ROUND@
+HAVE_DECL_ROUNDF = @HAVE_DECL_ROUNDF@
+HAVE_DECL_ROUNDL = @HAVE_DECL_ROUNDL@
+HAVE_DECL_SETENV = @HAVE_DECL_SETENV@
+HAVE_DECL_SETHOSTNAME = @HAVE_DECL_SETHOSTNAME@
+HAVE_DECL_SINL = @HAVE_DECL_SINL@
+HAVE_DECL_SNPRINTF = @HAVE_DECL_SNPRINTF@
+HAVE_DECL_SQRTL = @HAVE_DECL_SQRTL@
+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_TANL = @HAVE_DECL_TANL@
+HAVE_DECL_TRUNC = @HAVE_DECL_TRUNC@
+HAVE_DECL_TRUNCF = @HAVE_DECL_TRUNCF@
+HAVE_DECL_TRUNCL = @HAVE_DECL_TRUNCL@
+HAVE_DECL_TTYNAME_R = @HAVE_DECL_TTYNAME_R@
+HAVE_DECL_UNSETENV = @HAVE_DECL_UNSETENV@
+HAVE_DECL_VSNPRINTF = @HAVE_DECL_VSNPRINTF@
+HAVE_DECL_WCTOB = @HAVE_DECL_WCTOB@
+HAVE_DECL_WCWIDTH = @HAVE_DECL_WCWIDTH@
+HAVE_DIRENT_H = @HAVE_DIRENT_H@
+HAVE_DPRINTF = @HAVE_DPRINTF@
+HAVE_DUP2 = @HAVE_DUP2@
+HAVE_DUP3 = @HAVE_DUP3@
+HAVE_DUPLOCALE = @HAVE_DUPLOCALE@
+HAVE_EUIDACCESS = @HAVE_EUIDACCESS@
+HAVE_EXPF = @HAVE_EXPF@
+HAVE_EXPL = @HAVE_EXPL@
+HAVE_EXPM1 = @HAVE_EXPM1@
+HAVE_EXPM1F = @HAVE_EXPM1F@
+HAVE_FABSF = @HAVE_FABSF@
+HAVE_FABSL = @HAVE_FABSL@
+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_FMA = @HAVE_FMA@
+HAVE_FMAF = @HAVE_FMAF@
+HAVE_FMAL = @HAVE_FMAL@
+HAVE_FMODF = @HAVE_FMODF@
+HAVE_FMODL = @HAVE_FMODL@
+HAVE_FREXPF = @HAVE_FREXPF@
+HAVE_FSEEKO = @HAVE_FSEEKO@
+HAVE_FSTATAT = @HAVE_FSTATAT@
+HAVE_FSYNC = @HAVE_FSYNC@
+HAVE_FTELLO = @HAVE_FTELLO@
+HAVE_FTRUNCATE = @HAVE_FTRUNCATE@
+HAVE_FUTIMENS = @HAVE_FUTIMENS@
+HAVE_GETDTABLESIZE = @HAVE_GETDTABLESIZE@
+HAVE_GETGROUPS = @HAVE_GETGROUPS@
+HAVE_GETHOSTNAME = @HAVE_GETHOSTNAME@
+HAVE_GETLOGIN = @HAVE_GETLOGIN@
+HAVE_GETOPT_H = @HAVE_GETOPT_H@
+HAVE_GETPAGESIZE = @HAVE_GETPAGESIZE@
+HAVE_GETSUBOPT = @HAVE_GETSUBOPT@
+HAVE_GETTIMEOFDAY = @HAVE_GETTIMEOFDAY@
+HAVE_GRANTPT = @HAVE_GRANTPT@
+HAVE_GROUP_MEMBER = @HAVE_GROUP_MEMBER@
+HAVE_HYPOTF = @HAVE_HYPOTF@
+HAVE_HYPOTL = @HAVE_HYPOTL@
+HAVE_ILOGB = @HAVE_ILOGB@
+HAVE_ILOGBF = @HAVE_ILOGBF@
+HAVE_ILOGBL = @HAVE_ILOGBL@
+HAVE_INTTYPES_H = @HAVE_INTTYPES_H@
+HAVE_ISBLANK = @HAVE_ISBLANK@
+HAVE_ISNAND = @HAVE_ISNAND@
+HAVE_ISNANF = @HAVE_ISNANF@
+HAVE_ISNANL = @HAVE_ISNANL@
+HAVE_ISWBLANK = @HAVE_ISWBLANK@
+HAVE_ISWCNTRL = @HAVE_ISWCNTRL@
+HAVE_LANGINFO_CODESET = @HAVE_LANGINFO_CODESET@
+HAVE_LANGINFO_ERA = @HAVE_LANGINFO_ERA@
+HAVE_LANGINFO_H = @HAVE_LANGINFO_H@
+HAVE_LANGINFO_T_FMT_AMPM = @HAVE_LANGINFO_T_FMT_AMPM@
+HAVE_LANGINFO_YESEXPR = @HAVE_LANGINFO_YESEXPR@
+HAVE_LCHMOD = @HAVE_LCHMOD@
+HAVE_LCHOWN = @HAVE_LCHOWN@
+HAVE_LDEXPF = @HAVE_LDEXPF@
+HAVE_LINK = @HAVE_LINK@
+HAVE_LINKAT = @HAVE_LINKAT@
+HAVE_LOG10F = @HAVE_LOG10F@
+HAVE_LOG10L = @HAVE_LOG10L@
+HAVE_LOG1P = @HAVE_LOG1P@
+HAVE_LOG1PF = @HAVE_LOG1PF@
+HAVE_LOG1PL = @HAVE_LOG1PL@
+HAVE_LOGBF = @HAVE_LOGBF@
+HAVE_LOGBL = @HAVE_LOGBL@
+HAVE_LOGF = @HAVE_LOGF@
+HAVE_LOGL = @HAVE_LOGL@
+HAVE_LONG_LONG_INT = @HAVE_LONG_LONG_INT@
+HAVE_LSTAT = @HAVE_LSTAT@
+HAVE_MAX_ALIGN_T = @HAVE_MAX_ALIGN_T@
+HAVE_MBRLEN = @HAVE_MBRLEN@
+HAVE_MBRTOWC = @HAVE_MBRTOWC@
+HAVE_MBSINIT = @HAVE_MBSINIT@
+HAVE_MBSLEN = @HAVE_MBSLEN@
+HAVE_MBSNRTOWCS = @HAVE_MBSNRTOWCS@
+HAVE_MBSRTOWCS = @HAVE_MBSRTOWCS@
+HAVE_MEMCHR = @HAVE_MEMCHR@
+HAVE_MEMPCPY = @HAVE_MEMPCPY@
+HAVE_MKDIRAT = @HAVE_MKDIRAT@
+HAVE_MKDTEMP = @HAVE_MKDTEMP@
+HAVE_MKFIFO = @HAVE_MKFIFO@
+HAVE_MKFIFOAT = @HAVE_MKFIFOAT@
+HAVE_MKNOD = @HAVE_MKNOD@
+HAVE_MKNODAT = @HAVE_MKNODAT@
+HAVE_MKOSTEMP = @HAVE_MKOSTEMP@
+HAVE_MKOSTEMPS = @HAVE_MKOSTEMPS@
+HAVE_MKSTEMP = @HAVE_MKSTEMP@
+HAVE_MKSTEMPS = @HAVE_MKSTEMPS@
+HAVE_MODFF = @HAVE_MODFF@
+HAVE_MODFL = @HAVE_MODFL@
+HAVE_MSVC_INVALID_PARAMETER_HANDLER = @HAVE_MSVC_INVALID_PARAMETER_HANDLER@
+HAVE_NANOSLEEP = @HAVE_NANOSLEEP@
+HAVE_NETINET_IN_H = @HAVE_NETINET_IN_H@
+HAVE_NL_LANGINFO = @HAVE_NL_LANGINFO@
+HAVE_OPENAT = @HAVE_OPENAT@
+HAVE_OPENDIR = @HAVE_OPENDIR@
+HAVE_OS_H = @HAVE_OS_H@
+HAVE_PCLOSE = @HAVE_PCLOSE@
+HAVE_PIPE = @HAVE_PIPE@
+HAVE_PIPE2 = @HAVE_PIPE2@
+HAVE_POPEN = @HAVE_POPEN@
+HAVE_POSIX_OPENPT = @HAVE_POSIX_OPENPT@
+HAVE_POSIX_SIGNALBLOCKING = @HAVE_POSIX_SIGNALBLOCKING@
+HAVE_POWF = @HAVE_POWF@
+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_RAISE = @HAVE_RAISE@
+HAVE_RANDOM = @HAVE_RANDOM@
+HAVE_RANDOM_H = @HAVE_RANDOM_H@
+HAVE_RANDOM_R = @HAVE_RANDOM_R@
+HAVE_RAWMEMCHR = @HAVE_RAWMEMCHR@
+HAVE_READDIR = @HAVE_READDIR@
+HAVE_READLINK = @HAVE_READLINK@
+HAVE_READLINKAT = @HAVE_READLINKAT@
+HAVE_REALPATH = @HAVE_REALPATH@
+HAVE_REMAINDER = @HAVE_REMAINDER@
+HAVE_REMAINDERF = @HAVE_REMAINDERF@
+HAVE_RENAMEAT = @HAVE_RENAMEAT@
+HAVE_REWINDDIR = @HAVE_REWINDDIR@
+HAVE_RINT = @HAVE_RINT@
+HAVE_RINTL = @HAVE_RINTL@
+HAVE_RPMATCH = @HAVE_RPMATCH@
+HAVE_SAME_LONG_DOUBLE_AS_DOUBLE = @HAVE_SAME_LONG_DOUBLE_AS_DOUBLE@
+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_SIGACTION = @HAVE_SIGACTION@
+HAVE_SIGHANDLER_T = @HAVE_SIGHANDLER_T@
+HAVE_SIGINFO_T = @HAVE_SIGINFO_T@
+HAVE_SIGNED_SIG_ATOMIC_T = @HAVE_SIGNED_SIG_ATOMIC_T@
+HAVE_SIGNED_WCHAR_T = @HAVE_SIGNED_WCHAR_T@
+HAVE_SIGNED_WINT_T = @HAVE_SIGNED_WINT_T@
+HAVE_SIGSET_T = @HAVE_SIGSET_T@
+HAVE_SINF = @HAVE_SINF@
+HAVE_SINHF = @HAVE_SINHF@
+HAVE_SINL = @HAVE_SINL@
+HAVE_SLEEP = @HAVE_SLEEP@
+HAVE_SQRTF = @HAVE_SQRTF@
+HAVE_SQRTL = @HAVE_SQRTL@
+HAVE_STDINT_H = @HAVE_STDINT_H@
+HAVE_STPCPY = @HAVE_STPCPY@
+HAVE_STPNCPY = @HAVE_STPNCPY@
+HAVE_STRCASECMP = @HAVE_STRCASECMP@
+HAVE_STRCASESTR = @HAVE_STRCASESTR@
+HAVE_STRCHRNUL = @HAVE_STRCHRNUL@
+HAVE_STRINGS_H = @HAVE_STRINGS_H@
+HAVE_STRPBRK = @HAVE_STRPBRK@
+HAVE_STRPTIME = @HAVE_STRPTIME@
+HAVE_STRSEP = @HAVE_STRSEP@
+HAVE_STRTOD = @HAVE_STRTOD@
+HAVE_STRTOLL = @HAVE_STRTOLL@
+HAVE_STRTOULL = @HAVE_STRTOULL@
+HAVE_STRUCT_RANDOM_DATA = @HAVE_STRUCT_RANDOM_DATA@
+HAVE_STRUCT_SIGACTION_SA_SIGACTION = @HAVE_STRUCT_SIGACTION_SA_SIGACTION@
+HAVE_STRUCT_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_STRUCT_UTSNAME = @HAVE_STRUCT_UTSNAME@
+HAVE_STRVERSCMP = @HAVE_STRVERSCMP@
+HAVE_SYMLINK = @HAVE_SYMLINK@
+HAVE_SYMLINKAT = @HAVE_SYMLINKAT@
+HAVE_SYS_BITYPES_H = @HAVE_SYS_BITYPES_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_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_SYS_UTSNAME_H = @HAVE_SYS_UTSNAME_H@
+HAVE_TANF = @HAVE_TANF@
+HAVE_TANHF = @HAVE_TANHF@
+HAVE_TANL = @HAVE_TANL@
+HAVE_TIMEGM = @HAVE_TIMEGM@
+HAVE_TIMEZONE_T = @HAVE_TIMEZONE_T@
+HAVE_TYPE_VOLATILE_SIG_ATOMIC_T = @HAVE_TYPE_VOLATILE_SIG_ATOMIC_T@
+HAVE_UNAME = @HAVE_UNAME@
+HAVE_UNISTD_H = @HAVE_UNISTD_H@
+HAVE_UNLINKAT = @HAVE_UNLINKAT@
+HAVE_UNLOCKPT = @HAVE_UNLOCKPT@
+HAVE_UNSIGNED_LONG_LONG_INT = @HAVE_UNSIGNED_LONG_LONG_INT@
+HAVE_USLEEP = @HAVE_USLEEP@
+HAVE_UTIMENSAT = @HAVE_UTIMENSAT@
+HAVE_VASPRINTF = @HAVE_VASPRINTF@
+HAVE_VDPRINTF = @HAVE_VDPRINTF@
+HAVE_WCHAR_H = @HAVE_WCHAR_H@
+HAVE_WCHAR_T = @HAVE_WCHAR_T@
+HAVE_WCPCPY = @HAVE_WCPCPY@
+HAVE_WCPNCPY = @HAVE_WCPNCPY@
+HAVE_WCRTOMB = @HAVE_WCRTOMB@
+HAVE_WCSCASECMP = @HAVE_WCSCASECMP@
+HAVE_WCSCAT = @HAVE_WCSCAT@
+HAVE_WCSCHR = @HAVE_WCSCHR@
+HAVE_WCSCMP = @HAVE_WCSCMP@
+HAVE_WCSCOLL = @HAVE_WCSCOLL@
+HAVE_WCSCPY = @HAVE_WCSCPY@
+HAVE_WCSCSPN = @HAVE_WCSCSPN@
+HAVE_WCSDUP = @HAVE_WCSDUP@
+HAVE_WCSLEN = @HAVE_WCSLEN@
+HAVE_WCSNCASECMP = @HAVE_WCSNCASECMP@
+HAVE_WCSNCAT = @HAVE_WCSNCAT@
+HAVE_WCSNCMP = @HAVE_WCSNCMP@
+HAVE_WCSNCPY = @HAVE_WCSNCPY@
+HAVE_WCSNLEN = @HAVE_WCSNLEN@
+HAVE_WCSNRTOMBS = @HAVE_WCSNRTOMBS@
+HAVE_WCSPBRK = @HAVE_WCSPBRK@
+HAVE_WCSRCHR = @HAVE_WCSRCHR@
+HAVE_WCSRTOMBS = @HAVE_WCSRTOMBS@
+HAVE_WCSSPN = @HAVE_WCSSPN@
+HAVE_WCSSTR = @HAVE_WCSSTR@
+HAVE_WCSTOK = @HAVE_WCSTOK@
+HAVE_WCSWIDTH = @HAVE_WCSWIDTH@
+HAVE_WCSXFRM = @HAVE_WCSXFRM@
+HAVE_WCTRANS_T = @HAVE_WCTRANS_T@
+HAVE_WCTYPE_H = @HAVE_WCTYPE_H@
+HAVE_WCTYPE_T = @HAVE_WCTYPE_T@
+HAVE_WINSOCK2_H = @HAVE_WINSOCK2_H@
+HAVE_WINT_T = @HAVE_WINT_T@
+HAVE_WMEMCHR = @HAVE_WMEMCHR@
+HAVE_WMEMCMP = @HAVE_WMEMCMP@
+HAVE_WMEMCPY = @HAVE_WMEMCPY@
+HAVE_WMEMMOVE = @HAVE_WMEMMOVE@
+HAVE_WMEMSET = @HAVE_WMEMSET@
+HAVE_WS2TCPIP_H = @HAVE_WS2TCPIP_H@
+HAVE_XLOCALE_H = @HAVE_XLOCALE_H@
+HAVE__BOOL = @HAVE__BOOL@
+HAVE__EXIT = @HAVE__EXIT@
+INCLUDE_NEXT = @INCLUDE_NEXT@
+INCLUDE_NEXT_AS_FIRST_DIRECTIVE = @INCLUDE_NEXT_AS_FIRST_DIRECTIVE@
+INET_PTON_LIB = @INET_PTON_LIB@
+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@
+ISFINITE_LIBM = @ISFINITE_LIBM@
+ISINF_LIBM = @ISINF_LIBM@
+LDFLAGS = @LDFLAGS@
+LIBGNULIB_LIBDEPS = @LIBGNULIB_LIBDEPS@
+LIBGNULIB_LTLIBDEPS = @LIBGNULIB_LTLIBDEPS@
+LIBICONV = @LIBICONV@
+LIBINTL = @LIBINTL@
+LIBMULTITHREAD = @LIBMULTITHREAD@
+LIBOBJS = @LIBOBJS@
+LIBPTH = @LIBPTH@
+LIBPTH_PREFIX = @LIBPTH_PREFIX@
+LIBS = @LIBS@
+LIBSOCKET = @LIBSOCKET@
+LIBTESTS_LIBDEPS = @LIBTESTS_LIBDEPS@
+LIBTHREAD = @LIBTHREAD@
+LIBUNISTRING_UNITYPES_H = @LIBUNISTRING_UNITYPES_H@
+LIBUNISTRING_UNIWIDTH_H = @LIBUNISTRING_UNIWIDTH_H@
+LIB_CLOCK_GETTIME = @LIB_CLOCK_GETTIME@
+LIB_EACCESS = @LIB_EACCESS@
+LIB_NANOSLEEP = @LIB_NANOSLEEP@
+LIB_SELECT = @LIB_SELECT@
+LIB_SELINUX = @LIB_SELINUX@
+LN_S = @LN_S@
+LOCALCHARSET_TESTS_ENVIRONMENT = @LOCALCHARSET_TESTS_ENVIRONMENT@
+LOCALE_FR = @LOCALE_FR@
+LOCALE_FR_UTF8 = @LOCALE_FR_UTF8@
+LOCALE_JA = @LOCALE_JA@
+LOCALE_TR_UTF8 = @LOCALE_TR_UTF8@
+LOCALE_ZH_CN = @LOCALE_ZH_CN@
+LTLIBICONV = @LTLIBICONV@
+LTLIBINTL = @LTLIBINTL@
+LTLIBMULTITHREAD = @LTLIBMULTITHREAD@
+LTLIBOBJS = @LTLIBOBJS@
+LTLIBPTH = @LTLIBPTH@
+LTLIBTHREAD = @LTLIBTHREAD@
+MAKEINFO = @MAKEINFO@
+MKDIR_P = @MKDIR_P@
+MKINSTALLDIRS = @MKINSTALLDIRS@
+MODF_LIBM = @MODF_LIBM@
+MSGFMT = @MSGFMT@
+MSGFMT_015 = @MSGFMT_015@
+MSGMERGE = @MSGMERGE@
+NETINET_IN_H = @NETINET_IN_H@
+NEXT_ARPA_INET_H = @NEXT_ARPA_INET_H@
+NEXT_AS_FIRST_DIRECTIVE_ARPA_INET_H = @NEXT_AS_FIRST_DIRECTIVE_ARPA_INET_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_FCNTL_H = @NEXT_AS_FIRST_DIRECTIVE_FCNTL_H@
+NEXT_AS_FIRST_DIRECTIVE_FLOAT_H = @NEXT_AS_FIRST_DIRECTIVE_FLOAT_H@
+NEXT_AS_FIRST_DIRECTIVE_GETOPT_H = @NEXT_AS_FIRST_DIRECTIVE_GETOPT_H@
+NEXT_AS_FIRST_DIRECTIVE_INTTYPES_H = @NEXT_AS_FIRST_DIRECTIVE_INTTYPES_H@
+NEXT_AS_FIRST_DIRECTIVE_LANGINFO_H = @NEXT_AS_FIRST_DIRECTIVE_LANGINFO_H@
+NEXT_AS_FIRST_DIRECTIVE_LOCALE_H = @NEXT_AS_FIRST_DIRECTIVE_LOCALE_H@
+NEXT_AS_FIRST_DIRECTIVE_MATH_H = @NEXT_AS_FIRST_DIRECTIVE_MATH_H@
+NEXT_AS_FIRST_DIRECTIVE_NETINET_IN_H = @NEXT_AS_FIRST_DIRECTIVE_NETINET_IN_H@
+NEXT_AS_FIRST_DIRECTIVE_SELINUX_SELINUX_H = @NEXT_AS_FIRST_DIRECTIVE_SELINUX_SELINUX_H@
+NEXT_AS_FIRST_DIRECTIVE_SIGNAL_H = @NEXT_AS_FIRST_DIRECTIVE_SIGNAL_H@
+NEXT_AS_FIRST_DIRECTIVE_STDARG_H = @NEXT_AS_FIRST_DIRECTIVE_STDARG_H@
+NEXT_AS_FIRST_DIRECTIVE_STDDEF_H = @NEXT_AS_FIRST_DIRECTIVE_STDDEF_H@
+NEXT_AS_FIRST_DIRECTIVE_STDINT_H = @NEXT_AS_FIRST_DIRECTIVE_STDINT_H@
+NEXT_AS_FIRST_DIRECTIVE_STDIO_H = @NEXT_AS_FIRST_DIRECTIVE_STDIO_H@
+NEXT_AS_FIRST_DIRECTIVE_STDLIB_H = @NEXT_AS_FIRST_DIRECTIVE_STDLIB_H@
+NEXT_AS_FIRST_DIRECTIVE_STRINGS_H = @NEXT_AS_FIRST_DIRECTIVE_STRINGS_H@
+NEXT_AS_FIRST_DIRECTIVE_STRING_H = @NEXT_AS_FIRST_DIRECTIVE_STRING_H@
+NEXT_AS_FIRST_DIRECTIVE_SYS_IOCTL_H = @NEXT_AS_FIRST_DIRECTIVE_SYS_IOCTL_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_SYS_UTSNAME_H = @NEXT_AS_FIRST_DIRECTIVE_SYS_UTSNAME_H@
+NEXT_AS_FIRST_DIRECTIVE_SYS_WAIT_H = @NEXT_AS_FIRST_DIRECTIVE_SYS_WAIT_H@
+NEXT_AS_FIRST_DIRECTIVE_TIME_H = @NEXT_AS_FIRST_DIRECTIVE_TIME_H@
+NEXT_AS_FIRST_DIRECTIVE_UNISTD_H = @NEXT_AS_FIRST_DIRECTIVE_UNISTD_H@
+NEXT_AS_FIRST_DIRECTIVE_WCHAR_H = @NEXT_AS_FIRST_DIRECTIVE_WCHAR_H@
+NEXT_AS_FIRST_DIRECTIVE_WCTYPE_H = @NEXT_AS_FIRST_DIRECTIVE_WCTYPE_H@
+NEXT_CTYPE_H = @NEXT_CTYPE_H@
+NEXT_DIRENT_H = @NEXT_DIRENT_H@
+NEXT_ERRNO_H = @NEXT_ERRNO_H@
+NEXT_FCNTL_H = @NEXT_FCNTL_H@
+NEXT_FLOAT_H = @NEXT_FLOAT_H@
+NEXT_GETOPT_H = @NEXT_GETOPT_H@
+NEXT_INTTYPES_H = @NEXT_INTTYPES_H@
+NEXT_LANGINFO_H = @NEXT_LANGINFO_H@
+NEXT_LOCALE_H = @NEXT_LOCALE_H@
+NEXT_MATH_H = @NEXT_MATH_H@
+NEXT_NETINET_IN_H = @NEXT_NETINET_IN_H@
+NEXT_SELINUX_SELINUX_H = @NEXT_SELINUX_SELINUX_H@
+NEXT_SIGNAL_H = @NEXT_SIGNAL_H@
+NEXT_STDARG_H = @NEXT_STDARG_H@
+NEXT_STDDEF_H = @NEXT_STDDEF_H@
+NEXT_STDINT_H = @NEXT_STDINT_H@
+NEXT_STDIO_H = @NEXT_STDIO_H@
+NEXT_STDLIB_H = @NEXT_STDLIB_H@
+NEXT_STRINGS_H = @NEXT_STRINGS_H@
+NEXT_STRING_H = @NEXT_STRING_H@
+NEXT_SYS_IOCTL_H = @NEXT_SYS_IOCTL_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_SYS_UTSNAME_H = @NEXT_SYS_UTSNAME_H@
+NEXT_SYS_WAIT_H = @NEXT_SYS_WAIT_H@
+NEXT_TIME_H = @NEXT_TIME_H@
+NEXT_UNISTD_H = @NEXT_UNISTD_H@
+NEXT_WCHAR_H = @NEXT_WCHAR_H@
+NEXT_WCTYPE_H = @NEXT_WCTYPE_H@
+OBJEXT = @OBJEXT@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+POSUB = @POSUB@
+PRAGMA_COLUMNS = @PRAGMA_COLUMNS@
+PRAGMA_SYSTEM_HEADER = @PRAGMA_SYSTEM_HEADER@
+PRIPTR_PREFIX = @PRIPTR_PREFIX@
+PRI_MACROS_BROKEN = @PRI_MACROS_BROKEN@
+PTHREAD_H_DEFINES_STRUCT_TIMESPEC = @PTHREAD_H_DEFINES_STRUCT_TIMESPEC@
+PTRDIFF_T_SUFFIX = @PTRDIFF_T_SUFFIX@
+PYTHON = @PYTHON@
+PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
+PYTHON_PLATFORM = @PYTHON_PLATFORM@
+PYTHON_PREFIX = @PYTHON_PREFIX@
+PYTHON_VERSION = @PYTHON_VERSION@
+RANLIB = @RANLIB@
+REPLACE_BTOWC = @REPLACE_BTOWC@
+REPLACE_CALLOC = @REPLACE_CALLOC@
+REPLACE_CANONICALIZE_FILE_NAME = @REPLACE_CANONICALIZE_FILE_NAME@
+REPLACE_CBRTF = @REPLACE_CBRTF@
+REPLACE_CBRTL = @REPLACE_CBRTL@
+REPLACE_CEIL = @REPLACE_CEIL@
+REPLACE_CEILF = @REPLACE_CEILF@
+REPLACE_CEILL = @REPLACE_CEILL@
+REPLACE_CHOWN = @REPLACE_CHOWN@
+REPLACE_CLOSE = @REPLACE_CLOSE@
+REPLACE_CLOSEDIR = @REPLACE_CLOSEDIR@
+REPLACE_DIRFD = @REPLACE_DIRFD@
+REPLACE_DPRINTF = @REPLACE_DPRINTF@
+REPLACE_DUP = @REPLACE_DUP@
+REPLACE_DUP2 = @REPLACE_DUP2@
+REPLACE_DUPLOCALE = @REPLACE_DUPLOCALE@
+REPLACE_EXP2 = @REPLACE_EXP2@
+REPLACE_EXP2L = @REPLACE_EXP2L@
+REPLACE_EXPM1 = @REPLACE_EXPM1@
+REPLACE_EXPM1F = @REPLACE_EXPM1F@
+REPLACE_FABSL = @REPLACE_FABSL@
+REPLACE_FCHOWNAT = @REPLACE_FCHOWNAT@
+REPLACE_FCLOSE = @REPLACE_FCLOSE@
+REPLACE_FCNTL = @REPLACE_FCNTL@
+REPLACE_FDOPEN = @REPLACE_FDOPEN@
+REPLACE_FDOPENDIR = @REPLACE_FDOPENDIR@
+REPLACE_FFLUSH = @REPLACE_FFLUSH@
+REPLACE_FLOOR = @REPLACE_FLOOR@
+REPLACE_FLOORF = @REPLACE_FLOORF@
+REPLACE_FLOORL = @REPLACE_FLOORL@
+REPLACE_FMA = @REPLACE_FMA@
+REPLACE_FMAF = @REPLACE_FMAF@
+REPLACE_FMAL = @REPLACE_FMAL@
+REPLACE_FMOD = @REPLACE_FMOD@
+REPLACE_FMODF = @REPLACE_FMODF@
+REPLACE_FMODL = @REPLACE_FMODL@
+REPLACE_FOPEN = @REPLACE_FOPEN@
+REPLACE_FPRINTF = @REPLACE_FPRINTF@
+REPLACE_FPURGE = @REPLACE_FPURGE@
+REPLACE_FREOPEN = @REPLACE_FREOPEN@
+REPLACE_FREXP = @REPLACE_FREXP@
+REPLACE_FREXPF = @REPLACE_FREXPF@
+REPLACE_FREXPL = @REPLACE_FREXPL@
+REPLACE_FSEEK = @REPLACE_FSEEK@
+REPLACE_FSEEKO = @REPLACE_FSEEKO@
+REPLACE_FSTAT = @REPLACE_FSTAT@
+REPLACE_FSTATAT = @REPLACE_FSTATAT@
+REPLACE_FTELL = @REPLACE_FTELL@
+REPLACE_FTELLO = @REPLACE_FTELLO@
+REPLACE_FTRUNCATE = @REPLACE_FTRUNCATE@
+REPLACE_FUTIMENS = @REPLACE_FUTIMENS@
+REPLACE_GETCWD = @REPLACE_GETCWD@
+REPLACE_GETDELIM = @REPLACE_GETDELIM@
+REPLACE_GETDOMAINNAME = @REPLACE_GETDOMAINNAME@
+REPLACE_GETDTABLESIZE = @REPLACE_GETDTABLESIZE@
+REPLACE_GETGROUPS = @REPLACE_GETGROUPS@
+REPLACE_GETLINE = @REPLACE_GETLINE@
+REPLACE_GETLOGIN_R = @REPLACE_GETLOGIN_R@
+REPLACE_GETPAGESIZE = @REPLACE_GETPAGESIZE@
+REPLACE_GETTIMEOFDAY = @REPLACE_GETTIMEOFDAY@
+REPLACE_GMTIME = @REPLACE_GMTIME@
+REPLACE_HUGE_VAL = @REPLACE_HUGE_VAL@
+REPLACE_HYPOT = @REPLACE_HYPOT@
+REPLACE_HYPOTF = @REPLACE_HYPOTF@
+REPLACE_HYPOTL = @REPLACE_HYPOTL@
+REPLACE_ILOGB = @REPLACE_ILOGB@
+REPLACE_ILOGBF = @REPLACE_ILOGBF@
+REPLACE_INET_NTOP = @REPLACE_INET_NTOP@
+REPLACE_INET_PTON = @REPLACE_INET_PTON@
+REPLACE_IOCTL = @REPLACE_IOCTL@
+REPLACE_ISATTY = @REPLACE_ISATTY@
+REPLACE_ISFINITE = @REPLACE_ISFINITE@
+REPLACE_ISINF = @REPLACE_ISINF@
+REPLACE_ISNAN = @REPLACE_ISNAN@
+REPLACE_ISWBLANK = @REPLACE_ISWBLANK@
+REPLACE_ISWCNTRL = @REPLACE_ISWCNTRL@
+REPLACE_ITOLD = @REPLACE_ITOLD@
+REPLACE_LCHOWN = @REPLACE_LCHOWN@
+REPLACE_LDEXPL = @REPLACE_LDEXPL@
+REPLACE_LINK = @REPLACE_LINK@
+REPLACE_LINKAT = @REPLACE_LINKAT@
+REPLACE_LOCALECONV = @REPLACE_LOCALECONV@
+REPLACE_LOCALTIME = @REPLACE_LOCALTIME@
+REPLACE_LOCALTIME_R = @REPLACE_LOCALTIME_R@
+REPLACE_LOG = @REPLACE_LOG@
+REPLACE_LOG10 = @REPLACE_LOG10@
+REPLACE_LOG10F = @REPLACE_LOG10F@
+REPLACE_LOG10L = @REPLACE_LOG10L@
+REPLACE_LOG1P = @REPLACE_LOG1P@
+REPLACE_LOG1PF = @REPLACE_LOG1PF@
+REPLACE_LOG1PL = @REPLACE_LOG1PL@
+REPLACE_LOG2 = @REPLACE_LOG2@
+REPLACE_LOG2F = @REPLACE_LOG2F@
+REPLACE_LOG2L = @REPLACE_LOG2L@
+REPLACE_LOGB = @REPLACE_LOGB@
+REPLACE_LOGBF = @REPLACE_LOGBF@
+REPLACE_LOGBL = @REPLACE_LOGBL@
+REPLACE_LOGF = @REPLACE_LOGF@
+REPLACE_LOGL = @REPLACE_LOGL@
+REPLACE_LSEEK = @REPLACE_LSEEK@
+REPLACE_LSTAT = @REPLACE_LSTAT@
+REPLACE_MALLOC = @REPLACE_MALLOC@
+REPLACE_MBRLEN = @REPLACE_MBRLEN@
+REPLACE_MBRTOWC = @REPLACE_MBRTOWC@
+REPLACE_MBSINIT = @REPLACE_MBSINIT@
+REPLACE_MBSNRTOWCS = @REPLACE_MBSNRTOWCS@
+REPLACE_MBSRTOWCS = @REPLACE_MBSRTOWCS@
+REPLACE_MBSTATE_T = @REPLACE_MBSTATE_T@
+REPLACE_MBTOWC = @REPLACE_MBTOWC@
+REPLACE_MEMCHR = @REPLACE_MEMCHR@
+REPLACE_MEMMEM = @REPLACE_MEMMEM@
+REPLACE_MKDIR = @REPLACE_MKDIR@
+REPLACE_MKFIFO = @REPLACE_MKFIFO@
+REPLACE_MKNOD = @REPLACE_MKNOD@
+REPLACE_MKSTEMP = @REPLACE_MKSTEMP@
+REPLACE_MKTIME = @REPLACE_MKTIME@
+REPLACE_MODF = @REPLACE_MODF@
+REPLACE_MODFF = @REPLACE_MODFF@
+REPLACE_MODFL = @REPLACE_MODFL@
+REPLACE_NAN = @REPLACE_NAN@
+REPLACE_NANOSLEEP = @REPLACE_NANOSLEEP@
+REPLACE_NL_LANGINFO = @REPLACE_NL_LANGINFO@
+REPLACE_NULL = @REPLACE_NULL@
+REPLACE_OBSTACK_PRINTF = @REPLACE_OBSTACK_PRINTF@
+REPLACE_OPEN = @REPLACE_OPEN@
+REPLACE_OPENAT = @REPLACE_OPENAT@
+REPLACE_OPENDIR = @REPLACE_OPENDIR@
+REPLACE_PERROR = @REPLACE_PERROR@
+REPLACE_POPEN = @REPLACE_POPEN@
+REPLACE_PREAD = @REPLACE_PREAD@
+REPLACE_PRINTF = @REPLACE_PRINTF@
+REPLACE_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_R = @REPLACE_RANDOM_R@
+REPLACE_READ = @REPLACE_READ@
+REPLACE_READLINK = @REPLACE_READLINK@
+REPLACE_READLINKAT = @REPLACE_READLINKAT@
+REPLACE_REALLOC = @REPLACE_REALLOC@
+REPLACE_REALPATH = @REPLACE_REALPATH@
+REPLACE_REMAINDER = @REPLACE_REMAINDER@
+REPLACE_REMAINDERF = @REPLACE_REMAINDERF@
+REPLACE_REMAINDERL = @REPLACE_REMAINDERL@
+REPLACE_REMOVE = @REPLACE_REMOVE@
+REPLACE_RENAME = @REPLACE_RENAME@
+REPLACE_RENAMEAT = @REPLACE_RENAMEAT@
+REPLACE_RMDIR = @REPLACE_RMDIR@
+REPLACE_ROUND = @REPLACE_ROUND@
+REPLACE_ROUNDF = @REPLACE_ROUNDF@
+REPLACE_ROUNDL = @REPLACE_ROUNDL@
+REPLACE_SELECT = @REPLACE_SELECT@
+REPLACE_SETENV = @REPLACE_SETENV@
+REPLACE_SETLOCALE = @REPLACE_SETLOCALE@
+REPLACE_SIGNBIT = @REPLACE_SIGNBIT@
+REPLACE_SIGNBIT_USING_GCC = @REPLACE_SIGNBIT_USING_GCC@
+REPLACE_SLEEP = @REPLACE_SLEEP@
+REPLACE_SNPRINTF = @REPLACE_SNPRINTF@
+REPLACE_SPRINTF = @REPLACE_SPRINTF@
+REPLACE_SQRTL = @REPLACE_SQRTL@
+REPLACE_STAT = @REPLACE_STAT@
+REPLACE_STDIO_READ_FUNCS = @REPLACE_STDIO_READ_FUNCS@
+REPLACE_STDIO_WRITE_FUNCS = @REPLACE_STDIO_WRITE_FUNCS@
+REPLACE_STPNCPY = @REPLACE_STPNCPY@
+REPLACE_STRCASESTR = @REPLACE_STRCASESTR@
+REPLACE_STRCHRNUL = @REPLACE_STRCHRNUL@
+REPLACE_STRDUP = @REPLACE_STRDUP@
+REPLACE_STRERROR = @REPLACE_STRERROR@
+REPLACE_STRERROR_R = @REPLACE_STRERROR_R@
+REPLACE_STRNCAT = @REPLACE_STRNCAT@
+REPLACE_STRNDUP = @REPLACE_STRNDUP@
+REPLACE_STRNLEN = @REPLACE_STRNLEN@
+REPLACE_STRSIGNAL = @REPLACE_STRSIGNAL@
+REPLACE_STRSTR = @REPLACE_STRSTR@
+REPLACE_STRTOD = @REPLACE_STRTOD@
+REPLACE_STRTOIMAX = @REPLACE_STRTOIMAX@
+REPLACE_STRTOK_R = @REPLACE_STRTOK_R@
+REPLACE_STRTOUMAX = @REPLACE_STRTOUMAX@
+REPLACE_STRUCT_LCONV = @REPLACE_STRUCT_LCONV@
+REPLACE_STRUCT_TIMEVAL = @REPLACE_STRUCT_TIMEVAL@
+REPLACE_SYMLINK = @REPLACE_SYMLINK@
+REPLACE_SYMLINKAT = @REPLACE_SYMLINKAT@
+REPLACE_TIMEGM = @REPLACE_TIMEGM@
+REPLACE_TMPFILE = @REPLACE_TMPFILE@
+REPLACE_TOWLOWER = @REPLACE_TOWLOWER@
+REPLACE_TRUNC = @REPLACE_TRUNC@
+REPLACE_TRUNCF = @REPLACE_TRUNCF@
+REPLACE_TRUNCL = @REPLACE_TRUNCL@
+REPLACE_TTYNAME_R = @REPLACE_TTYNAME_R@
+REPLACE_UNLINK = @REPLACE_UNLINK@
+REPLACE_UNLINKAT = @REPLACE_UNLINKAT@
+REPLACE_UNSETENV = @REPLACE_UNSETENV@
+REPLACE_USLEEP = @REPLACE_USLEEP@
+REPLACE_UTIMENSAT = @REPLACE_UTIMENSAT@
+REPLACE_VASPRINTF = @REPLACE_VASPRINTF@
+REPLACE_VDPRINTF = @REPLACE_VDPRINTF@
+REPLACE_VFPRINTF = @REPLACE_VFPRINTF@
+REPLACE_VPRINTF = @REPLACE_VPRINTF@
+REPLACE_VSNPRINTF = @REPLACE_VSNPRINTF@
+REPLACE_VSPRINTF = @REPLACE_VSPRINTF@
+REPLACE_WCRTOMB = @REPLACE_WCRTOMB@
+REPLACE_WCSNRTOMBS = @REPLACE_WCSNRTOMBS@
+REPLACE_WCSRTOMBS = @REPLACE_WCSRTOMBS@
+REPLACE_WCSWIDTH = @REPLACE_WCSWIDTH@
+REPLACE_WCTOB = @REPLACE_WCTOB@
+REPLACE_WCTOMB = @REPLACE_WCTOMB@
+REPLACE_WCWIDTH = @REPLACE_WCWIDTH@
+REPLACE_WRITE = @REPLACE_WRITE@
+SED = @SED@
+SELINUX_CONTEXT_H = @SELINUX_CONTEXT_H@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+SIG_ATOMIC_T_SUFFIX = @SIG_ATOMIC_T_SUFFIX@
+SIZE_T_SUFFIX = @SIZE_T_SUFFIX@
+SORT = @SORT@
+SORT_SUPPORTS_Z = @SORT_SUPPORTS_Z@
+STDALIGN_H = @STDALIGN_H@
+STDARG_H = @STDARG_H@
+STDBOOL_H = @STDBOOL_H@
+STDDEF_H = @STDDEF_H@
+STDINT_H = @STDINT_H@
+STRIP = @STRIP@
+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@
+TIME_H_DEFINES_STRUCT_TIMESPEC = @TIME_H_DEFINES_STRUCT_TIMESPEC@
+TRUNC_LIBM = @TRUNC_LIBM@
+UINT32_MAX_LT_UINTMAX_MAX = @UINT32_MAX_LT_UINTMAX_MAX@
+UINT64_MAX_EQ_ULONG_MAX = @UINT64_MAX_EQ_ULONG_MAX@
+UNDEFINE_STRTOK_R = @UNDEFINE_STRTOK_R@
+UNISTD_H_DEFINES_STRUCT_TIMESPEC = @UNISTD_H_DEFINES_STRUCT_TIMESPEC@
+UNISTD_H_HAVE_WINSOCK2_H = @UNISTD_H_HAVE_WINSOCK2_H@
+UNISTD_H_HAVE_WINSOCK2_H_AND_USE_SOCKETS = @UNISTD_H_HAVE_WINSOCK2_H_AND_USE_SOCKETS@
+USE_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@
+WINT_T_SUFFIX = @WINT_T_SUFFIX@
+XGETTEXT = @XGETTEXT@
+XGETTEXT_015 = @XGETTEXT_015@
+XGETTEXT_EXTRA_OPTIONS = @XGETTEXT_EXTRA_OPTIONS@
+YACC = @YACC@
+YFLAGS = @YFLAGS@
+YIELD_LIB = @YIELD_LIB@
+abs_aux_dir = @abs_aux_dir@
+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_RANLIB = @ac_ct_RANLIB@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+gl_LIBOBJS = @gl_LIBOBJS@
+gl_LTLIBOBJS = @gl_LTLIBOBJS@
+gltests_LIBOBJS = @gltests_LIBOBJS@
+gltests_LTLIBOBJS = @gltests_LTLIBOBJS@
+gltests_WITNESS = @gltests_WITNESS@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+lispdir = @lispdir@
+localedir = $(datadir)/locale
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+pkgpyexecdir = @pkgpyexecdir@
+pkgpythondir = @pkgpythondir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+pyexecdir = @pyexecdir@
+pythondir = @pythondir@
+runstatedir = @runstatedir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+AUTOMAKE_OPTIONS = std-options
+AM_CFLAGS = $(WARN_CFLAGS)
+noinst_LIBRARIES = libfindtools.a
+libfindtools_a_SOURCES = finddata.c fstype.c parser.c pred.c exec.c tree.c util.c sharefile.c print.c
+find_SOURCES = ftsfind.c
+oldfind_SOURCES = oldfind.c
+man_MANS = find.1
+EXTRA_DIST = defs.h sharefile.h print.h $(man_MANS)
+AM_CPPFLAGS = -I../gl/lib -I$(top_srcdir)/lib -I$(top_srcdir)/gl/lib -I../intl -DLOCALEDIR=\"$(localedir)\"
+LDADD = ./libfindtools.a ../lib/libfind.a ../gl/lib/libgnulib.a $(LIBINTL) $(LIB_CLOCK_GETTIME) $(LIB_EACCESS) $(LIB_SELINUX) $(LIB_CLOSE) $(MODF_LIBM) $(FINDLIBS) $(GETHOSTNAME_LIB) $(LIB_EACCESS)
+# gnulib advises we link against <first> because we use <second>:
+# $(GETHOSTNAME_LIB) uname
+# $(LIB_CLOCK_GETTIME) (some indirect dependency)
+# $(LIB_EACCESS) faccessat
+# $(LIB_SELINUX) selinux-h
+# $(MODF_LIBM) modf
+SUBDIRS = . testsuite
+all: all-recursive
+
+.SUFFIXES:
+.SUFFIXES: .c .o .obj
+$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnits find/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --gnits find/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+
+clean-noinstLIBRARIES:
+ -test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES)
+
+libfindtools.a: $(libfindtools_a_OBJECTS) $(libfindtools_a_DEPENDENCIES) $(EXTRA_libfindtools_a_DEPENDENCIES)
+ $(AM_V_at)-rm -f libfindtools.a
+ $(AM_V_AR)$(libfindtools_a_AR) libfindtools.a $(libfindtools_a_OBJECTS) $(libfindtools_a_LIBADD)
+ $(AM_V_at)$(RANLIB) libfindtools.a
+install-binPROGRAMS: $(bin_PROGRAMS)
+ @$(NORMAL_INSTALL)
+ @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \
+ if test -n "$$list"; then \
+ echo " $(MKDIR_P) '$(DESTDIR)$(bindir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(bindir)" || exit 1; \
+ fi; \
+ for p in $$list; do echo "$$p $$p"; done | \
+ sed 's/$(EXEEXT)$$//' | \
+ while read p p1; do if test -f $$p \
+ ; then echo "$$p"; echo "$$p"; else :; fi; \
+ done | \
+ sed -e 'p;s,.*/,,;n;h' \
+ -e 's|.*|.|' \
+ -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \
+ sed 'N;N;N;s,\n, ,g' | \
+ $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \
+ { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \
+ if ($$2 == $$4) files[d] = files[d] " " $$1; \
+ else { print "f", $$3 "/" $$4, $$1; } } \
+ END { for (d in files) print "f", d, files[d] }' | \
+ while read type dir files; do \
+ if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \
+ test -z "$$files" || { \
+ echo " $(INSTALL_PROGRAM_ENV) $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(bindir)$$dir'"; \
+ $(INSTALL_PROGRAM_ENV) $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \
+ } \
+ ; done
+
+uninstall-binPROGRAMS:
+ @$(NORMAL_UNINSTALL)
+ @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \
+ files=`for p in $$list; do echo "$$p"; done | \
+ sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \
+ -e 's/$$/$(EXEEXT)/' \
+ `; \
+ test -n "$$list" || exit 0; \
+ echo " ( cd '$(DESTDIR)$(bindir)' && rm -f" $$files ")"; \
+ cd "$(DESTDIR)$(bindir)" && rm -f $$files
+
+clean-binPROGRAMS:
+ -test -z "$(bin_PROGRAMS)" || rm -f $(bin_PROGRAMS)
+
+installcheck-binPROGRAMS: $(bin_PROGRAMS)
+ bad=0; pid=$$$$; list="$(bin_PROGRAMS)"; for p in $$list; do \
+ case ' $(AM_INSTALLCHECK_STD_OPTIONS_EXEMPT) ' in \
+ *" $$p "* | *" $(srcdir)/$$p "*) continue;; \
+ esac; \
+ f=`echo "$$p" | \
+ sed 's,^.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/'`; \
+ for opt in --help --version; do \
+ if "$(DESTDIR)$(bindir)/$$f" $$opt >c$${pid}_.out \
+ 2>c$${pid}_.err </dev/null \
+ && test -n "`cat c$${pid}_.out`" \
+ && test -z "`cat c$${pid}_.err`"; then :; \
+ else echo "$$f does not support $$opt" 1>&2; bad=1; fi; \
+ done; \
+ done; rm -f c$${pid}_.???; exit $$bad
+
+clean-checkPROGRAMS:
+ -test -z "$(check_PROGRAMS)" || rm -f $(check_PROGRAMS)
+
+find$(EXEEXT): $(find_OBJECTS) $(find_DEPENDENCIES) $(EXTRA_find_DEPENDENCIES)
+ @rm -f find$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(find_OBJECTS) $(find_LDADD) $(LIBS)
+
+oldfind$(EXEEXT): $(oldfind_OBJECTS) $(oldfind_DEPENDENCIES) $(EXTRA_oldfind_DEPENDENCIES)
+ @rm -f oldfind$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(oldfind_OBJECTS) $(oldfind_LDADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/exec.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/finddata.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fstype.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ftsfind.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/oldfind.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/parser.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pred.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/print.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sharefile.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tree.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/util.Po@am__quote@
+
+.c.o:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $<
+
+.c.obj:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
+install-man1: $(man_MANS)
+ @$(NORMAL_INSTALL)
+ @list1=''; \
+ list2='$(man_MANS)'; \
+ test -n "$(man1dir)" \
+ && test -n "`echo $$list1$$list2`" \
+ || exit 0; \
+ echo " $(MKDIR_P) '$(DESTDIR)$(man1dir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(man1dir)" || exit 1; \
+ { for i in $$list1; do echo "$$i"; done; \
+ if test -n "$$list2"; then \
+ for i in $$list2; do echo "$$i"; done \
+ | sed -n '/\.1[a-z]*$$/p'; \
+ fi; \
+ } | while read p; do \
+ if test -f $$p; then d=; else d="$(srcdir)/"; fi; \
+ echo "$$d$$p"; echo "$$p"; \
+ done | \
+ sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^1][0-9a-z]*$$,1,;x' \
+ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \
+ sed 'N;N;s,\n, ,g' | { \
+ list=; while read file base inst; do \
+ if test "$$base" = "$$inst"; then list="$$list $$file"; else \
+ echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man1dir)/$$inst'"; \
+ $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man1dir)/$$inst" || exit $$?; \
+ fi; \
+ done; \
+ for i in $$list; do echo "$$i"; done | $(am__base_list) | \
+ while read files; do \
+ test -z "$$files" || { \
+ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man1dir)'"; \
+ $(INSTALL_DATA) $$files "$(DESTDIR)$(man1dir)" || exit $$?; }; \
+ done; }
+
+uninstall-man1:
+ @$(NORMAL_UNINSTALL)
+ @list=''; test -n "$(man1dir)" || exit 0; \
+ files=`{ for i in $$list; do echo "$$i"; done; \
+ l2='$(man_MANS)'; for i in $$l2; do echo "$$i"; done | \
+ sed -n '/\.1[a-z]*$$/p'; \
+ } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^1][0-9a-z]*$$,1,;x' \
+ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \
+ dir='$(DESTDIR)$(man1dir)'; $(am__uninstall_files_from_dir)
+
+# This directory's subdirectories are mostly independent; you can cd
+# into them and run 'make' without going through this Makefile.
+# To change the values of 'make' variables: instead of editing Makefiles,
+# (1) if the variable is set in 'config.status', edit 'config.status'
+# (which will cause the Makefiles to be regenerated when you run 'make');
+# (2) otherwise, pass the desired values on the 'make' command line.
+$(am__recursive_targets):
+ @fail=; \
+ if $(am__make_keepgoing); then \
+ failcom='fail=yes'; \
+ else \
+ failcom='exit 1'; \
+ fi; \
+ dot_seen=no; \
+ target=`echo $@ | sed s/-recursive//`; \
+ case "$@" in \
+ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \
+ *) list='$(SUBDIRS)' ;; \
+ esac; \
+ for subdir in $$list; do \
+ echo "Making $$target in $$subdir"; \
+ if test "$$subdir" = "."; then \
+ dot_seen=yes; \
+ local_target="$$target-am"; \
+ else \
+ local_target="$$target"; \
+ fi; \
+ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
+ || eval $$failcom; \
+ done; \
+ if test "$$dot_seen" = "no"; then \
+ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \
+ fi; test -z "$$fail"
+
+ID: $(am__tagged_files)
+ $(am__define_uniq_tagged_files); mkid -fID $$unique
+tags: tags-recursive
+TAGS: tags
+
+tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+ set x; \
+ here=`pwd`; \
+ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \
+ include_option=--etags-include; \
+ empty_fix=.; \
+ else \
+ include_option=--include; \
+ empty_fix=; \
+ fi; \
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ if test "$$subdir" = .; then :; else \
+ test ! -f $$subdir/TAGS || \
+ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \
+ fi; \
+ done; \
+ $(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-recursive
+
+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-recursive
+
+cscopelist-am: $(am__tagged_files)
+ list='$(am__tagged_files)'; \
+ case "$(srcdir)" in \
+ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
+ *) sdir=$(subdir)/$(srcdir) ;; \
+ esac; \
+ for i in $$list; do \
+ if test -f "$$i"; then \
+ echo "$(subdir)/$$i"; \
+ else \
+ echo "$$sdir/$$i"; \
+ fi; \
+ done >> $(top_builddir)/cscope.files
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d "$(distdir)/$$file"; then \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+ else \
+ test -f "$(distdir)/$$file" \
+ || cp -p $$d/$$file "$(distdir)/$$file" \
+ || exit 1; \
+ fi; \
+ done
+ @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \
+ if test "$$subdir" = .; then :; else \
+ $(am__make_dryrun) \
+ || test -d "$(distdir)/$$subdir" \
+ || $(MKDIR_P) "$(distdir)/$$subdir" \
+ || exit 1; \
+ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \
+ $(am__relativize); \
+ new_distdir=$$reldir; \
+ dir1=$$subdir; dir2="$(top_distdir)"; \
+ $(am__relativize); \
+ new_top_distdir=$$reldir; \
+ echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \
+ echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \
+ ($(am__cd) $$subdir && \
+ $(MAKE) $(AM_MAKEFLAGS) \
+ top_distdir="$$new_top_distdir" \
+ distdir="$$new_distdir" \
+ am__remove_distdir=: \
+ am__skip_length_check=: \
+ am__skip_mode_fix=: \
+ distdir) \
+ || exit 1; \
+ fi; \
+ done
+ $(MAKE) $(AM_MAKEFLAGS) \
+ top_distdir="$(top_distdir)" distdir="$(distdir)" \
+ dist-hook
+check-am: all-am
+ $(MAKE) $(AM_MAKEFLAGS) $(check_PROGRAMS)
+check: check-recursive
+all-am: Makefile $(LIBRARIES) $(PROGRAMS) $(MANS)
+installdirs: installdirs-recursive
+installdirs-am:
+ for dir in "$(DESTDIR)$(bindir)" "$(DESTDIR)$(man1dir)"; do \
+ test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+ done
+install: install-recursive
+install-exec: install-exec-recursive
+install-data: install-data-recursive
+uninstall: uninstall-recursive
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-recursive
+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-recursive
+
+clean-am: clean-binPROGRAMS clean-checkPROGRAMS clean-generic \
+ clean-local clean-noinstLIBRARIES mostlyclean-am
+
+distclean: distclean-recursive
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+ distclean-tags
+
+dvi: dvi-recursive
+
+dvi-am:
+
+html: html-recursive
+
+html-am:
+
+info: info-recursive
+
+info-am:
+
+install-data-am: install-man
+
+install-dvi: install-dvi-recursive
+
+install-dvi-am:
+
+install-exec-am: install-binPROGRAMS
+
+install-html: install-html-recursive
+
+install-html-am:
+
+install-info: install-info-recursive
+
+install-info-am:
+
+install-man: install-man1
+
+install-pdf: install-pdf-recursive
+
+install-pdf-am:
+
+install-ps: install-ps-recursive
+
+install-ps-am:
+
+installcheck-am: installcheck-binPROGRAMS
+
+maintainer-clean: maintainer-clean-recursive
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-recursive
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic
+
+pdf: pdf-recursive
+
+pdf-am:
+
+ps: ps-recursive
+
+ps-am:
+
+uninstall-am: uninstall-binPROGRAMS uninstall-man
+
+uninstall-man: uninstall-man1
+
+.MAKE: $(am__recursive_targets) check-am install-am install-strip
+
+.PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am check \
+ check-am clean clean-binPROGRAMS clean-checkPROGRAMS \
+ clean-generic clean-local clean-noinstLIBRARIES cscopelist-am \
+ ctags ctags-am dist-hook distclean distclean-compile \
+ distclean-generic distclean-tags distdir dvi dvi-am html \
+ html-am info info-am install install-am install-binPROGRAMS \
+ 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-man1 \
+ install-pdf install-pdf-am install-ps install-ps-am \
+ install-strip installcheck installcheck-am \
+ installcheck-binPROGRAMS installdirs installdirs-am \
+ maintainer-clean maintainer-clean-generic mostlyclean \
+ mostlyclean-compile mostlyclean-generic pdf pdf-am ps ps-am \
+ tags tags-am uninstall uninstall-am uninstall-binPROGRAMS \
+ uninstall-man uninstall-man1
+
+
+dist-hook: findutils-check-manpages
+
+# Clean coverage files generated by running binaries built with
+# gcc -fprofile-arcs -ftest-coverage
+coverage-clean:
+ $(RM) *.gcno *.gcda *.gcov *.lcov
+
+clean-local: coverage-clean
+
+findutils-check-manpages:
+ $(top_srcdir)/build-aux/man-lint.sh $(srcdir) $(man_MANS)
+
+# 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/find/defs.h b/find/defs.h
new file mode 100644
index 0000000..ba0b855
--- /dev/null
+++ b/find/defs.h
@@ -0,0 +1,677 @@
+/* defs.h -- data types and declarations.
+ Copyright (C) 1990, 1991, 1992, 1993, 1994, 2000, 2004, 2005, 2006,
+ 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+
+#ifndef INC_DEFS_H
+#define INC_DEFS_H 1
+
+#if !defined ALREADY_INCLUDED_CONFIG_H
+/*
+ * Savannah bug #20128: if we include some system header and it
+ * includes some other second system header, the second system header
+ * may in fact turn out to be a file provided by gnulib. For that
+ * situation, we need to have already included <config.h> so that the
+ * Gnulib files have access to the information probed by their
+ * configure script fragments. So <config.h> should be the first
+ * thing included.
+ */
+#error "<config.h> should be #included before defs.h, and indeed before any other header"
+Please stop compiling the program now
+#endif
+
+
+#include <sys/types.h>
+
+/* XXX: some of these includes probably don't belong in a common header file */
+#include <sys/stat.h>
+#include <stdio.h> /* for FILE* */
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <time.h>
+#include <limits.h> /* for CHAR_BIT */
+#include <stdbool.h> /* for bool */
+#include <stdint.h> /* for uintmax_t */
+#include <sys/stat.h> /* S_ISUID etc. */
+#include <selinux/selinux.h>
+
+
+
+#ifndef CHAR_BIT
+# define CHAR_BIT 8
+#endif
+
+# include <inttypes.h>
+
+#include "regex.h"
+#include "timespec.h"
+#include "buildcmd.h"
+#include "quotearg.h"
+#include "sharefile.h"
+
+#ifndef ATTRIBUTE_NORETURN
+# if HAVE_ATTRIBUTE_NORETURN
+# define ATTRIBUTE_NORETURN __attribute__ ((__noreturn__))
+# else
+# define ATTRIBUTE_NORETURN /* nothing */
+# endif
+#endif
+
+int optionl_stat (const char *name, struct stat *p);
+int optionp_stat (const char *name, struct stat *p);
+int optionh_stat (const char *name, struct stat *p);
+int debug_stat (const char *file, struct stat *bufp);
+
+void set_stat_placeholders (struct stat *p);
+int get_statinfo (const char *pathname, const char *name, struct stat *p);
+
+
+#define MODE_WXUSR (S_IWUSR | S_IXUSR)
+#define MODE_R (S_IRUSR | S_IRGRP | S_IROTH)
+#define MODE_RW (S_IWUSR | S_IWGRP | S_IWOTH | MODE_R)
+#define MODE_RWX (S_IXUSR | S_IXGRP | S_IXOTH | MODE_RW)
+#define MODE_ALL (S_ISUID | S_ISGID | S_ISVTX | MODE_RWX)
+
+
+struct predicate;
+struct options;
+
+/* Pointer to a predicate function. */
+typedef bool (*PRED_FUNC)(const char *pathname, struct stat *stat_buf, struct predicate *pred_ptr);
+
+/* The number of seconds in a day. */
+#define DAYSECS 86400
+
+/* Argument structures for predicates. */
+
+enum comparison_type
+{
+ COMP_GT,
+ COMP_LT,
+ COMP_EQ
+};
+
+enum permissions_type
+{
+ PERM_AT_LEAST,
+ PERM_ANY,
+ PERM_EXACT
+};
+
+enum predicate_type
+{
+ NO_TYPE,
+ PRIMARY_TYPE,
+ UNI_OP,
+ BI_OP,
+ OPEN_PAREN,
+ CLOSE_PAREN
+};
+
+enum predicate_precedence
+{
+ NO_PREC,
+ COMMA_PREC,
+ OR_PREC,
+ AND_PREC,
+ NEGATE_PREC,
+ MAX_PREC
+};
+
+struct long_val
+{
+ enum comparison_type kind;
+ bool negative; /* Defined only when representing time_t. */
+ uintmax_t l_val;
+};
+
+struct perm_val
+{
+ enum permissions_type kind;
+ mode_t val[2];
+};
+
+/* dir_id is used to support loop detection in oldfind.c
+ */
+struct dir_id
+{
+ ino_t ino;
+ dev_t dev;
+};
+
+/* samefile_file_id is used to support the -samefile test.
+ */
+struct samefile_file_id
+{
+ ino_t ino;
+ dev_t dev;
+ int fd;
+};
+
+struct size_val
+{
+ enum comparison_type kind;
+ int blocksize;
+ uintmax_t size;
+};
+
+
+enum xval
+ {
+ XVAL_ATIME, XVAL_BIRTHTIME, XVAL_CTIME, XVAL_MTIME, XVAL_TIME
+ };
+
+struct time_val
+{
+ enum xval xval;
+ enum comparison_type kind;
+ struct timespec ts;
+};
+
+
+struct exec_val
+{
+ bool multiple; /* -exec {} \+ denotes multiple argument. */
+ struct buildcmd_control ctl;
+ struct buildcmd_state state;
+ char **replace_vec; /* Command arguments (for ";" style) */
+ int num_args;
+ bool close_stdin; /* If true, close stdin in the child. */
+ struct saved_cwd *wd_for_exec; /* What directory to perform the exec in. */
+ int last_child_status; /* Status of the most recent child. */
+};
+
+/* The format string for a -printf or -fprintf is chopped into one or
+ more `struct segment', linked together into a list.
+ Each stretch of plain text is a segment, and
+ each \c and `%' conversion is a segment. */
+
+/* Special values for the `kind' field of `struct segment'. */
+enum SegmentKind
+ {
+ KIND_PLAIN=0, /* Segment containing just plain text. */
+ KIND_STOP=1, /* \c -- stop printing and flush output. */
+ KIND_FORMAT, /* Regular format */
+ };
+
+struct segment
+{
+ enum SegmentKind segkind; /* KIND_FORMAT, KIND_PLAIN, KIND_STOP */
+ char format_char[2]; /* Format chars if kind is KIND_FORMAT */
+ char *text; /* Plain text or `%' format string. */
+ int text_len; /* Length of `text'. */
+ struct segment *next; /* Next segment for this predicate. */
+};
+
+struct format_val
+{
+ struct segment *segment; /* Linked list of segments. */
+ FILE *stream; /* Output stream to print on. */
+ const char *filename; /* We need the filename for error messages. */
+ bool dest_is_tty; /* True if the destination is a terminal. */
+ struct quoting_options *quote_opts;
+};
+
+/* Profiling information for a predicate */
+struct predicate_performance_info
+{
+ unsigned long visits;
+ unsigned long successes;
+};
+
+/* evaluation cost of a predicate */
+enum EvaluationCost
+{
+ NeedsNothing,
+ NeedsInodeNumber,
+ NeedsType,
+ NeedsStatInfo,
+ NeedsLinkName,
+ NeedsAccessInfo,
+ NeedsSyncDiskHit,
+ NeedsEventualExec,
+ NeedsImmediateExec,
+ NeedsUserInteraction,
+ NeedsUnknown,
+ NumEvaluationCosts
+};
+
+struct predicate
+{
+ /* Pointer to the function that implements this predicate. */
+ PRED_FUNC pred_func;
+
+ /* Only used for debugging, but defined unconditionally so individual
+ modules can be compiled with -DDEBUG. */
+ const char *p_name;
+
+ /* The type of this node. There are two kinds. The first is real
+ predicates ("primaries") such as -perm, -print, or -exec. The
+ other kind is operators for combining predicates. */
+ enum predicate_type p_type;
+
+ /* The precedence of this node. Only has meaning for operators. */
+ enum predicate_precedence p_prec;
+
+ /* True if this predicate node produces side effects.
+ If side_effects are produced
+ then optimization will not be performed */
+ bool side_effects;
+
+ /* True if this predicate node requires default print be turned off. */
+ bool no_default_print;
+
+ /* True if this predicate node requires a stat system call to execute. */
+ bool need_stat;
+
+ /* True if this predicate node requires knowledge of the file type. */
+ bool need_type;
+
+ /* True if this predicate node requires knowledge of the inode number. */
+ bool need_inum;
+
+ enum EvaluationCost p_cost;
+
+ /* est_success_rate is a number between 0.0 and 1.0 */
+ float est_success_rate;
+
+ /* True if this predicate should display control characters literally */
+ bool literal_control_chars;
+
+ /* True if this predicate didn't originate from the user. */
+ bool artificial;
+
+ /* The raw text of the argument of this predicate. */
+ const char *arg_text;
+
+ /* Information needed by the predicate processor.
+ Next to each member are listed the predicates that use it. */
+ union
+ {
+ const char *str; /* fstype [i]lname [i]name [i]path */
+ struct re_pattern_buffer *regex; /* regex */
+ struct exec_val exec_vec; /* exec ok */
+ struct long_val numinfo; /* gid inum links uid */
+ struct size_val size; /* size */
+ uid_t uid; /* user */
+ gid_t gid; /* group */
+ struct time_val reftime; /* newer newerXY anewer cnewer mtime atime ctime mmin amin cmin */
+ struct perm_val perm; /* perm */
+ struct samefile_file_id samefileid; /* samefile */
+ mode_t type; /* type */
+ struct format_val printf_vec; /* printf fprintf fprint ls fls print0 fprint0 print */
+ security_context_t scontext; /* security context */
+ } args;
+
+ /* The next predicate in the user input sequence,
+ which represents the order in which the user supplied the
+ predicates on the command line. */
+ struct predicate *pred_next;
+
+ /* The right and left branches from this node in the expression
+ tree, which represents the order in which the nodes should be
+ processed. */
+ struct predicate *pred_left;
+ struct predicate *pred_right;
+
+ struct predicate_performance_info perf;
+
+ const struct parser_table* parser_entry;
+};
+
+/* oldfind.c, ftsfind.c */
+bool is_fts_enabled(int *ftsoptions);
+
+/* find library function declarations. */
+
+/* find global function declarations. */
+
+/* oldfind.c */
+/* SymlinkOption represents the choice of
+ * -P, -L or -P (default) on the command line.
+ */
+enum SymlinkOption
+ {
+ SYMLINK_NEVER_DEREF, /* Option -P */
+ SYMLINK_ALWAYS_DEREF, /* Option -L */
+ SYMLINK_DEREF_ARGSONLY /* Option -H */
+ };
+extern enum SymlinkOption symlink_handling; /* defined in oldfind.c. */
+
+void set_follow_state (enum SymlinkOption opt);
+void cleanup(void);
+
+/* fstype.c */
+char *filesystem_type (const struct stat *statp, const char *path);
+char * get_mounted_filesystems (void);
+dev_t * get_mounted_devices (size_t *);
+
+
+
+enum arg_type
+ {
+ ARG_OPTION, /* regular options like -maxdepth */
+ ARG_NOOP, /* does nothing, returns true, internal use only */
+ ARG_POSITIONAL_OPTION, /* options whose position is important (-follow) */
+ ARG_TEST, /* a like -name */
+ ARG_SPECIAL_PARSE, /* complex to parse, don't eat the test name before calling parse_xx(). */
+ ARG_PUNCTUATION, /* like -o or ( */
+ ARG_ACTION /* like -print */
+ };
+
+
+struct parser_table;
+/* Pointer to a parser function. */
+typedef bool (*PARSE_FUNC)(const struct parser_table *p,
+ char *argv[], int *arg_ptr);
+struct parser_table
+{
+ enum arg_type type;
+ const char *parser_name;
+ PARSE_FUNC parser_func;
+ PRED_FUNC pred_func;
+};
+
+/* parser.c */
+const struct parser_table* find_parser (const char *search_name);
+bool parse_print (const struct parser_table*, char *argv[], int *arg_ptr);
+void pred_sanity_check (const struct predicate *predicates);
+void check_option_combinations (const struct predicate *p);
+void parse_begin_user_args (char **args, int argno, const struct predicate *last, const struct predicate *predicates);
+void parse_end_user_args (char **args, int argno, const struct predicate *last, const struct predicate *predicates);
+bool parse_openparen (const struct parser_table* entry, char *argv[], int *arg_ptr);
+bool parse_closeparen (const struct parser_table* entry, char *argv[], int *arg_ptr);
+
+/* pred.c */
+
+typedef bool PREDICATEFUNCTION(const char *pathname, struct stat *stat_buf, struct predicate *pred_ptr);
+PREDICATEFUNCTION pred_amin;
+PREDICATEFUNCTION pred_and;
+PREDICATEFUNCTION pred_anewer;
+PREDICATEFUNCTION pred_atime;
+PREDICATEFUNCTION pred_closeparen;
+PREDICATEFUNCTION pred_cmin;
+PREDICATEFUNCTION pred_cnewer;
+PREDICATEFUNCTION pred_comma;
+PREDICATEFUNCTION pred_ctime;
+PREDICATEFUNCTION pred_delete;
+PREDICATEFUNCTION pred_empty;
+PREDICATEFUNCTION pred_exec;
+PREDICATEFUNCTION pred_execdir;
+PREDICATEFUNCTION pred_executable;
+PREDICATEFUNCTION pred_false;
+PREDICATEFUNCTION pred_fls;
+PREDICATEFUNCTION pred_fprint;
+PREDICATEFUNCTION pred_fprint0;
+PREDICATEFUNCTION pred_fprintf;
+PREDICATEFUNCTION pred_fstype;
+PREDICATEFUNCTION pred_gid;
+PREDICATEFUNCTION pred_group;
+PREDICATEFUNCTION pred_ilname;
+PREDICATEFUNCTION pred_iname;
+PREDICATEFUNCTION pred_inum;
+PREDICATEFUNCTION pred_ipath;
+PREDICATEFUNCTION pred_links;
+PREDICATEFUNCTION pred_lname;
+PREDICATEFUNCTION pred_ls;
+PREDICATEFUNCTION pred_mmin;
+PREDICATEFUNCTION pred_mtime;
+PREDICATEFUNCTION pred_name;
+PREDICATEFUNCTION pred_negate;
+PREDICATEFUNCTION pred_newer;
+PREDICATEFUNCTION pred_newerXY;
+PREDICATEFUNCTION pred_nogroup;
+PREDICATEFUNCTION pred_nouser;
+PREDICATEFUNCTION pred_ok;
+PREDICATEFUNCTION pred_okdir;
+PREDICATEFUNCTION pred_openparen;
+PREDICATEFUNCTION pred_or;
+PREDICATEFUNCTION pred_path;
+PREDICATEFUNCTION pred_perm;
+PREDICATEFUNCTION pred_print;
+PREDICATEFUNCTION pred_print0;
+PREDICATEFUNCTION pred_prune;
+PREDICATEFUNCTION pred_quit;
+PREDICATEFUNCTION pred_readable;
+PREDICATEFUNCTION pred_regex;
+PREDICATEFUNCTION pred_samefile;
+PREDICATEFUNCTION pred_size;
+PREDICATEFUNCTION pred_true;
+PREDICATEFUNCTION pred_type;
+PREDICATEFUNCTION pred_uid;
+PREDICATEFUNCTION pred_used;
+PREDICATEFUNCTION pred_user;
+PREDICATEFUNCTION pred_writable;
+PREDICATEFUNCTION pred_xtype;
+PREDICATEFUNCTION pred_context;
+
+
+
+char *find_pred_name (PRED_FUNC pred_func);
+
+
+void print_predicate (FILE *fp, const struct predicate *p);
+void print_tree (FILE*, struct predicate *node, int indent);
+void print_list (FILE*, struct predicate *node);
+void print_optlist (FILE *fp, const struct predicate *node);
+void show_success_rates(const struct predicate *node);
+
+
+/* tree.c */
+bool matches_start_point(const char * glob, bool foldcase);
+struct predicate * build_expression_tree (int argc, char *argv[], int end_of_leading_options);
+struct predicate * get_eval_tree (void);
+struct predicate *get_new_pred_noarg (const struct parser_table *entry);
+struct predicate *get_new_pred (const struct parser_table *entry);
+struct predicate *get_new_pred_chk_op (const struct parser_table *entry,
+ const char *arg);
+float calculate_derived_rates (struct predicate *p);
+
+/* util.c */
+bool fd_leak_check_is_enabled (void);
+struct predicate *insert_primary (const struct parser_table *entry, const char *arg);
+struct predicate *insert_primary_noarg (const struct parser_table *entry);
+struct predicate *insert_primary_withpred (const struct parser_table *entry, PRED_FUNC fptr, const char *arg);
+void usage (FILE *fp, int status, char *msg);
+extern bool check_nofollow(void);
+void complete_pending_execs(struct predicate *p);
+void complete_pending_execdirs (void);
+const char *safely_quote_err_filename (int n, char const *arg);
+void record_initial_cwd (void);
+bool is_exec_in_local_dir(const PRED_FUNC pred_func);
+
+void fatal_target_file_error (int errno_value, const char *name) ATTRIBUTE_NORETURN;
+void fatal_nontarget_file_error (int errno_value, const char *name) ATTRIBUTE_NORETURN;
+void nonfatal_target_file_error (int errno_value, const char *name);
+void nonfatal_nontarget_file_error (int errno_value, const char *name);
+
+
+int process_leading_options (int argc, char *argv[]);
+void set_option_defaults (struct options *p);
+void error_severity (int level);
+
+#if 0
+#define apply_predicate(pathname, stat_buf_ptr, node) \
+ (*(node)->pred_func)((pathname), (stat_buf_ptr), (node))
+#else
+bool apply_predicate(const char *pathname, struct stat *stat_buf, struct predicate *p);
+#endif
+
+#define pred_is(node, fn) ( ((node)->pred_func) == (fn) )
+
+
+/* oldfind.c. */
+int get_info (const char *pathname, struct stat *p, struct predicate *pred_ptr);
+bool following_links (void);
+bool digest_mode (mode_t *mode, const char *pathname, const char *name, struct stat *pstat, bool leaf);
+bool default_prints (struct predicate *pred);
+bool looks_like_expression (const char *arg, bool leading);
+
+
+enum DebugOption
+ {
+ DebugNone = 0,
+ DebugExpressionTree = 1,
+ DebugStat = 2,
+ DebugSearch = 4,
+ DebugTreeOpt = 8,
+ DebugHelp = 16,
+ DebugExec = 32,
+ DebugSuccessRates = 64
+ };
+
+struct options
+{
+ /* If true, process directory before contents. True unless -depth given. */
+ bool do_dir_first;
+ /* If true, -depth was EXPLICITLY set (as opposed to having been turned
+ * on by -delete, for example).
+ */
+ bool explicit_depth;
+
+ /* If >=0, don't descend more than this many levels of subdirectories. */
+ int maxdepth;
+
+ /* If >=0, don't process files above this level. */
+ int mindepth;
+
+ /* If true, do not assume that files in directories with nlink == 2
+ are non-directories. */
+ bool no_leaf_check;
+
+ /* If true, don't cross filesystem boundaries. */
+ bool stay_on_filesystem;
+
+ /* If true, we ignore the problem where we find that a directory entry
+ * no longer exists by the time we get around to processing it.
+ */
+ bool ignore_readdir_race;
+
+ /* If true, pass control characters through. If false, escape them
+ * or turn them into harmless things.
+ */
+ bool literal_control_chars;
+
+ /* If true, we issue warning messages
+ */
+ bool warnings;
+
+ /* If true, avoid POSIX-incompatible behaviours
+ * (this functionality is currently incomplete
+ * and at the moment affects mainly warning messages).
+ */
+ bool posixly_correct;
+
+ struct timespec start_time; /* Time at start of execution. */
+
+ /* Either one day before now (the default), or the start of today (if -daystart is given). */
+ struct timespec cur_day_start;
+
+ /* If true, cur_day_start has been adjusted to the start of the day. */
+ bool full_days;
+
+ int output_block_size; /* Output block size. */
+
+ /* bitmask for debug options */
+ unsigned long debug_options;
+
+ enum SymlinkOption symlink_handling;
+
+
+ /* Pointer to the function used to stat files. */
+ int (*xstat) (const char *name, struct stat *statbuf);
+
+
+ /* Indicate if we can implement safely_chdir() using the O_NOFOLLOW
+ * flag to open(2).
+ */
+ bool open_nofollow_available;
+
+ /* The variety of regular expression that we support.
+ * The default is POSIX Basic Regular Expressions, but this
+ * can be changed with the positional option, -regextype.
+ */
+ int regex_options;
+
+ /* function used to get file context */
+ int (*x_getfilecon) (int, const char *, security_context_t *);
+
+ /* Optimisation level. One is the default.
+ */
+ unsigned short optimisation_level;
+
+
+ /* How should we quote filenames in error messages and so forth?
+ */
+ enum quoting_style err_quoting_style;
+};
+
+
+struct state
+{
+ /* Current depth; 0 means current path is a command line arg. */
+ int curdepth;
+
+ /* If true, we have called stat on the current path. */
+ bool have_stat;
+
+ /* If true, we know the type of the current path. */
+ bool have_type;
+ mode_t type; /* this is the actual type */
+
+ /* The file being operated on, relative to the current directory.
+ Used for stat, readlink, remove, and opendir. */
+ char *rel_pathname;
+ /* The directory fd to which rel_pathname is relative. This is relevant
+ * when we're navigating the hierarchy with fts() and using FTS_CWDFD.
+ */
+ int cwd_dir_fd;
+
+ /* Length of starting path. */
+ int starting_path_length;
+
+ /* If true, don't descend past current directory.
+ Can be set by -prune, -maxdepth, and -xdev/-mount. */
+ bool stop_at_current_level;
+
+ /* Status value to return to system. */
+ int exit_status;
+
+ /* True if there are any execdirs. This saves us a pair of fchdir()
+ * calls for every directory we leave if it is false. This is just
+ * an optimisation. Set to true if you want to be conservative.
+ */
+ bool execdirs_outstanding;
+
+ /* Shared files, opened via the interface in sharefile.h. */
+ sharefile_handle shared_files;
+
+ /* Avoid multiple error messages for the same file. */
+ bool already_issued_stat_error_msg;
+};
+
+/* exec.c */
+bool impl_pred_exec (const char *pathname, struct stat *stat_buf, struct predicate *pred_ptr);
+int launch (struct buildcmd_control *ctl, void *usercontext, int argc, char **argv);
+
+/* finddata.c */
+extern struct options options;
+extern struct state state;
+extern struct saved_cwd *initial_wd;
+
+#endif
diff --git a/find/exec.c b/find/exec.c
new file mode 100644
index 0000000..7b6ecf6
--- /dev/null
+++ b/find/exec.c
@@ -0,0 +1,390 @@
+/* exec.c -- Implementation of -exec, -execdir, -ok, -okdir.
+ Copyright (C) 1990, 1991, 1992, 1993, 1994, 2000, 2003,
+ 2004, 2005, 2006, 2007, 2008, 2009,
+ 2010 Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/* config.h must be included first. */
+#include <config.h>
+
+/* system headers. */
+#include <assert.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <signal.h>
+#include <sys/wait.h>
+
+
+/* gnulib headers */
+#include "cloexec.h"
+#include "dirname.h"
+#include "error.h"
+#include "gettext.h"
+#include "save-cwd.h"
+#include "xalloc.h"
+
+/* findutils headers */
+#include "buildcmd.h"
+#include "defs.h"
+#include "fdleak.h"
+
+#if ENABLE_NLS
+# include <libintl.h>
+# define _(Text) gettext (Text)
+#else
+# define _(Text) Text
+#endif
+#ifdef gettext_noop
+# define N_(String) gettext_noop (String)
+#else
+/* See locate.c for explanation as to why not use (String) */
+# define N_(String) String
+#endif
+
+
+/* Initialize exec->wd_for_exec.
+
+ We save in exec->wd_for_exec the directory whose path relative to
+ cwd_df is dir.
+ */
+static bool
+initialize_wd_for_exec (struct exec_val *execp, int cwd_fd, const char *dir)
+{
+ execp->wd_for_exec = xmalloc (sizeof (*execp->wd_for_exec));
+ execp->wd_for_exec->name = NULL;
+ execp->wd_for_exec->desc = openat (cwd_fd, dir, O_RDONLY);
+ if (execp->wd_for_exec->desc < 0)
+ return false;
+ set_cloexec_flag (execp->wd_for_exec->desc, true);
+ return true;
+}
+
+
+static bool
+record_exec_dir (struct exec_val *execp)
+{
+ if (!execp->state.todo)
+ {
+ /* working directory not already known, so must be a *dir variant,
+ and this must be the first arg we added. However, this may
+ be -execdir foo {} \; (i.e. not multiple). */
+ assert (!execp->state.todo);
+
+ /* Record the WD. If we're using -L or fts chooses to do so for
+ any other reason, state.cwd_dir_fd may in fact not be the
+ directory containing the target file. When this happens,
+ rel_path will contain directory components (since it is the
+ path from state.cwd_dir_fd to the target file).
+
+ We deal with this by extracting any directory part and using
+ that to adjust what goes into execp->wd_for_exec.
+ */
+ if (strchr (state.rel_pathname, '/'))
+ {
+ char *dir = mdir_name (state.rel_pathname);
+ bool result = initialize_wd_for_exec (execp, state.cwd_dir_fd, dir);
+ free (dir);
+ return result;
+ }
+ else
+ {
+ return initialize_wd_for_exec (execp, state.cwd_dir_fd, ".");
+ }
+ }
+ return true;
+}
+
+
+
+
+bool
+impl_pred_exec (const char *pathname,
+ struct stat *stat_buf,
+ struct predicate *pred_ptr)
+{
+ struct exec_val *execp = &pred_ptr->args.exec_vec;
+ char *buf = NULL;
+ const char *target;
+ bool result;
+ const bool local = is_exec_in_local_dir (pred_ptr->pred_func);
+ char *prefix;
+ size_t pfxlen;
+
+ (void) stat_buf;
+ if (local)
+ {
+ /* For -execdir/-okdir predicates, the parser did not fill in
+ the wd_for_exec member of struct exec_val. So for those
+ predicates, we do so now.
+ */
+ if (!record_exec_dir (execp))
+ {
+ error (EXIT_FAILURE, errno,
+ _("Failed to save working directory in order to "
+ "run a command on %s"),
+ safely_quote_err_filename (0, pathname));
+ /*NOTREACHED*/
+ }
+ target = buf = base_name (state.rel_pathname);
+ if ('/' == target[0])
+ {
+ /* find / execdir ls -d {} \; */
+ prefix = NULL;
+ pfxlen = 0;
+ }
+ else
+ {
+ prefix = "./";
+ pfxlen = 2u;
+ }
+ }
+ else
+ {
+ /* For the others (-exec, -ok), the parser should
+ have set wd_for_exec to initial_wd, indicating
+ that the exec should take place from find's initial
+ working directory.
+ */
+ assert (execp->wd_for_exec == initial_wd);
+ target = pathname;
+ prefix = NULL;
+ pfxlen = 0u;
+ }
+
+ if (execp->multiple)
+ {
+ /* Push the argument onto the current list.
+ * The command may or may not be run at this point,
+ * depending on the command line length limits.
+ */
+ bc_push_arg (&execp->ctl,
+ &execp->state,
+ target, strlen (target)+1,
+ prefix, pfxlen,
+ 0);
+
+ /* remember that there are pending execdirs. */
+ if (execp->state.todo)
+ state.execdirs_outstanding = true;
+
+ /* POSIX: If the primary expression is punctuated by a plus
+ * sign, the primary shall always evaluate as true
+ */
+ result = true;
+ }
+ else
+ {
+ int i;
+
+ for (i=0; i<execp->num_args; ++i)
+ {
+ bc_do_insert (&execp->ctl,
+ &execp->state,
+ execp->replace_vec[i],
+ strlen (execp->replace_vec[i]),
+ prefix, pfxlen,
+ target, strlen (target),
+ 0);
+ }
+
+ /* Actually invoke the command. */
+ bc_do_exec (&execp->ctl, &execp->state);
+ if (WIFEXITED(execp->last_child_status))
+ {
+ if (0 == WEXITSTATUS(execp->last_child_status))
+ result = true; /* The child succeeded. */
+ else
+ result = false;
+ }
+ else
+ {
+ result = false;
+ }
+ if (local)
+ free_cwd (execp->wd_for_exec);
+ }
+ if (buf)
+ {
+ assert (local);
+ free (buf);
+ }
+ return result;
+}
+
+
+
+/* 1) fork to get a child; parent remembers the child pid
+ 2) child execs the command requested
+ 3) parent waits for child; checks for proper pid of child
+
+ Possible returns:
+
+ ret errno status(h) status(l)
+
+ pid x signal# 0177 stopped
+ pid x exit arg 0 term by _exit
+ pid x 0 signal # term by signal
+ -1 EINTR parent got signal
+ -1 other some other kind of error
+
+ Return true only if the pid matches, status(l) is
+ zero, and the exit arg (status high) is 0.
+ Otherwise return false, possibly printing an error message. */
+static bool
+prep_child_for_exec (bool close_stdin, const struct saved_cwd *wd)
+{
+ bool ok = true;
+ if (close_stdin)
+ {
+ const char inputfile[] = "/dev/null";
+
+ if (close (0) < 0)
+ {
+ error (0, errno, _("Cannot close standard input"));
+ ok = false;
+ }
+ else
+ {
+ if (open (inputfile, O_RDONLY
+#if defined O_LARGEFILE
+ |O_LARGEFILE
+#endif
+ ) < 0)
+ {
+ /* This is not entirely fatal, since
+ * executing the child with a closed
+ * stdin is almost as good as executing it
+ * with its stdin attached to /dev/null.
+ */
+ error (0, errno, "%s", safely_quote_err_filename (0, inputfile));
+ /* do not set ok=false, it is OK to continue anyway. */
+ }
+ }
+ }
+
+ /* Even if DebugSearch is set, don't announce our change of
+ * directory, since we're not going to emit a subsequent
+ * announcement of a call to stat() anyway, as we're about to exec
+ * something.
+ */
+ if (0 != restore_cwd (wd))
+ {
+ error (0, errno, _("Failed to change directory%s%s"),
+ (wd->desc < 0 && wd->name) ? ": " : "",
+ (wd->desc < 0 && wd->name) ? wd->name : "");
+ ok = false;
+ }
+ return ok;
+}
+
+
+int
+launch (struct buildcmd_control *ctl, void *usercontext, int argc, char **argv)
+{
+ pid_t child_pid;
+ static int first_time = 1;
+ struct exec_val *execp = usercontext;
+
+ /* Make sure output of command doesn't get mixed with find output. */
+ fflush (stdout);
+ fflush (stderr);
+
+ /* Make sure to listen for the kids. */
+ if (first_time)
+ {
+ first_time = 0;
+ signal (SIGCHLD, SIG_DFL);
+ }
+
+ child_pid = fork ();
+ if (child_pid == -1)
+ error (EXIT_FAILURE, errno, _("cannot fork"));
+ if (child_pid == 0)
+ {
+ /* We are the child. */
+ assert (NULL != execp->wd_for_exec);
+ if (!prep_child_for_exec (execp->close_stdin, execp->wd_for_exec))
+ {
+ _exit (1);
+ }
+ else
+ {
+ if (fd_leak_check_is_enabled ())
+ {
+ complain_about_leaky_fds ();
+ }
+ }
+
+ if (bc_args_exceed_testing_limit (argv))
+ errno = E2BIG;
+ else
+ execvp (argv[0], argv);
+ /* TODO: use a pipe to pass back the errno value, like xargs does */
+ error (0, errno, "%s",
+ safely_quote_err_filename (0, argv[0]));
+ _exit (1);
+ }
+
+ while (waitpid (child_pid, &(execp->last_child_status), 0) == (pid_t) -1)
+ {
+ if (errno != EINTR)
+ {
+ error (0, errno, _("error waiting for %s"),
+ safely_quote_err_filename (0, argv[0]));
+ state.exit_status = 1;
+ return 0; /* FAIL */
+ }
+ }
+
+ if (WIFSIGNALED (execp->last_child_status))
+ {
+ error (0, 0, _("%s terminated by signal %d"),
+ quotearg_n_style (0, options.err_quoting_style, argv[0]),
+ WTERMSIG (execp->last_child_status));
+
+ if (execp->multiple)
+ {
+ /* -exec \; just returns false if the invoked command fails.
+ * -exec {} + returns true if the invoked command fails, but
+ * sets the program exit status.
+ */
+ state.exit_status = 1;
+ }
+
+ return 1; /* OK */
+ }
+
+ if (0 == WEXITSTATUS (execp->last_child_status))
+ {
+ return 1; /* OK */
+ }
+ else
+ {
+ if (execp->multiple)
+ {
+ /* -exec \; just returns false if the invoked command fails.
+ * -exec {} + returns true if the invoked command fails, but
+ * sets the program exit status.
+ */
+ state.exit_status = 1;
+ }
+ /* The child failed, but this is the exec callback. We
+ * don't want to run the child again in this case anwyay.
+ */
+ return 1; /* FAIL (but don't try again) */
+ }
+
+}
diff --git a/find/find.1 b/find/find.1
new file mode 100644
index 0000000..7b141b8
--- /dev/null
+++ b/find/find.1
@@ -0,0 +1,2220 @@
+.TH FIND 1 \" -*- nroff -*-
+.SH NAME
+find \- search for files in a directory hierarchy
+.SH SYNOPSIS
+.B find
+[\-H] [\-L] [\-P] [\-D debugopts] [\-Olevel] [starting-point...] [expression]
+.SH DESCRIPTION
+This manual page
+documents the GNU version of
+.BR find .
+GNU
+.B find
+searches the directory tree rooted at each given starting-point by
+evaluating the given expression from left to right, according to the
+rules of precedence (see section OPERATORS), until the outcome is
+known (the left hand side is false for \fIand\fR operations, true for
+\fIor\fR), at which point
+.B find
+moves on to the next file name. If no starting-point is specified,
+`.' is assumed.
+.PP
+If you are using
+.B find
+in an environment where security is important (for example if you are
+using it to search directories that are writable by other users), you
+should read the "Security Considerations" chapter of the findutils
+documentation, which is called \fBFinding Files\fP and comes with
+findutils. That document also includes a lot more detail
+and discussion than this manual page, so you may find it a more useful
+source of information.
+.SH OPTIONS
+The
+.BR \-H ,
+.B \-L
+and
+.B \-P
+options control the treatment of symbolic
+links. Command-line arguments following these are taken to be names
+of files or directories to be examined, up to the first argument that
+begins with `\-', or the argument `(' or `!'. That argument and any
+following arguments are taken to be the expression describing what is
+to be searched for. If no paths are given, the current directory is
+used. If no expression is given, the expression
+.B \-print
+is used
+(but you should probably consider using
+.B \-print0
+instead, anyway).
+.PP
+This manual page talks about `options' within the expression list.
+These options control the behaviour of
+.B find
+but are specified immediately after the last path name. The five
+`real' options
+.BR \-H ,
+.BR \-L ,
+.BR \-P ,
+.B \-D
+and
+.B \-O
+must appear before
+the first path name, if at all. A double dash
+.B \-\-
+can also be used
+to signal that any remaining arguments are not options (though
+ensuring that all start points begin with either `./' or `/' is
+generally safer if you use wildcards in the list of start points).
+.IP \-P
+Never follow symbolic links. This is the default behaviour. When
+.B find
+examines or prints information a file, and the file is a symbolic
+link, the information used shall be taken from the properties of the
+symbolic link itself.
+
+.IP \-L
+Follow symbolic links. When
+.B find
+examines or prints information about files, the information used shall
+be taken from the properties of the file to which the link points, not
+from the link itself (unless it is a broken symbolic link or
+.B find
+is unable to examine the file to which the link points). Use of this
+option implies
+.BR \-noleaf .
+If you later use the
+.B \-P
+option,
+.B \-noleaf
+will still be in effect. If
+.B \-L
+is in effect and
+.B find
+discovers a symbolic link to a subdirectory during its search,
+the subdirectory pointed to by the symbolic link will be searched.
+.IP
+When the
+.B \-L
+option is in effect, the
+.B \-type
+predicate will always
+match against the type of the file that a symbolic link points to
+rather than the link itself (unless the symbolic link is broken).
+Actions that can cause symbolic links to become broken while
+.B find
+is executing (for example
+.BR \-delete )
+can give rise to confusing behaviour.
+Using
+.B \-L
+causes the
+.B \-lname
+and
+.B \-ilname
+predicates always to return
+false.
+
+.IP \-H
+Do not follow symbolic links, except while processing the command
+line arguments. When
+.B find
+examines or prints information about files, the information used
+shall be taken from the properties of the symbolic link itself. The
+only exception to this behaviour is when a file specified on the
+command line is a symbolic link, and the link can be resolved. For
+that situation, the information used is taken from whatever the link
+points to (that is, the link is followed). The information about the
+link itself is used as a fallback if the file pointed to by the
+symbolic link cannot be examined. If
+.B \-H
+is in effect and one of the
+paths specified on the command line is a symbolic link to a directory,
+the contents of that directory will be examined (though of course
+\-maxdepth 0 would prevent this).
+.P
+If more than one of
+.BR \-H ,
+.B \-L
+and
+.B \-P
+is specified, each overrides the
+others; the last one appearing on the command line takes effect.
+Since it is the default, the
+.B \-P
+option should be considered to be in
+effect unless either
+.B \-H
+or
+.B \-L
+is specified.
+
+GNU
+.B find
+frequently stats files during the processing of the command line
+itself, before any searching has begun. These options also affect how
+those arguments are processed. Specifically, there are a number of
+tests that compare files listed on the command line against a file we
+are currently considering. In each case, the file specified on the
+command line will have been examined and some of its properties will
+have been saved. If the named file is in fact a symbolic link, and
+the
+.B \-P
+option is in effect (or if neither
+.B \-H
+nor
+.B \-L
+were specified), the information used for the comparison will be taken from
+the properties of the symbolic link. Otherwise, it will be taken from
+the properties of the file the link points to. If
+.B find
+cannot follow the link (for example because it has insufficient
+privileges or the link points to a nonexistent file) the properties of
+the link itself will be used.
+.P
+When the
+.B \-H
+or
+.B \-L options are in effect, any symbolic links listed
+as the argument of
+.B \-newer
+will be dereferenced, and the timestamp
+will be taken from the file to which the symbolic link points. The
+same consideration applies to
+.BR \-newerXY ,
+.B \-anewer
+and
+.BR \-cnewer .
+
+The
+.B \-follow
+option has a similar effect to
+.BR \-L ,
+though it takes
+effect at the point where it appears (that is, if
+.B \-L
+is not used but
+.B \-follow
+is, any symbolic links appearing after
+.B \-follow
+on the
+command line will be dereferenced, and those before it will not).
+
+.IP "\-D debugoptions"
+Print diagnostic information; this can be helpful to diagnose problems
+with why
+.B find
+is not doing what you want. The list of debug options should be comma
+separated. Compatibility of the debug options is not guaranteed
+between releases of findutils. For a complete list of valid debug
+options, see the output of
+.B find \-D
+.BR help .
+Valid debug options include
+.RS
+.IP help
+Explain the debugging options
+.IP tree
+Show the expression tree in its original and optimised form.
+.IP stat
+Print messages as files are examined with the
+.B stat
+and
+.B lstat
+system calls. The
+.B find
+program tries to minimise such calls.
+.IP opt
+Prints diagnostic information relating to the optimisation of the
+expression tree; see the \-O option.
+.IP rates
+Prints a summary indicating how often each predicate succeeded or
+failed.
+.RE
+.IP \-Olevel
+Enables query optimisation. The
+.B find
+program reorders tests to speed up execution while preserving the
+overall effect; that is, predicates with side effects are not
+reordered relative to each other. The optimisations performed at each
+optimisation level are as follows.
+.RS
+.IP 0
+Equivalent to optimisation level 1.
+.IP 1
+This is the default optimisation level and corresponds to the
+traditional behaviour. Expressions are reordered so that tests based
+only on the names of files (for example
+.B \-name
+and
+.BR \-regex )
+are performed first.
+.IP 2
+Any
+.B \-type
+or
+.B \-xtype
+tests are performed after any tests based only on the names of files,
+but before any tests that require information from the inode. On many
+modern versions of Unix, file types are returned by
+.B readdir()
+and so these predicates are faster to evaluate than predicates which
+need to stat the file first.
+If you use the
+.B \-fstype
+.I FOO
+predicate and specify a filesystem type
+.I FOO
+which is not known (that is, present in `/etc/mtab') at the time
+.B find
+starts, that predicate is equivalent to
+.BR \-false .
+.IP 3
+At this optimisation level, the full cost-based query optimiser is
+enabled. The order of tests is modified so that cheap (i.e.\& fast)
+tests are performed first and more expensive ones are performed later,
+if necessary. Within each cost band, predicates are evaluated earlier
+or later according to whether they are likely to succeed or not. For
+.BR \-o ,
+predicates which are likely to succeed are evaluated earlier, and for
+.BR \-a ,
+predicates which are likely to fail are evaluated earlier.
+.RE
+.IP
+The cost-based optimiser has a fixed idea of how likely any given test
+is to succeed. In some cases the probability takes account of the
+specific nature of the test (for example,
+.B \-type f
+is assumed to be more likely to succeed than
+.BR "\-type c" ).
+The cost-based optimiser is currently being evaluated. If it does
+not actually improve the performance of
+.BR find ,
+it will be removed again. Conversely, optimisations that prove to be
+reliable, robust and effective may be enabled at lower optimisation
+levels over time. However, the default behaviour (i.e.\& optimisation
+level 1) will not be changed in the 4.3.x release series. The
+findutils test suite runs all the tests on
+.B find
+at each optimisation level and ensures that the result is the same.
+.P
+.SH EXPRESSION
+The part of the command line after the list of starting points is the
+.IR expression .
+This is a kind of query specification describing how we match files
+and what we do with the files that were matched.
+An expression is composed of a sequence of things:
+
+.IP Tests
+Tests return a true or false value, usually on the basis of some
+property of a file we are considering. The
+.B \-empty
+test for example is true only when the current file is empty.
+
+.IP Actions
+Actions have side effects (such as printing something on the standard
+output) and return either true or false, usually based on whether or
+not they are successful. The
+.B \-print
+action for example prints the name of the current file on the standard
+output.
+
+.IP "Global options"
+Global options affect the operation of tests and actions specified on
+any part of the command line. Global options always return true. The
+.B \-depth
+option for example makes
+.B find
+traverse the file system in a depth-first order.
+
+.IP "Positional options"
+Positional optiona affect only tests or actions which follow them.
+Positional options always return true. The
+.B \-regextype
+option for example is positional, specifying the regular expression
+dialect for regulat expressions occurring later on the command line.
+
+.IP Operators
+Operators join together the other items within the expression. They
+include for example
+.B \-o
+(meaning logical OR) and
+.B \-a
+(meaning logical AND). Where an operator is missing,
+.B \-a
+is assumed.
+
+.P
+If the whole expression contains no actions other than
+.B \-prune
+or
+.BR \-print ,
+.B \-print
+is performed on all files for which the whole expression is true.
+
+The
+.B \-delete
+action also acts like an option (since it implies
+.BR \-depth ).
+
+.SS POSITIONAL OPTIONS
+Positional options always return true. They affect only tests occurring
+later on the command line.
+
+.IP \-daystart
+Measure times (for
+.BR \-amin ,
+.BR \-atime ,
+.BR \-cmin ,
+.BR \-ctime ,
+.BR \-mmin ,
+and
+.BR \-mtime )
+from the beginning of today rather than from 24 hours ago. This
+option only affects tests which appear later on the command line.
+
+.IP \-follow
+Deprecated; use the
+.B \-L
+option instead. Dereference symbolic links.
+Implies
+.BR \-noleaf .
+The
+.B \-follow
+option affects only those tests which
+appear after it on the command line. Unless the
+.B \-H
+or
+.B \-L
+option has
+been specified, the position of the
+.B \-follow
+option changes the behaviour of the
+.B \-newer
+predicate; any files listed as the argument
+of
+.B \-newer
+will be dereferenced if they are symbolic links. The same
+consideration applies to
+.BR \-newerXY ,
+.B \-anewer
+and
+.BR \-cnewer .
+Similarly, the
+.B \-type
+predicate will always match against the type of the file
+that a symbolic link points to rather than the link itself. Using
+.B \-follow
+causes the
+.B \-lname and
+.B \-ilname
+predicates always to return false.
+
+.IP "\-regextype \fItype\fR"
+Changes the regular expression syntax understood by
+.B \-regex
+and
+.B \-iregex
+tests which occur later on the command line. To see which regular
+expression types are known, use
+.B -regextype
+.BR help .
+The Texinfo documentation (see
+.B SEE
+.BR ALSO )
+explains the meaning of and
+differences between the various types of regular expression.
+
+.IP "\-warn, \-nowarn"
+Turn warning messages on or off. These warnings apply only to the
+command line usage, not to any conditions that
+.B find
+might encounter when it searches directories. The default behaviour
+corresponds to
+.B \-warn
+if standard input is a tty, and to
+.B \-nowarn
+otherwise. If a warning message relating to command-line usage is
+produced, the exit status of
+.B find
+is not affected. If the POSIXLY_CORRECT environment variable is set,
+and
+.B \-warn is also used, it is not specified which, if any, warnings will be active.
+
+.SS GLOBAL OPTIONS
+Global options always return true.
+Global options take effect even for tests which occurr earlier on the
+command line. To prevent confusion, global options should specified
+on the command-line after the list of start points, just before the
+first test, positional option or action. If you specify a global
+option in some other place,
+.B find
+will issue a warning message explaining that this can be confusing.
+
+The global options occur after the list of start points, and so are
+not the same kind of option as
+.BR \-L ,
+for example.
+
+.IP \-d
+A synonym for \-depth, for compatibility with FreeBSD, NetBSD, MacOS X and OpenBSD.
+
+.IP \-depth
+Process each directory's contents before the directory itself. The
+\-delete action also implies
+.BR \-depth .
+
+.IP "\-help, \-\-help"
+Print a summary of the command-line usage of
+.B find
+and exit.
+
+.IP \-ignore_readdir_race
+Normally, \fBfind\fR will emit an error message when it fails to stat a file.
+If you give this option and a file is deleted between the time \fBfind\fR
+reads the name of the file from the directory and the time it tries to stat
+the file, no error message will be issued. This also applies to files
+or directories whose names are given on the command line. This option takes
+effect at the time the command line is read, which means that you cannot search
+one part of the filesystem with this option on and part of it with this option
+off (if you need to do that, you will need to issue two \fBfind\fR commands
+instead, one with the option and one without it).
+
+.IP "\-maxdepth \fIlevels\fR"
+Descend at most \fIlevels\fR (a non-negative integer) levels of
+directories below the starting-points.
+.B \-maxdepth 0
+ means only apply the tests and actions to the starting-points themselves.
+
+.IP "\-mindepth \fIlevels\fR"
+Do not apply any tests or actions at levels less than \fIlevels\fR (a
+non-negative integer).
+.B \-mindepth 1
+means process all files except the starting-points.
+
+.IP \-mount
+Don't descend directories on other filesystems. An alternate name for
+.BR \-xdev ,
+for compatibility with some other versions of
+.BR find .
+
+.IP \-noignore_readdir_race
+Turns off the effect of
+.BR \-ignore_readdir_race .
+
+.IP "\-noleaf"
+Do not optimize by assuming that directories contain 2 fewer
+subdirectories than their hard link count. This option is needed when
+searching filesystems that do not follow the Unix directory-link
+convention, such as CD-ROM or MS-DOS filesystems or AFS volume mount
+points. Each directory on a normal Unix filesystem has at least 2
+hard links: its name and its `.' entry. Additionally, its
+subdirectories (if any) each have a `..\&' entry linked to that
+directory. When
+.B find
+is examining a directory, after it has statted 2 fewer subdirectories
+than the directory's link count, it knows that the rest of the entries
+in the directory are non-directories (`leaf' files in the directory
+tree). If only the files' names need to be examined, there is no need
+to stat them; this gives a significant increase in search speed.
+
+.IP "\-version, \-\-version"
+Print the \fBfind\fR version number and exit.
+
+.IP \-xdev
+Don't descend directories on other filesystems.
+
+.SS TESTS
+Some tests, for example
+.B \-newerXY
+and
+.BR -samefile ,
+allow comparison between the file currently being examined and some
+reference file specified on the command line. When these tests are
+used, the interpretation of the reference file is determined by the
+options
+.BR \-H ,
+.B \-L
+and
+.B \-P
+and any previous
+.BR \-follow ,
+but the reference file is only examined once, at the time the command
+line is parsed. If the reference file cannot be examined (for
+example, the
+.BR stat (2)
+system call fails for it), an error message is issued, and
+.B find
+exits with a nonzero status.
+.P
+Numeric arguments can be specified as
+.IP \fI+n\fP
+for greater than
+.IR n ,
+.IP \fI\-n\fP
+for less than
+.IR n ,
+.IP \fIn\fP
+for exactly
+.IR n .
+.P
+
+.IP "\-amin \fIn\fR"
+File was last accessed \fIn\fR minutes ago.
+
+.IP "\-anewer \fIfile\fR"
+File was last accessed more recently than \fIfile\fR was modified. If
+\fIfile\fR is a symbolic link and the
+.B \-H
+option or the
+.B \-L
+option is in effect, the access time of the file it points to is
+always used.
+
+.IP "\-atime \fIn\fR"
+File was last accessed \fIn\fR*24 hours ago.
+When find figures out how many 24-hour periods ago the file
+was last accessed, any fractional part is ignored, so to match
+.B \-atime
+.BR +1 ,
+a file has to have been accessed at least
+.I two
+days ago.
+
+.IP "\-cmin \fIn\fR"
+File's status was last changed \fIn\fR minutes ago.
+
+.IP "\-cnewer \fIfile\fR"
+File's status was last changed more recently than \fIfile\fR was
+modified. If \fIfile\fR is a symbolic link and the
+.B \-H
+option or the
+.B \-L
+option is in effect, the status-change time of the file it points
+to is always used.
+
+.IP "\-ctime \fIn\fR"
+File's status was last changed \fIn\fR*24 hours ago.
+See the comments for
+.B \-atime
+to understand how rounding affects the interpretation of file status
+change times.
+
+.IP \-empty
+File is empty and is either a regular file or a directory.
+
+.IP \-executable
+Matches files which are executable and directories which are
+searchable (in a file name resolution sense). This takes into account
+access control lists and other permissions artefacts which the
+.B \-perm
+test ignores. This test makes use of the
+.BR access (2)
+system call, and so can be fooled by NFS servers which do UID
+mapping (or root-squashing), since many systems implement
+.BR access (2)
+in the client's kernel and so cannot make use of the UID mapping
+information held on the server. Because this test is based only on
+the result of the
+.BR access (2)
+system call, there is no guarantee that a file for which this test
+succeeds can actually be executed.
+
+.IP \-false
+Always false.
+
+.IP "\-fstype \fItype\fR"
+File is on a filesystem of type \fItype\fR. The valid filesystem
+types vary among different versions of Unix; an incomplete list of
+filesystem types that are accepted on some version of Unix or another
+is: ufs, 4.2, 4.3, nfs, tmp, mfs, S51K, S52K. You can use
+.B \-printf
+with the %F directive to see the types of your filesystems.
+
+.IP "\-gid \fIn\fR"
+File's numeric group ID is \fIn\fR.
+
+.IP "\-group \fIgname\fR"
+File belongs to group \fIgname\fR (numeric group ID allowed).
+
+.IP "\-ilname \fIpattern\fR"
+Like
+.BR \-lname ,
+but the match is case insensitive.
+If the
+.B \-L
+option or the
+.B \-follow
+option is in effect, this test returns false unless the symbolic link
+is broken.
+
+
+.IP "\-iname \fIpattern\fR"
+Like
+.BR \-name ,
+but the match is case insensitive. For example, the
+patterns `fo*' and `F??' match the file names `Foo', `FOO', `foo',
+`fOo', etc. The pattern `*foo*` will also match a file
+called '.foobar'.
+
+.IP "\-inum \fIn\fR"
+File has inode number \fIn\fR. It is normally easier to use the
+.B \-samefile
+test instead.
+
+.IP "\-ipath \fIpattern\fR"
+Like
+.BR \-path .
+but the match is case insensitive.
+
+.IP "\-iregex \fIpattern\fR"
+Like
+.BR \-regex ,
+but the match is case insensitive.
+
+.IP "\-iwholename \fIpattern\fR"
+See \-ipath. This alternative is less portable than
+.BR \-ipath .
+
+.IP "\-links \fIn\fR"
+File has \fIn\fR links.
+
+.IP "\-lname \fIpattern\fR"
+File is a symbolic link whose contents match shell pattern
+\fIpattern\fR. The metacharacters do not treat `/' or `.' specially.
+If the
+.B \-L
+option or the
+.B \-follow
+option is in effect, this test returns false unless the symbolic link
+is broken.
+
+.IP "\-mmin \fIn\fR"
+File's data was last modified \fIn\fR minutes ago.
+
+.IP "\-mtime \fIn\fR"
+File's data was last modified \fIn\fR*24 hours ago.
+See the comments for
+.B \-atime
+to understand how rounding affects the interpretation of file
+modification times.
+
+.IP "\-name \fIpattern\fR"
+Base of file name (the path with the leading directories removed)
+matches shell pattern \fIpattern\fR. Because the leading directories
+are removed, the file names considered for a match with
+.B \-name
+will never include a slash, so `\-name a/b' will never match anything
+(you probably need to use
+.B \-path
+instead). A warning is issued if you try to do this, unless the environment variable
+POSIXLY_CORRECT is set.
+The metacharacters (`*', `?',
+and `[]') match a `.' at the start of the base name (this is a change
+in findutils-4.2.2; see section STANDARDS CONFORMANCE below). To ignore a
+directory and the files under it, use
+.BR \-prune ;
+see an example in the
+description of
+.BR \-path .
+Braces are not recognised as being
+special, despite the fact that some shells including Bash imbue braces
+with a special meaning in shell patterns. The filename matching is
+performed with the use of the
+.BR fnmatch (3)
+library function. Don't forget to enclose the pattern in quotes
+in order to protect it from expansion by the shell.
+
+.IP "\-newer \fIfile\fR"
+File was modified more recently than \fIfile\fR. If \fIfile\fR is a
+symbolic link and the
+.B \-H
+option or the
+.B \-L
+option is in effect, the
+modification time of the file it points to is always used.
+
+.IP "\-newerXY \fIreference\fR"
+Succeeds if timestamp \fIX\fR of the file being considered is newer
+than timestamp \fIY\fR of the file \fIreference\fR. The letters
+\fIX\fR and \fIY\fR can be any of the following letters:
+
+.TS
+ll
+ll
+ll
+ll
+llw(2i).
+a The access time of the file \fIreference\fR
+B The birth time of the file \fIreference\fR
+c The inode status change time of \fIreference\fR
+m The modification time of the file \fIreference\fR
+t \fIreference\fR is interpreted directly as a time
+.TE
+
+Some combinations are invalid; for example, it is invalid for
+.I X
+to be
+.IR t .
+Some combinations are not implemented on all systems; for example
+.I B
+is not supported on all systems. If an invalid or unsupported
+combination of
+.I XY
+is specified, a fatal error results. Time specifications are
+interpreted as for the argument to the
+.B \-d
+option of GNU
+.BR date .
+If you try to use the birth time of a reference file, and the birth
+time cannot be determined, a fatal error message results. If you
+specify a test which refers to the birth time of files being examined,
+this test will fail for any files where the birth time is unknown.
+
+.IP \-nogroup
+No group corresponds to file's numeric group ID.
+
+.IP \-nouser
+No user corresponds to file's numeric user ID.
+
+.IP "\-path \fIpattern\fR"
+File name matches shell pattern \fIpattern\fR. The metacharacters do
+not treat `/' or `.' specially; so, for example,
+.br
+.in +1i
+find . \-path "./sr*sc"
+.br
+.in -1i
+will print an entry for a directory called `./src/misc' (if one
+exists). To ignore a whole directory tree, use
+.B \-prune
+rather than
+checking every file in the tree. For example, to skip the
+directory `src/emacs' and all files and directories under it, and
+print the names of the other files found, do something like this:
+.br
+.in +1i
+find . \-path ./src/emacs \-prune \-o \-print
+.br
+.in -1i
+Note that the pattern match test applies to the whole file name,
+starting from one of the start points named on the command line. It
+would only make sense to use an absolute path name here if the
+relevant start point is also an absolute path. This means that this
+command will never match anything:
+.br
+.in +1i
+find bar \-path /foo/bar/myfile \-print
+.br
+.in -1i
+Find compares the
+.B \-path
+argument with the concatenation of a directory name and the base name
+of the file it's examining. Since the concatenation will never end
+with a slash,
+.B \-path
+arguments ending in a slash will match nothing (except perhaps a start
+point specified on the command line).
+The predicate
+.B \-path
+is also supported by HP-UX
+.B find
+and will be in a forthcoming version of the POSIX standard.
+
+.IP "\-perm \fImode\fR"
+File's permission bits are exactly \fImode\fR (octal or symbolic).
+Since an exact match is required, if you want to use this form for
+symbolic modes, you may have to specify a rather complex mode string.
+For example `\-perm g=w' will only match files which have mode 0020
+(that is, ones for which group write permission is the only permission
+set). It is more likely that you will want to use the `/' or `-'
+forms, for example `\-perm \-g=w', which matches any file with group
+write permission. See the
+.B EXAMPLES
+section for some illustrative examples.
+
+.IP "\-perm \-\fImode\fR"
+All of the permission bits \fImode\fR are set for the file.
+Symbolic modes are accepted in this form, and this is usually the way
+in which you would want to use them. You must specify `u', `g' or `o' if
+you use a symbolic mode. See the
+.B EXAMPLES
+section for some illustrative examples.
+
+.IP "\-perm /\fImode\fR"
+Any of the permission bits \fImode\fR are set for the file. Symbolic
+modes are accepted in this form. You must specify `u', `g' or `o' if
+you use a symbolic mode. See the
+.B EXAMPLES
+section for some illustrative examples. If no permission bits in
+.I mode
+are set, this test matches any file (the idea here is to be consistent
+with the behaviour of
+.B \-perm
+.BR \-000 ).
+
+.IP "\-perm +\fImode\fR"
+This is no longer supported (and has been deprecated since 2005). Use
+.B "\-perm /\fImode\fR"
+instead.
+
+.IP \-readable
+Matches files which are readable. This takes into account access
+control lists and other permissions artefacts which the
+.B \-perm
+test ignores. This test makes use of the
+.BR access (2)
+system call, and so can be fooled by NFS servers which do UID
+mapping (or root-squashing), since many systems implement
+.BR access (2)
+in the client's kernel and so cannot make use of the UID mapping
+information held on the server.
+
+.IP "\-regex \fIpattern\fR"
+File name matches regular expression \fIpattern\fR. This is a match
+on the whole path, not a search. For example, to match a file named
+`./fubar3', you can use the regular expression `.*bar.' or `.*b.*3',
+but not `f.*r3'. The regular expressions understood by
+.B find
+are by default Emacs Regular Expressions, but this can be
+changed with the
+.B \-regextype
+option.
+
+.IP "\-samefile \fIname\fR"
+File refers to the same inode as \fIname\fR. When
+.B \-L
+is in effect, this can include symbolic links.
+
+.IP "\-size \fIn\fR[cwbkMG]"
+File uses \fIn\fP units of space, rounding up. The following suffixes
+can be used:
+.RS
+.IP `b'
+for 512-byte blocks (this is the default if no suffix is used)
+.IP `c'
+for bytes
+.IP `w'
+for two-byte words
+.IP `k'
+for Kilobytes (units of 1024 bytes)
+.IP `M'
+for Megabytes (units of 1048576 bytes)
+.IP `G'
+for Gigabytes (units of 1073741824 bytes)
+.RE
+.IP
+The size does not count indirect blocks, but it does count blocks in
+sparse files that are not actually allocated. Bear in mind that the
+`%k' and `%b' format specifiers of
+.B \-printf
+handle sparse files
+differently. The `b' suffix always denotes 512-byte blocks and never
+1 Kilobyte blocks, which is different to the behaviour of
+.BR \-ls .
+The + and - prefixes signify greater than and less than, as usual,
+but bear in mind that the size is rounded up to the next unit (so a
+1-byte file is not matched by
+.BR "-size -1M" ).
+.IP \-true
+Always true.
+
+.IP "\-type \fIc\fR"
+File is of type \fIc\fR:
+.RS
+.IP b
+block (buffered) special
+.IP c
+character (unbuffered) special
+.IP d
+directory
+.IP p
+named pipe (FIFO)
+.IP f
+regular file
+.IP l
+symbolic link; this is never true if the
+.B \-L
+option or the
+.B \-follow
+option is in effect, unless the symbolic link is broken. If you want
+to search for symbolic links when
+.B \-L
+is in effect, use
+.BR \-xtype .
+.IP s
+socket
+.IP D
+door (Solaris)
+.RE
+.IP "\-uid \fIn\fR"
+File's numeric user ID is \fIn\fR.
+
+.IP "\-used \fIn\fR"
+File was last accessed \fIn\fR days after its status was last changed.
+
+.IP "\-user \fIuname\fR"
+File is owned by user \fIuname\fR (numeric user ID allowed).
+
+.IP "\-wholename \fIpattern\fR"
+See \-path. This alternative is less portable than
+.BR \-path .
+
+.IP "\-writable"
+Matches files which are writable. This takes into account access
+control lists and other permissions artefacts which the
+.B \-perm
+test ignores. This test makes use of the
+.BR access (2)
+system call, and so can be fooled by NFS servers which do UID
+mapping (or root-squashing), since many systems implement
+.BR access (2)
+in the client's kernel and so cannot make use of the UID mapping
+information held on the server.
+
+.IP "\-xtype \fIc\fR"
+The same as
+.B \-type
+unless the file is a symbolic link. For symbolic
+links: if the
+.B \-H
+or
+.B \-P
+option was specified, true if the file is a
+link to a file of type \fIc\fR; if the
+.B \-L
+option has been given, true
+if \fIc\fR is `l'. In other words, for symbolic links,
+.B \-xtype
+checks the type of the file that
+.B \-type
+does not check.
+.IP "\-context \fIpattern\fR"
+(SELinux only) Security context of the file matches glob \fIpattern\fR.
+
+.SS ACTIONS
+.IP "\-delete\fR"
+Delete files; true if removal succeeded. If the removal failed, an
+error message is issued.
+If
+.B \-delete
+fails,
+.BR find 's
+exit status will be nonzero
+(when it eventually exits).
+Use of
+.B \-delete
+automatically turns on the
+.RB ` \-depth '
+option.
+
+.BR Warnings :
+Don't forget that the find command line is
+evaluated as an expression, so putting
+.B \-delete
+first will make
+.B find
+try to delete everything below the starting points you specified.
+When testing a
+.B find
+command line that you later intend to use with
+.BR \-delete ,
+you should explicitly specify
+.B \-depth
+in order to avoid later surprises. Because
+.B \-delete
+implies
+.BR \-depth ,
+you cannot usefully use
+.B \-prune
+and
+.B \-delete
+together.
+
+.IP "\-exec \fIcommand\fR ;"
+Execute \fIcommand\fR; true if 0 status is returned. All following
+arguments to
+.B find
+are taken to be arguments to the command until an argument consisting
+of `;' is encountered. The string `{}' is replaced by the current
+file name being processed everywhere it occurs in the arguments to the
+command, not just in arguments where it is alone, as in some versions
+of
+.BR find .
+Both of these constructions might need to be escaped (with a `\e') or
+quoted to protect them from expansion by the shell. See the
+.B EXAMPLES
+section for examples of the use of the
+.B \-exec
+option. The specified
+command is run once for each matched file.
+The command is executed in the starting directory. There are
+unavoidable security problems surrounding use of the
+.B \-exec
+action;
+you should use the
+.B \-execdir
+option instead.
+
+.IP "\-exec \fIcommand\fR {} +"
+This variant of the
+.B \-exec
+action runs the specified command on the
+selected files, but the command line is built by appending each
+selected file name at the end; the total number of invocations of the
+command will be much less than the number of matched files. The
+command line is built in much the same way that
+.B xargs
+builds its command lines. Only one instance of `{}' is allowed within
+the command. The command is executed in the starting directory. If
+.B find
+encounters an error, this can sometimes cause an
+immediate exit, so some pending commands may not be run
+at all. This variant of
+.B \-exec
+always returns true.
+
+.IP "\-execdir \fIcommand\fR ;"
+.IP "\-execdir \fIcommand\fR {} +"
+Like
+.BR \-exec ,
+but the specified command is run from the subdirectory
+containing the matched file, which is not normally the directory in
+which you started
+.BR find .
+This a much more secure method for invoking commands, as it avoids
+race conditions during resolution of the paths to the matched files.
+As with the
+.B \-exec
+action, the `+' form of
+.B \-execdir
+will build a
+command line to process more than one matched file, but any given
+invocation of
+.I command
+will only list files that exist in the same subdirectory. If you use
+this option, you must ensure that your
+.B $PATH
+environment variable does not reference `.';
+otherwise, an attacker can run any commands they like by leaving an
+appropriately-named file in a directory in which you will run
+.BR \-execdir .
+The same applies to having entries in
+.B $PATH
+which are empty or which are not absolute directory names. If
+.B find
+encounters an error, this can sometimes cause an
+immediate exit, so some pending commands may not be run
+at all. The result of the action depends on whether the
+.B +
+or the
+.B ;
+variant is being used;
+.B \-execdir
+.I command
+.B {} +
+always returns true, while
+.B \-execdir
+.I command
+.B {} ;
+returns true only if
+.I command
+returns 0.
+
+
+.IP "\-fls \fIfile\fR"
+True; like
+.B \-ls
+but write to \fIfile\fR like
+.BR \-fprint .
+The output file is always created, even if the predicate is never
+matched.
+See the
+.B UNUSUAL FILENAMES
+section for information about how unusual characters in filenames are handled.
+
+.IP "\-fprint \fIfile\fR"
+True; print the full file name into file \fIfile\fR. If \fIfile\fR
+does not exist when \fBfind\fR is run, it is created; if it does
+exist, it is truncated. The file names `/dev/stdout' and
+`/dev/stderr' are handled specially; they refer to the standard
+output and standard error output, respectively.
+The output file is always created, even if the predicate is never matched.
+See the
+.B UNUSUAL FILENAMES
+section for information about how unusual characters in filenames are handled.
+
+.IP "\-fprint0 \fIfile\fR"
+True; like
+.B \-print0
+but write to \fIfile\fR like
+.BR \-fprint .
+The output file is always created, even if the predicate is never matched.
+See the
+.B UNUSUAL FILENAMES
+section for information about how unusual characters in filenames are handled.
+
+.IP "\-fprintf \fIfile\fR \fIformat\fR"
+True; like
+.B \-printf
+but write to \fIfile\fR like
+.BR \-fprint .
+The output file is always created, even if the predicate is never matched.
+See the
+.B UNUSUAL FILENAMES
+section for information about how unusual characters in filenames are handled.
+
+.IP \-ls
+True; list current file in
+.B ls \-dils
+format on standard output.
+The block counts are of 1K blocks, unless the environment variable
+POSIXLY_CORRECT is set, in which case 512-byte blocks are used.
+See the
+.B UNUSUAL FILENAMES
+section for information about how unusual characters in filenames are handled.
+
+.IP "\-ok \fIcommand\fR ;"
+Like
+.B \-exec
+but ask the user first. If the user agrees, run the command. Otherwise
+just return false. If the command is run, its standard input is redirected
+from
+.BR /dev/null .
+
+.IP
+The response to the prompt is matched against a pair of regular
+expressions to determine if it is an affirmative or negative
+response. This regular expression is obtained from the system if the
+`POSIXLY_CORRECT' environment variable is set, or otherwise from
+.BR find 's
+message translations. If the system has no suitable
+definition,
+.BR find 's
+own definition will be used. In either case, the interpretation of
+the regular expression itself will be affected by the environment
+variables 'LC_CTYPE' (character classes) and 'LC_COLLATE' (character
+ranges and equivalence classes).
+
+
+
+.IP "\-okdir \fIcommand\fR ;"
+Like
+.B \-execdir
+but ask the user first in the same way as for
+.BR \-ok .
+If the user does not agree, just return false.
+If the command is run, its standard input is redirected from
+.BR /dev/null .
+
+.IP \-print
+True; print the full file name on the standard output, followed by a
+newline. If you are piping the output of
+.B find
+into another program and there is the faintest possibility that the files
+which you are searching for might contain a newline, then you should
+seriously consider using the
+.B \-print0
+option instead of
+.BR \-print .
+See the
+.B UNUSUAL FILENAMES
+section for information about how unusual characters in filenames are handled.
+
+.IP \-print0
+True; print the full file name on the standard output, followed by a
+null character (instead of the newline character that
+.B \-print
+uses).
+This allows file names that contain newlines or other types of white
+space to be correctly interpreted by programs that process the
+\fBfind\fR output. This option corresponds to the
+.B \-0
+option of
+.BR xargs .
+
+.IP "\-printf \fIformat\fR"
+True; print \fIformat\fR on the standard output, interpreting `\e'
+escapes and `%' directives. Field widths and precisions can be
+specified as with the `printf' C function. Please note that many of
+the fields are printed as %s rather than %d, and this may mean that
+flags don't work as you might expect. This also means that the `\-'
+flag does work (it forces fields to be left-aligned). Unlike
+.BR \-print ,
+.B \-printf
+does not add a newline at the end of the string. The escapes
+and directives are:
+.RS
+.IP \ea
+Alarm bell.
+.IP \eb
+Backspace.
+.IP \ec
+Stop printing from this format immediately and flush the output.
+.IP \ef
+Form feed.
+.IP \en
+Newline.
+.IP \er
+Carriage return.
+.IP \et
+Horizontal tab.
+.IP \ev
+Vertical tab.
+.IP \e0
+ASCII NUL.
+.IP \e\e
+A literal backslash (`\e').
+.IP \eNNN
+The character whose ASCII code is NNN (octal).
+.PP
+A `\e' character followed by any other character is treated as an
+ordinary character, so they both are printed.
+.IP %%
+A literal percent sign.
+.IP %a
+File's last access time in the format returned by the C `ctime' function.
+.IP %A\fIk\fP
+File's last access time in the format specified by \fIk\fR, which is
+either `@' or a directive for the C `strftime' function. The possible
+values for \fIk\fR are listed below; some of them might not be
+available on all systems, due to differences in `strftime' between
+systems.
+.RS
+.IP @
+seconds since Jan.\& 1, 1970, 00:00 GMT, with fractional part.
+.PP
+Time fields:
+.IP H
+hour (00..23)
+.IP I
+hour (01..12)
+.IP k
+hour ( 0..23)
+.IP l
+hour ( 1..12)
+.IP M
+minute (00..59)
+.IP p
+locale's AM or PM
+.IP r
+time, 12-hour (hh:mm:ss [AP]M)
+.IP S
+Second (00.00 .. 61.00). There is a fractional part.
+.IP T
+time, 24-hour (hh:mm:ss)
+.IP +
+Date and time, separated by `+', for example
+`2004\-04\-28+22:22:05.0'. This is a GNU extension. The time is
+given in the current timezone (which may be affected by setting the TZ
+environment variable). The seconds field includes a fractional part.
+.IP X
+locale's time representation (H:M:S)
+.IP Z
+time zone (e.g., EDT), or nothing if no time zone is determinable
+.PP
+Date fields:
+.IP a
+locale's abbreviated weekday name (Sun..Sat)
+.IP A
+locale's full weekday name, variable length (Sunday..Saturday)
+.IP b
+locale's abbreviated month name (Jan..Dec)
+.IP B
+locale's full month name, variable length (January..December)
+.IP c
+locale's date and time (Sat Nov 04 12:02:33 EST 1989). The format is
+the same as for
+.BR ctime (3)
+and so to preserve compatibility with that format, there is no fractional part
+in the seconds field.
+.IP d
+day of month (01..31)
+.IP D
+date (mm/dd/yy)
+.IP h
+same as b
+.IP j
+day of year (001..366)
+.IP m
+month (01..12)
+.IP U
+week number of year with Sunday as first day of week (00..53)
+.IP w
+day of week (0..6)
+.IP W
+week number of year with Monday as first day of week (00..53)
+.IP x
+locale's date representation (mm/dd/yy)
+.IP y
+last two digits of year (00..99)
+.IP Y
+year (1970...)
+.RE
+.IP %b
+The amount of disk space used for this file in 512-byte blocks. Since disk
+space is allocated in multiples of the filesystem block size this is usually
+greater than %s/512, but it can also be smaller if the file is a sparse file.
+.IP %c
+File's last status change time in the format returned by the C `ctime'
+function.
+.IP %C\fIk\fP
+File's last status change time in the format specified by \fIk\fR,
+which is the same as for %A.
+.IP %d
+File's depth in the directory tree; 0 means the file is a starting-point.
+.IP %D
+The device number on which the file exists (the st_dev field of struct
+stat), in decimal.
+.IP %f
+File's name with any leading directories removed (only the last element).
+.IP %F
+Type of the filesystem the file is on; this value can be used for
+\-fstype.
+.IP %g
+File's group name, or numeric group ID if the group has no name.
+.IP %G
+File's numeric group ID.
+.IP %h
+Leading directories of file's name (all but the last element).
+If the file name contains no slashes (since it is in the current
+directory) the %h specifier expands to ".".
+.IP %H
+Starting-point under which file was found.
+.IP %i
+File's inode number (in decimal).
+.IP %k
+The amount of disk space used for this file in 1K blocks. Since disk space is
+allocated in multiples of the filesystem block size this is usually greater
+than %s/1024, but it can also be smaller if the file is a sparse file.
+.IP %l
+Object of symbolic link (empty string if file is not a symbolic link).
+.IP %m
+File's permission bits (in octal). This option uses the `traditional'
+numbers which most Unix implementations use, but if your particular
+implementation uses an unusual ordering of octal permissions bits, you
+will see a difference between the actual value of the file's mode and
+the output of %m. Normally you will want to have a leading
+zero on this number, and to do this, you should use the
+.B #
+flag (as in, for example, `%#m').
+.IP %M
+File's permissions (in symbolic form, as for
+.BR ls ).
+This directive is supported in findutils 4.2.5 and later.
+.IP %n
+Number of hard links to file.
+.IP %p
+File's name.
+.IP %P
+File's name with the name of the starting-point under which
+it was found removed.
+.IP %s
+File's size in bytes.
+.IP %S
+File's sparseness. This is calculated as (BLOCKSIZE*st_blocks /
+st_size). The exact value you will get for an ordinary file of a
+certain length is system-dependent. However, normally sparse files
+will have values less than 1.0, and files which use indirect blocks
+may have a value which is greater than 1.0. The value used for
+BLOCKSIZE is system-dependent, but is usually 512 bytes. If the file
+size is zero, the value printed is undefined. On systems which lack
+support for st_blocks, a file's sparseness is assumed to be 1.0.
+.IP %t
+File's last modification time in the format returned by the C `ctime'
+function.
+.IP %T\fIk\fP
+File's last modification time in the format specified by \fIk\fR,
+which is the same as for %A.
+.IP %u
+File's user name, or numeric user ID if the user has no name.
+.IP %U
+File's numeric user ID.
+.IP %y
+File's type (like in
+.BR "ls \-l" ),
+U=unknown type (shouldn't happen)
+.IP %Y
+File's type (like %y), plus follow symlinks: L=loop, N=nonexistent
+.IP %Z
+(SELinux only) file's security context.
+.IP "%{ %[ %("
+Reserved for future use.
+.PP
+A `%' character followed by any other character is discarded, but the
+other character is printed (don't rely on this, as further format
+characters may be introduced). A `%' at the end of the format
+argument causes undefined behaviour since there is no following
+character. In some locales, it may hide your door keys, while in
+others it may remove the final page from the novel you are reading.
+
+The %m and %d directives support the
+.B #
+,
+.B 0
+and
+.B +
+flags, but the other directives do not, even if they
+print numbers. Numeric directives that do not support these flags
+include
+.BR G ,
+.BR U ,
+.BR b ,
+.BR D ,
+.B k
+and
+.BR n .
+The `\-' format flag is supported and changes the alignment of a field
+from right-justified (which is the default) to left-justified.
+.PP
+See the
+.B UNUSUAL FILENAMES
+section for information about how unusual characters in filenames are handled.
+
+
+.RE
+.IP \-prune
+True; if the file is a directory, do not descend into it. If
+.B \-depth
+is given, false; no effect. Because
+.B \-delete
+implies
+.BR \-depth ,
+you cannot usefully use
+.B \-prune
+and
+.B \-delete
+together.
+
+.IP "\-quit"
+Exit immediately. No child processes will be left running, but no more
+paths specified on the command line will be processed. For example,
+.B find /tmp/foo /tmp/bar \-print \-quit
+will print only
+.BR /tmp/foo .
+Any command lines which have been built up with
+.B \-execdir \&...\& {} +
+will be invoked before
+.B find
+exits. The exit status may or may not be zero, depending on whether
+an error has already occurred.
+
+.SS OPERATORS
+.P
+Listed in order of decreasing precedence:
+
+.IP "( \fIexpr\fR )"
+Force precedence. Since parentheses are special to the shell, you
+will normally need to quote them. Many of the examples in this manual
+page use backslashes for this purpose: `\e(...\e)' instead of `(...)'.
+
+.IP "! \fIexpr\fR"
+True if \fIexpr\fR is false. This character will also usually need
+protection from interpretation by the shell.
+
+.IP "\-not \fIexpr\fR"
+Same as ! \fIexpr\fR, but not POSIX compliant.
+
+.IP "\fIexpr1 expr2\fR"
+Two expressions in a row are taken to be joined with an
+implied "and"; \fIexpr2\fR is not evaluated if \fIexpr1\fR is false.
+
+.IP "\fIexpr1\fR \-a \fIexpr2\fR"
+Same as \fIexpr1 expr2\fR.
+
+.IP "\fIexpr1\fR \-and \fIexpr2\fR"
+Same as \fIexpr1 expr2\fR, but not POSIX compliant.
+
+.IP "\fIexpr1\fR \-o \fIexpr2\fR"
+Or; \fIexpr2\fR is not evaluated if \fIexpr1\fR is true.
+
+.IP "\fIexpr1\fR \-or \fIexpr2\fR"
+Same as \fIexpr1\fR
+.B \-o
+\fIexpr2\fR, but not POSIX compliant.
+
+.IP "\fIexpr1\fR , \fIexpr2\fR"
+List; both \fIexpr1\fR and \fIexpr2\fR are always evaluated. The
+value of \fIexpr1\fR is discarded; the value of the list is the value
+of \fIexpr2\fR. The comma operator can be useful for searching for
+several different types of thing, but traversing the filesystem
+hierarchy only once. The
+.B \-fprintf
+action can be used to list the various matched items into several
+different output files.
+
+
+.SH UNUSUAL FILENAMES
+Many of the actions of
+.B find
+result in the printing of data which is under the control of other
+users. This includes file names, sizes, modification times and so
+forth. File names are a potential problem since they can contain any
+character except `\e0' and `/'. Unusual characters in file names can
+do unexpected and often undesirable things to your terminal (for
+example, changing the settings of your function keys on some
+terminals). Unusual characters are handled differently by various
+actions, as described below.
+
+.IP "\-print0, \-fprint0"
+Always print the exact filename, unchanged, even if the output is
+going to a terminal.
+
+.IP "\-ls, \-fls"
+Unusual characters are always escaped. White space, backslash, and
+double quote characters are printed using C-style escaping (for
+example `\ef', `\e"'). Other unusual characters are printed using an
+octal escape. Other printable characters (for
+.B \-ls
+and
+.B \-fls
+these are the characters between octal 041 and 0176) are printed as-is.
+
+.IP "\-printf, \-fprintf"
+If the output is not going to a terminal, it is printed as-is.
+Otherwise, the result depends on which directive is in use. The
+directives %D, %F, %g, %G, %H, %Y, and %y expand to values which are
+not under control of files' owners, and so are printed as-is. The
+directives %a, %b, %c, %d, %i, %k, %m, %M, %n, %s, %t, %u and %U have
+values which are under the control of files' owners but which cannot
+be used to send arbitrary data to the terminal, and so these are
+printed as-is. The directives %f, %h, %l, %p and %P are quoted. This
+quoting is performed in the same way as for GNU
+.BR ls .
+This is not the same quoting mechanism as the one used for
+.B \-ls
+and
+.BR \-fls .
+If you are able to decide what format to use for the output of
+.B find
+then it is normally better to use `\e0' as a terminator
+than to use newline, as file names can contain white space and newline
+characters. The setting of the `LC_CTYPE' environment
+variable is used to determine which characters need to be quoted.
+
+.IP "\-print, \-fprint"
+Quoting is handled in the same way as for
+.B \-printf
+and
+.BR \-fprintf .
+If you are using
+.B find
+in a script or in a situation where the matched files might have
+arbitrary names, you should consider using
+.B \-print0
+instead of
+.BR \-print .
+.P
+The
+.B \-ok
+and
+.B \-okdir
+actions print the current filename as-is. This may change in a future release.
+
+.SH "STANDARDS CONFORMANCE"
+For closest compliance to the POSIX standard, you should set the
+POSIXLY_CORRECT environment variable. The following options are
+specified in the POSIX standard (IEEE Std 1003.1, 2003 Edition):
+
+.IP \fB\-H\fR
+This option is supported.
+
+.IP \fB\-L\fR
+This option is supported.
+
+.IP \fB\-name\fR
+This option is supported, but POSIX conformance depends on the
+POSIX conformance of the system's
+.BR fnmatch (3)
+library function. As of findutils-4.2.2, shell metacharacters
+(`*', `?' or `[]' for example) will match a leading `.', because
+IEEE PASC interpretation 126 requires this. This is a change from
+previous versions of findutils.
+
+.IP \fB\-type\fR
+Supported. POSIX specifies `b', `c', `d', `l', `p', `f' and `s'.
+GNU find also supports `D', representing a Door, where the OS provides these.
+
+.IP \fB\-ok\fR
+Supported.
+Interpretation of the response is according to the "yes" and "no"
+patterns selected by setting the `LC_MESSAGES' environment variable.
+When the `POSIXLY_CORRECT' environment variable is set, these patterns
+are taken system's definition of a positive (yes) or negative (no)
+response. See the system's
+documentation for \fBnl_langinfo\fP(3), in particular YESEXPR and
+NOEXPR. When `POSIXLY_CORRECT' is not set, the patterns are instead
+taken from
+.BR find 's
+own message catalogue.
+
+.IP \fB\-newer\fR
+Supported. If the file specified is a symbolic link, it is always
+dereferenced. This is a change from previous behaviour, which used to
+take the relevant time from the symbolic link; see the HISTORY section
+below.
+
+.IP \fB\-perm\fR
+Supported. If the POSIXLY_CORRECT environment variable is not set,
+some mode arguments (for example +a+x) which are not valid in POSIX
+are supported for backward-compatibility.
+
+.IP "Other predicates"
+The predicates
+.BR \-atime ,
+.BR \-ctime ,
+.BR \-depth ,
+.BR \-group ,
+.BR \-links ,
+.BR \-mtime ,
+.BR \-nogroup ,
+.BR \-nouser ,
+.BR \-print ,
+.BR \-prune ,
+.BR \-size ,
+.BR \-user
+and
+.B \-xdev
+`\-atime',
+`\-ctime',
+`\-depth',
+`\-group',
+`\-links',
+`\-mtime',
+`\-nogroup',
+`\-nouser',
+`\-perm',
+`\-print',
+`\-prune',
+`\-size',
+`\-user' and
+`\-xdev',
+are all supported.
+
+.P
+The POSIX standard specifies parentheses `(', `)', negation `!' and the
+`and' and `or' operators (
+.BR \-a ,
+.BR \-o ).
+.P
+All other options, predicates, expressions and so forth are extensions
+beyond the POSIX standard. Many of these extensions are not unique to
+GNU find, however.
+.P
+The POSIX standard requires that
+.B find
+detects loops:
+.IP
+The
+.B find
+utility shall detect infinite loops; that is, entering a
+previously visited directory that is an ancestor of the last file
+encountered. When it detects an infinite loop, find shall write a
+diagnostic message to standard error and shall either recover its
+position in the hierarchy or terminate.
+.P
+GNU
+.B find
+complies with these requirements. The link count of
+directories which contain entries which are hard links to an ancestor
+will often be lower than they otherwise should be. This can mean that
+GNU find will sometimes optimise away the visiting of a subdirectory
+which is actually a link to an ancestor. Since
+.B find
+does not actually enter such a subdirectory, it is allowed to avoid
+emitting a diagnostic message. Although this behaviour may be
+somewhat confusing, it is unlikely that anybody actually depends on
+this behaviour. If the leaf optimisation has been turned off with
+.BR \-noleaf ,
+the directory entry will always be examined and the diagnostic message
+will be issued where it is appropriate. Symbolic links cannot be used
+to create filesystem cycles as such, but if the
+.B \-L
+option or the
+.B \-follow
+option is in use, a diagnostic message is issued when
+.B find
+encounters a loop of symbolic links. As with loops containing hard
+links, the leaf optimisation will often mean that
+.B find
+knows that it doesn't need to call
+.I stat()
+or
+.I chdir()
+on the symbolic link, so this diagnostic is frequently not necessary.
+.P
+The
+.B \-d
+option is supported for compatibility with various BSD systems,
+but you should use the POSIX-compliant option
+.B \-depth
+instead.
+.P
+The POSIXLY_CORRECT environment variable does not affect the behaviour
+of the
+.B \-regex
+or
+.B \-iregex
+tests because those tests aren't specified in the POSIX standard.
+.SH "ENVIRONMENT VARIABLES"
+
+.IP LANG
+Provides a default value for the internationalization variables that
+are unset or null.
+
+.IP LC_ALL
+If set to a non-empty string value, override the values of all the
+other internationalization variables.
+
+.IP LC_COLLATE
+The POSIX standard specifies that this variable affects the pattern
+matching to be used for the
+.B \-name
+option. GNU find uses the
+.BR fnmatch (3)
+library function, and so support for `LC_COLLATE' depends on the
+system library. This variable also affects the interpretation of
+the response to
+.BR \-ok;
+while the `LC_MESSAGES' variable selects the actual pattern used to
+interpret the response to
+.BR \-ok ,
+the interpretation of any bracket expressions in the pattern will be
+affected by `LC_COLLATE'.
+
+.IP LC_CTYPE
+This variable affects the treatment of character classes used in
+regular expressions and also with
+the
+.B \-name
+test, if the system's
+.BR fnmatch (3)
+library function supports this. This variable also affects the
+interpretation of any character classes in the regular expressions
+used to interpret the response to the prompt issued by
+.BR \-ok .
+The `LC_CTYPE' environment variable will
+also affect which characters are considered to be unprintable when
+filenames are printed; see the section UNUSUAL FILENAMES.
+
+.IP LC_MESSAGES
+Determines the locale to be used for internationalised messages. If
+the `POSIXLY_CORRECT' environment variable is set, this also
+determines the interpretation of the response to the prompt made by the
+.BR \-ok
+action.
+
+.IP NLSPATH
+Determines the location of the internationalisation message catalogues.
+
+.IP PATH
+Affects the directories which are searched to find the executables
+invoked by
+.BR \-exec ,
+.BR \-execdir ,
+.B \-ok
+and
+.BR \-okdir .
+
+.IP POSIXLY_CORRECT
+Determines the block size used by
+.B \-ls
+and
+.BR \-fls .
+If
+.B POSIXLY_CORRECT
+is set, blocks are units of 512 bytes. Otherwise they are units of 1024 bytes.
+.IP
+Setting this variable also turns off
+warning messages (that is, implies
+.BR \-nowarn )
+by default, because POSIX requires that apart from
+the output for
+.BR \-ok ,
+all messages printed on stderr are diagnostics and must result in a
+non-zero exit status.
+.IP
+When POSIXLY_CORRECT is not set,
+.B \-perm
++zzz
+is treated just like
+.B \-perm
+/zzz
+if
++zzz is not a valid symbolic mode. When POSIXLY_CORRECT is set, such
+constructs are treated as an error.
+.IP
+When POSIXLY_CORRECT is set, the response to the prompt made by the
+.B \-ok
+action is interpreted according to the system's message catalogue, as
+opposed to according to
+.BR find 's
+own message translations.
+
+.IP TZ
+Affects the time zone used for some of the time-related format
+directives of
+.B \-printf
+and
+.BR \-fprintf .
+.SH "EXAMPLES"
+.nf
+.B find /tmp \-name core \-type f \-print | xargs /bin/rm \-f
+
+.fi
+Find files named
+.B core
+in or below the directory
+.B /tmp
+and delete them. Note that this will work incorrectly if there are
+any filenames containing newlines, single or double quotes, or spaces.
+.P
+.B find /tmp \-name core \-type f \-print0 | xargs \-0 /bin/rm \-f
+
+.fi
+Find files named
+.B core
+in or below the directory
+.B /tmp
+and delete them, processing filenames in such a way that file or
+directory names containing single or double quotes, spaces or newlines
+are correctly handled. The
+.B \-name
+test comes before the
+.B \-type
+test in order to avoid having to call
+.B stat(2)
+on every file.
+
+.P
+.nf
+.B find . \-type f \-exec file \(aq{}\(aq \e;
+
+.fi
+Runs `file' on every file in or below the current directory. Notice
+that the braces are enclosed in single quote marks to protect them
+from interpretation as shell script punctuation. The semicolon is
+similarly protected by the use of a backslash, though single quotes
+could have been used in that case also.
+
+.P
+.nf
+.B find / \e( \-perm \-4000 \-fprintf /root/suid.txt \(aq%#m %u %p\en\(aq \e) , \e
+.B \e( \-size +100M \-fprintf /root/big.txt \(aq%\-10s %p\en\(aq \e)
+
+.fi
+Traverse the filesystem just once, listing setuid files and
+directories into
+.B /root/suid.txt
+and large files into
+.BR /root/big.txt .
+
+.P
+.nf
+.B find $HOME \-mtime 0
+
+.fi
+Search for files in your home directory which have been modified in
+the last twenty-four hours. This command works this way because the
+time since each file was last modified is divided by 24 hours and any
+remainder is discarded. That means that to match
+.B \-mtime
+.BR 0 ,
+a file will have to have a modification in the past which is less than
+24 hours ago.
+
+.P
+.nf
+.B find /sbin /usr/sbin -executable \e! -readable \-print
+
+.fi
+Search for files which are executable but not readable.
+
+.P
+.nf
+.B find . \-perm 664
+
+.fi
+Search for files which have read and write permission for their owner,
+and group, but which other users can read but not write to. Files
+which meet these criteria but have other permissions bits set (for
+example if someone can execute the file) will not be matched.
+
+.P
+.nf
+.B find . \-perm \-664
+
+.fi
+Search for files which have read and write permission for their owner
+and group, and which other users can read, without regard to the
+presence of any extra permission bits (for example the executable
+bit). This will match a file which has mode 0777, for example.
+
+.P
+.nf
+.B find . \-perm /222
+
+.fi
+Search for files which are writable by somebody (their owner, or
+their group, or anybody else).
+
+.P
+.nf
+.B find . \-perm /220
+.B find . \-perm /u+w,g+w
+.B find . \-perm /u=w,g=w
+
+.fi
+All three of these commands do the same thing, but the first one uses
+the octal representation of the file mode, and the other two use the
+symbolic form. These commands all search for files which are
+writable by either their owner or their group. The files don't have
+to be writable by both the owner and group to be matched; either will
+do.
+
+.P
+.nf
+.B find . \-perm \-220
+.B find . \-perm \-g+w,u+w
+
+.fi
+Both these commands do the same thing; search for files which are
+writable by both their owner and their group.
+
+.P
+.nf
+.B find . \-perm \-444 \-perm /222 ! \-perm /111
+.B find . \-perm \-a+r \-perm /a+w ! \-perm /a+x
+
+.fi
+These two commands both search for files that are readable for
+everybody (
+.B \-perm \-444
+or
+.BR "\-perm \-a+r" ),
+have at least one write bit
+set (
+.B \-perm /222
+or
+.BR "\-perm /a+w" )
+but are not executable for anybody (
+.B ! \-perm /111
+and
+.B ! \-perm /a+x
+respectively).
+
+.P
+.nf
+.B cd /source-dir
+.B find . \-name .snapshot \-prune \-o \e( \e! \-name "*~" \-print0 \e)|
+.B cpio \-pmd0 /dest-dir
+
+.fi
+This command copies the contents of
+.B /source-dir
+to
+.BR /dest-dir ,
+but omits files and directories named
+.B .snapshot
+(and anything in them). It also omits files or directories whose name
+ends in
+.BR ~ ,
+but not their contents. The construct
+.B \-prune \-o \e( \&...\& \-print0 \e)
+is quite common. The idea here is that the expression before
+.B \-prune
+matches things which are to be pruned. However, the
+.B \-prune
+action itself returns true, so the following
+.B \-o
+ensures that the right hand side is evaluated only for those
+directories which didn't get pruned (the contents of the pruned
+directories are not even visited, so their contents are irrelevant).
+The expression on the right hand side of the
+.B \-o
+is in parentheses only for clarity. It emphasises that the
+.B \-print0
+action takes place only for things that didn't have
+.B \-prune
+applied to them. Because the default `and' condition between tests
+binds more tightly than
+.BR \-o ,
+this is the default anyway, but the parentheses help to show
+what is going on.
+
+.P
+.nf
+.B find repo/ -exec test -d {}/.svn \e; -or \e
+.B -exec test -d {}/.git \e; -or -exec test -d {}/CVS \e; \e
+.B -print -prune
+.fi
+
+Given the following directory of projects and their associated SCM
+administrative directories, perform an efficient search for the
+projects' roots:
+
+.nf
+.B repo/project1/CVS
+.B repo/gnu/project2/.svn
+.B repo/gnu/project3/.svn
+.B repo/gnu/project3/src/.svn
+.B repo/project4/.git
+
+.fi
+In this example,
+.B \-prune
+prevents unnecessary descent into directories that have already been
+discovered (for example we do not search project3/src because we
+already found project3/.svn), but ensures sibling directories
+(project2 and project3) are found.
+
+.SH EXIT STATUS
+.PP
+.B find
+exits with status 0 if all files are processed successfully, greater
+than 0 if errors occur. This is deliberately a very broad
+description, but if the return value is non-zero, you should not rely
+on the correctness of the results of
+.BR find .
+
+When some error occurs,
+.B find
+may stop immediately, without completing all the actions specified.
+For example, some starting points may not have been examined or some
+pending program invocations for
+.B \-exec \&...\& {} +
+or
+.B \-execdir \&...\& {} +
+may not have been performed.
+
+
+.SH "SEE ALSO"
+\fBlocate\fP(1), \fBlocatedb\fP(5), \fBupdatedb\fP(1), \fBxargs\fP(1),
+\fBchmod\fP(1), \fBfnmatch\fP(3), \fBregex\fP(7), \fBstat\fP(2),
+\fBlstat\fP(2), \fBls\fP(1), \fBprintf\fP(3), \fBstrftime\fP(3),
+\fBctime\fP(3)
+
+The full documentation for
+.B find
+is maintained as a Texinfo manual. If the
+.B info
+and
+.B find
+programs are properly installed at your site, the command
+.B info find
+should give you access to the complete manual.
+
+.SH "HISTORY"
+As of findutils-4.2.2, shell metacharacters (`*', `?' or `[]' for
+example) used in filename patterns will match a leading `.', because
+IEEE POSIX interpretation 126 requires this.
+.P
+As of findutils-4.3.3,
+.B \-perm /000
+now matches all files instead of none.
+.P
+Nanosecond-resolution
+timestamps were implemented in findutils-4.3.3.
+.P
+As of findutils-4.3.11, the
+.B \-delete
+action sets
+.BR find 's
+exit status to a nonzero value when it fails.
+However,
+.B find
+will not exit immediately. Previously,
+.BR find 's
+exit status was unaffected by the failure of
+.BR \-delete .
+.TS
+l l l .
+Feature Added in Also occurs in
+\-newerXY 4.3.3 BSD
+\-D 4.3.1
+\-O 4.3.1
+\-readable 4.3.0
+\-writable 4.3.0
+\-executable 4.3.0
+\-regextype 4.2.24
+\-exec ... + 4.2.12 POSIX
+\-execdir 4.2.12 BSD
+\-okdir 4.2.12
+\-samefile 4.2.11
+\-H 4.2.5 POSIX
+\-L 4.2.5 POSIX
+\-P 4.2.5 BSD
+\-delete 4.2.3
+\-quit 4.2.3
+\-d 4.2.3 BSD
+\-wholename 4.2.0
+\-iwholename 4.2.0
+\-ignore_readdir_race 4.2.0
+\-fls 4.0
+\-ilname 3.8
+\-iname 3.8
+\-ipath 3.8
+\-iregex 3.8
+.TE
+.P
+The syntax
+\.B \-perm +MODE
+was removed in findutils-4.5.12, in favour of
+\.B \-perm
+.BR /MODE .
+The
+.B +MODE
+syntax had been deprecated since findutils-4.2.21
+which was released in 2005.
+.P
+.SH "NON-BUGS"
+.nf
+.B $ find . \-name *.c \-print
+find: paths must precede expression
+Usage: find [\-H] [\-L] [\-P] [\-Olevel] [\-D help|tree|search|stat|rates|opt|exec] [path...] [expression]
+.fi
+.P
+This happens because
+.I *.c
+has been expanded by the shell
+resulting in
+.B find
+actually receiving a command line like this:
+.nf
+
+.B find . \-name bigram.c code.c frcode.c locate.c \-print
+
+.fi
+That command is of course not going to work. Instead of doing things
+this way, you should enclose the pattern in quotes or escape the wildcard:
+.nf
+.B $ find . \-name \(aq*.c\(aq \-print
+.B $ find . \-name \e*.c \-print
+.fi
+
+.SH "BUGS"
+.P
+There are security problems inherent in the behaviour that the POSIX
+standard specifies for
+.BR find ,
+which therefore cannot be fixed. For example, the
+.B \-exec
+action is
+inherently insecure, and
+.B \-execdir
+should be used instead.
+Please see \fBFinding Files\fP for more information.
+.P
+The environment variable
+.B LC_COLLATE
+has no effect on the
+.B \-ok
+action.
+.P
+The best way to report a bug is to use the form at
+http://savannah.gnu.org/bugs/?group=findutils.
+The reason for this is that you will then be able to track progress in
+fixing the problem. Other comments about \fBfind\fP(1) and about
+the findutils package in general can be sent to the
+.I bug\-findutils
+mailing list. To join the list, send email to
+.IR bug\-findutils\-request@gnu.org .
diff --git a/find/finddata.c b/find/finddata.c
new file mode 100644
index 0000000..6ef91c6
--- /dev/null
+++ b/find/finddata.c
@@ -0,0 +1,33 @@
+/* finddata.c -- global data for "find".
+ Copyright (C) 1990, 1991, 1992, 1993, 1994, 2000, 2003, 2004, 2005,
+ 2007, 2010, 2011 Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/* config.h must be included first. */
+#include <config.h>
+
+/* system headers would go here, but we include none. */
+
+/* gnulib headers. */
+#include "save-cwd.h"
+
+/* find headers. */
+#include "defs.h"
+
+
+struct options options;
+struct state state;
+struct saved_cwd *initial_wd = NULL;
diff --git a/find/fstype.c b/find/fstype.c
new file mode 100644
index 0000000..a47b6d3
--- /dev/null
+++ b/find/fstype.c
@@ -0,0 +1,326 @@
+/* fstype.c -- determine type of file systems that files are on
+ Copyright (C) 1990, 1991, 1992, 1993, 1994, 2000,
+ 2004, 2010, 2011 Free Software Foundation, Inc.
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/* Written by David MacKenzie <djm@gnu.org>.
+ *
+ * Converted to use gnulib's read_file_system_list()
+ * by James Youngman <jay@gnu.org> (which saves a lot
+ * of manual hacking of configure.in).
+ */
+
+/* config.h must be included first. */
+#include <config.h>
+
+/* system headers. */
+#include <errno.h>
+#include <fcntl.h>
+#if HAVE_MNTENT_H
+# include <mntent.h>
+#endif
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+#ifdef HAVE_SYS_MKDEV_H
+# include <sys/mkdev.h>
+#endif
+#ifdef HAVE_SYS_MNTIO_H
+# include <sys/mntio.h>
+#endif
+#if HAVE_SYS_MNTTAB_H
+# include <sys/mnttab.h>
+#endif
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+/* gnulib headers. */
+#include "dirname.h"
+#include "xalloc.h"
+#include "xstrtol.h"
+#include "mountlist.h"
+#include "error.h"
+#include "gettext.h"
+
+/* find headers. */
+#include "defs.h"
+#include "extendbuf.h"
+
+#if ENABLE_NLS
+# include <libintl.h>
+# define _(Text) gettext (Text)
+#else
+# define _(Text) Text
+#endif
+#ifdef gettext_noop
+# define N_(String) gettext_noop (String)
+#else
+/* See locate.c for explanation as to why not use (String) */
+# define N_(String) String
+#endif
+
+static char *file_system_type_uncached (const struct stat *statp, const char *path);
+
+
+static void
+free_file_system_list (struct mount_entry *p)
+{
+ while (p)
+ {
+ struct mount_entry *pnext = p->me_next;
+
+ free (p->me_devname);
+ free (p->me_mountdir);
+
+ if (p->me_type_malloced)
+ free (p->me_type);
+ p->me_next = NULL;
+ free (p);
+ p = pnext;
+ }
+}
+
+
+
+
+#ifdef AFS
+#include <netinet/in.h>
+#include <afs/venus.h>
+#if __STDC__
+/* On SunOS 4, afs/vice.h defines this to rely on a pre-ANSI cpp. */
+#undef _VICEIOCTL
+#define _VICEIOCTL(id) ((unsigned int ) _IOW('V', id, struct ViceIoctl))
+#endif
+#ifndef _IOW
+/* AFS on Solaris 2.3 doesn't get this definition. */
+#include <sys/ioccom.h>
+#endif
+
+static int
+in_afs (char *path)
+{
+ static char space[2048];
+ struct ViceIoctl vi;
+
+ vi.in_size = 0;
+ vi.out_size = sizeof (space);
+ vi.out = space;
+
+ if (pioctl (path, VIOC_FILE_CELL_NAME, &vi, 1)
+ && (errno == EINVAL || errno == ENOENT))
+ return 0;
+ return 1;
+}
+#endif /* AFS */
+
+/* Nonzero if the current file system's type is known. */
+static int fstype_known = 0;
+
+/* Return a static string naming the type of file system that the file PATH,
+ described by STATP, is on.
+ RELPATH is the file name relative to the current directory.
+ Return "unknown" if its file system type is unknown. */
+
+char *
+filesystem_type (const struct stat *statp, const char *path)
+{
+ static char *current_fstype = NULL;
+ static dev_t current_dev;
+
+ if (current_fstype != NULL)
+ {
+ if (fstype_known && statp->st_dev == current_dev)
+ return current_fstype; /* Cached value. */
+ free (current_fstype);
+ }
+ current_dev = statp->st_dev;
+ current_fstype = file_system_type_uncached (statp, path);
+ return current_fstype;
+}
+
+static int
+set_fstype_devno (struct mount_entry *p)
+{
+ struct stat stbuf;
+
+ if (p->me_dev == (dev_t)-1)
+ {
+ set_stat_placeholders (&stbuf);
+ if (0 == (options.xstat)(p->me_mountdir, &stbuf))
+ {
+ p->me_dev = stbuf.st_dev;
+ return 0;
+ }
+ else
+ {
+ return -1;
+ }
+ }
+ return 0; /* not needed */
+}
+
+static struct mount_entry *
+must_read_fs_list (bool need_fs_type)
+{
+ struct mount_entry *entries = read_file_system_list (need_fs_type);
+ if (NULL == entries)
+ {
+ /* We cannot determine for sure which file we were trying to
+ * use because gnulib has abstracted all that stuff away.
+ * Hence we cannot issue a specific error message here.
+ */
+ error (EXIT_FAILURE, 0, _("Cannot read mounted file system list"));
+ }
+ return entries;
+}
+
+
+
+/* Return a newly allocated string naming the type of file system that the
+ file PATH, described by STATP, is on.
+ RELPATH is the file name relative to the current directory.
+ Return "unknown" if its file system type is unknown. */
+
+static char *
+file_system_type_uncached (const struct stat *statp, const char *path)
+{
+ struct mount_entry *entries, *entry, *best;
+ char *type;
+
+ (void) path;
+
+#ifdef AFS
+ if (in_afs (path))
+ {
+ fstype_known = 1;
+ return xstrdup ("afs");
+ }
+#endif
+
+ best = NULL;
+ entries = must_read_fs_list (true);
+ for (type=NULL, entry=entries; entry; entry=entry->me_next)
+ {
+#ifdef MNTTYPE_IGNORE
+ if (!strcmp (entry->me_type, MNTTYPE_IGNORE))
+ continue;
+#endif
+ if (0 == set_fstype_devno (entry))
+ {
+ if (entry->me_dev == statp->st_dev)
+ {
+ best = entry;
+ /* Don't exit the loop, because some systems (for
+ example Linux-based systems in which /etc/mtab is a
+ symlink to /proc/mounts) can have duplicate entries
+ in the filesystem list. This happens most frequently
+ for /.
+ */
+ }
+ }
+ }
+ if (best)
+ {
+ type = xstrdup (best->me_type);
+ }
+ free_file_system_list (entries);
+
+ /* Don't cache unknown values. */
+ fstype_known = (type != NULL);
+
+ return type ? type : xstrdup (_("unknown"));
+}
+
+
+char *
+get_mounted_filesystems (void)
+{
+ char *result = NULL;
+ size_t alloc_size = 0u;
+ size_t used = 0u;
+ struct mount_entry *entries, *entry;
+ void *p;
+
+ entries = must_read_fs_list (false);
+ for (entry=entries; entry; entry=entry->me_next)
+ {
+ size_t len;
+
+#ifdef MNTTYPE_IGNORE
+ if (!strcmp (entry->me_type, MNTTYPE_IGNORE))
+ continue;
+#endif
+
+ len = strlen (entry->me_mountdir) + 1;
+ p = extendbuf (result, used+len, &alloc_size);
+ if (p)
+ {
+ result = p;
+ strcpy (&result[used], entry->me_mountdir);
+ used += len; /* len already includes one for the \0 */
+ }
+ else
+ {
+ break;
+ }
+ }
+
+ free_file_system_list (entries);
+ return result;
+}
+
+
+dev_t *
+get_mounted_devices (size_t *n)
+{
+ size_t alloc_size = 0u;
+ size_t used = 0u;
+ struct mount_entry *entries, *entry;
+ dev_t *result = NULL;
+
+ /* Use read_file_system_list () rather than must_read_fs_list()
+ * because on some system this is always called at startup,
+ * and find should only exit fatally if it needs to use the
+ * result of this operation. If we can't get the fs list
+ * but we never need the information, there is no need to fail.
+ */
+ for (entry = entries = read_file_system_list (false);
+ entry;
+ entry = entry->me_next)
+ {
+ void *p = extendbuf (result, sizeof(dev_t)*(used+1), &alloc_size);
+ if (p)
+ {
+ result = p;
+ if (0 == set_fstype_devno (entry))
+ {
+ result[used] = entry->me_dev;
+ ++used;
+ }
+ }
+ else
+ {
+ free (result);
+ result = NULL;
+ }
+ }
+ free_file_system_list (entries);
+ if (result)
+ {
+ *n = used;
+ }
+ return result;
+}
diff --git a/find/ftsfind.c b/find/ftsfind.c
new file mode 100644
index 0000000..414327b
--- /dev/null
+++ b/find/ftsfind.c
@@ -0,0 +1,757 @@
+/* find -- search for files in a directory hierarchy (fts version)
+ Copyright (C) 1990, 1091, 1992, 1993, 1994, 2000, 2003, 2004, 2005,
+ 2006, 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/* This file was written by James Youngman, based on oldfind.c.
+
+ GNU find was written by Eric Decker <cire@soe.ucsc.edu>,
+ with enhancements by David MacKenzie <djm@gnu.org>,
+ Jay Plett <jay@silence.princeton.nj.us>,
+ and Tim Wood <axolotl!tim@toad.com>.
+ The idea for -print0 and xargs -0 came from
+ Dan Bernstein <brnstnd@kramden.acf.nyu.edu>.
+*/
+
+/* config.h must always be included first. */
+#include <config.h>
+
+
+/* system headers. */
+#include <assert.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <inttypes.h>
+#include <locale.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
+/* gnulib headers. */
+#include "cloexec.h"
+#include "closeout.h"
+#include "error.h"
+#include "fts_.h"
+#include "gettext.h"
+#include "progname.h"
+#include "quotearg.h"
+#include "save-cwd.h"
+#include "xgetcwd.h"
+
+/* find headers. */
+#include "defs.h"
+#include "dircallback.h"
+#include "fdleak.h"
+#include "unused-result.h"
+
+#define USE_SAFE_CHDIR 1
+#undef STAT_MOUNTPOINTS
+
+
+#if ENABLE_NLS
+# include <libintl.h>
+# define _(Text) gettext (Text)
+#else
+# define _(Text) Text
+#define textdomain(Domain)
+#define bindtextdomain(Package, Directory)
+#endif
+#ifdef gettext_noop
+# define N_(String) gettext_noop (String)
+#else
+/* See locate.c for explanation as to why not use (String) */
+# define N_(String) String
+#endif
+
+
+/* FTS_TIGHT_CYCLE_CHECK tries to work around Savannah bug #17877
+ * (but actually using it doesn't fix the bug).
+ */
+static int ftsoptions = FTS_NOSTAT|FTS_TIGHT_CYCLE_CHECK|FTS_CWDFD|FTS_VERBATIM;
+
+static int prev_depth = INT_MIN; /* fts_level can be < 0 */
+static int curr_fd = -1;
+
+
+static bool find (char *arg) __attribute_warn_unused_result__;
+static bool process_all_startpoints (int argc, char *argv[]) __attribute_warn_unused_result__;
+
+
+
+static void
+left_dir (void)
+{
+ if (ftsoptions & FTS_CWDFD)
+ {
+ if (curr_fd >= 0)
+ {
+ close (curr_fd);
+ curr_fd = -1;
+ }
+ }
+ else
+ {
+ /* do nothing. */
+ }
+}
+
+/*
+ * Signal that we are now inside a directory pointed to by dir_fd.
+ * The caller can't tell if this is the first time this happens, so
+ * we have to be careful not to call dup() more than once
+ */
+static void
+inside_dir (int dir_fd)
+{
+ if (ftsoptions & FTS_CWDFD)
+ {
+ assert (dir_fd == AT_FDCWD || dir_fd >= 0);
+
+ state.cwd_dir_fd = dir_fd;
+ if (curr_fd < 0)
+ {
+ if (AT_FDCWD == dir_fd)
+ {
+ curr_fd = AT_FDCWD;
+ }
+ else if (dir_fd >= 0)
+ {
+ curr_fd = dup_cloexec (dir_fd);
+ }
+ else
+ {
+ /* curr_fd is invalid, but dir_fd is also invalid.
+ * This should not have happened.
+ */
+ assert (curr_fd >= 0 || dir_fd >= 0);
+ }
+ }
+ }
+ else
+ {
+ /* FTS_CWDFD is not in use. We can always assume that
+ * AT_FDCWD refers to the directory we are currentl searching.
+ *
+ * Therefore there is nothing to do.
+ */
+ }
+}
+
+
+
+#ifdef STAT_MOUNTPOINTS
+static void init_mounted_dev_list (void);
+#endif
+
+#define STRINGIFY(X) #X
+#define HANDLECASE(N) case N: return #N;
+
+static char *
+get_fts_info_name (int info)
+{
+ static char buf[10];
+ switch (info)
+ {
+ HANDLECASE(FTS_D);
+ HANDLECASE(FTS_DC);
+ HANDLECASE(FTS_DEFAULT);
+ HANDLECASE(FTS_DNR);
+ HANDLECASE(FTS_DOT);
+ HANDLECASE(FTS_DP);
+ HANDLECASE(FTS_ERR);
+ HANDLECASE(FTS_F);
+ HANDLECASE(FTS_INIT);
+ HANDLECASE(FTS_NS);
+ HANDLECASE(FTS_NSOK);
+ HANDLECASE(FTS_SL);
+ HANDLECASE(FTS_SLNONE);
+ HANDLECASE(FTS_W);
+ default:
+ sprintf (buf, "[%d]", info);
+ return buf;
+ }
+}
+
+static void
+visit (FTS *p, FTSENT *ent, struct stat *pstat)
+{
+ struct predicate *eval_tree;
+
+ state.have_stat = (ent->fts_info != FTS_NS) && (ent->fts_info != FTS_NSOK);
+ state.rel_pathname = ent->fts_accpath;
+ state.cwd_dir_fd = p->fts_cwd_fd;
+
+ /* Apply the predicates to this path. */
+ eval_tree = get_eval_tree ();
+ apply_predicate (ent->fts_path, pstat, eval_tree);
+
+ /* Deal with any side effects of applying the predicates. */
+ if (state.stop_at_current_level)
+ {
+ fts_set (p, ent, FTS_SKIP);
+ }
+}
+
+static const char*
+partial_quotearg_n (int n, char *s, size_t len, enum quoting_style style)
+{
+ if (0 == len)
+ {
+ return quotearg_n_style (n, style, "");
+ }
+ else
+ {
+ char saved;
+ const char *result;
+
+ saved = s[len];
+ s[len] = 0;
+ result = quotearg_n_style (n, style, s);
+ s[len] = saved;
+ return result;
+ }
+}
+
+
+/* We've detected a file system loop. This is caused by one of
+ * two things:
+ *
+ * 1. Option -L is in effect and we've hit a symbolic link that
+ * points to an ancestor. This is harmless. We won't traverse the
+ * symbolic link.
+ *
+ * 2. We have hit a real cycle in the directory hierarchy. In this
+ * case, we issue a diagnostic message (POSIX requires this) and we
+ * skip that directory entry.
+ */
+static void
+issue_loop_warning (FTSENT * ent)
+{
+ if (S_ISLNK(ent->fts_statp->st_mode))
+ {
+ error (0, 0,
+ _("Symbolic link %s is part of a loop in the directory hierarchy; we have already visited the directory to which it points."),
+ safely_quote_err_filename (0, ent->fts_path));
+ }
+ else
+ {
+ /* We have found an infinite loop. POSIX requires us to
+ * issue a diagnostic. Usually we won't get to here
+ * because when the leaf optimisation is on, it will cause
+ * the subdirectory to be skipped. If /a/b/c/d is a hard
+ * link to /a/b, then the link count of /a/b/c is 2,
+ * because the ".." entry of /a/b/c/d points to /a, not
+ * to /a/b/c.
+ */
+ error (0, 0,
+ _("File system loop detected; "
+ "%s is part of the same file system loop as %s."),
+ safely_quote_err_filename (0, ent->fts_path),
+ partial_quotearg_n (1,
+ ent->fts_cycle->fts_path,
+ ent->fts_cycle->fts_pathlen,
+ options.err_quoting_style));
+ }
+}
+
+/*
+ * Return true if NAME corresponds to a file which forms part of a
+ * symbolic link loop. The command
+ * rm -f a b; ln -s a b; ln -s b a
+ * produces such a loop.
+ */
+static bool
+symlink_loop (const char *name)
+{
+ struct stat stbuf;
+ const int rv = options.xstat (name, &stbuf);
+ return (0 != rv) && (ELOOP == errno);
+}
+
+
+static void
+show_outstanding_execdirs (FILE *fp)
+{
+ if (options.debug_options & DebugExec)
+ {
+ int seen=0;
+ struct predicate *p;
+ p = get_eval_tree ();
+ fprintf (fp, "Outstanding execdirs:");
+
+ while (p)
+ {
+ const char *pfx;
+
+ if (pred_is (p, pred_execdir))
+ pfx = "-execdir";
+ else if (pred_is (p, pred_okdir))
+ pfx = "-okdir";
+ else
+ pfx = NULL;
+ if (pfx)
+ {
+ size_t i;
+ const struct exec_val *execp = &p->args.exec_vec;
+ ++seen;
+
+ fprintf (fp, "%s ", pfx);
+ if (execp->multiple)
+ fprintf (fp, "multiple ");
+ fprintf (fp, "%" PRIuMAX " args: ", (uintmax_t) execp->state.cmd_argc);
+ for (i=0; i<execp->state.cmd_argc; ++i)
+ {
+ fprintf (fp, "%s ", execp->state.cmd_argv[i]);
+ }
+ fprintf (fp, "\n");
+ }
+ p = p->pred_next;
+ }
+ if (!seen)
+ fprintf (fp, " none\n");
+ }
+ else
+ {
+ /* No debug output is wanted. */
+ }
+}
+
+static void
+consider_visiting (FTS *p, FTSENT *ent)
+{
+ struct stat statbuf;
+ mode_t mode;
+ int ignore, isdir;
+
+ if (options.debug_options & DebugSearch)
+ fprintf (stderr,
+ "consider_visiting (early): %s: "
+ "fts_info=%-6s, fts_level=%2d, prev_depth=%d "
+ "fts_path=%s, fts_accpath=%s\n",
+ quotearg_n_style (0, options.err_quoting_style, ent->fts_path),
+ get_fts_info_name (ent->fts_info),
+ (int)ent->fts_level, prev_depth,
+ quotearg_n_style (1, options.err_quoting_style, ent->fts_path),
+ quotearg_n_style (2, options.err_quoting_style, ent->fts_accpath));
+
+ if (ent->fts_info == FTS_DP)
+ {
+ left_dir ();
+ }
+ else if (ent->fts_level > prev_depth || ent->fts_level==0)
+ {
+ left_dir ();
+ }
+ inside_dir (p->fts_cwd_fd);
+ prev_depth = ent->fts_level;
+
+ statbuf.st_ino = ent->fts_statp->st_ino;
+
+ /* Cope with various error conditions. */
+ if (ent->fts_info == FTS_ERR
+ || ent->fts_info == FTS_DNR)
+ {
+ nonfatal_target_file_error (ent->fts_errno, ent->fts_path);
+ return;
+ }
+ else if (ent->fts_info == FTS_DC)
+ {
+ issue_loop_warning (ent);
+ error_severity (EXIT_FAILURE);
+ return;
+ }
+ else if (ent->fts_info == FTS_SLNONE)
+ {
+ /* fts_read() claims that ent->fts_accpath is a broken symbolic
+ * link. That would be fine, but if this is part of a symbolic
+ * link loop, we diagnose the problem and also ensure that the
+ * eventual return value is nonzero. Note that while the path
+ * we stat is local (fts_accpath), we print the full path name
+ * of the file (fts_path) in the error message.
+ */
+ if (symlink_loop (ent->fts_accpath))
+ {
+ nonfatal_target_file_error (ELOOP, ent->fts_path);
+ return;
+ }
+ }
+ else if (ent->fts_info == FTS_NS)
+ {
+ if (ent->fts_level == 0)
+ {
+ /* e.g., nonexistent starting point */
+ nonfatal_target_file_error (ent->fts_errno, ent->fts_path);
+ return;
+ }
+ else
+ {
+ /* The following if statement fixes Savannah bug #19605
+ * (failure to diagnose a symbolic link loop)
+ */
+ if (symlink_loop (ent->fts_accpath))
+ {
+ nonfatal_target_file_error (ELOOP, ent->fts_path);
+ return;
+ }
+ else
+ {
+ nonfatal_target_file_error (ent->fts_errno, ent->fts_path);
+ /* Continue despite the error, as file name without stat info
+ * might be better than not even processing the file name. This
+ * can lead to repeated error messages later on, though, if a
+ * predicate requires stat information.
+ *
+ * Not printing an error message here would be even more wrong,
+ * though, as this could cause the contents of a directory to be
+ * silently ignored, as the directory wouldn't be identified as
+ * such.
+ */
+ }
+
+ }
+ }
+
+ /* Cope with the usual cases. */
+ if (ent->fts_info == FTS_NSOK
+ || ent->fts_info == FTS_NS /* e.g. symlink loop */)
+ {
+ assert (!state.have_stat);
+ assert (ent->fts_info == FTS_NSOK || state.type == 0);
+ mode = state.type;
+ }
+ else
+ {
+ state.have_stat = true;
+ state.have_type = true;
+ statbuf = *(ent->fts_statp);
+ state.type = mode = statbuf.st_mode;
+
+ if (00000 == mode)
+ {
+ /* Savannah bug #16378. */
+ error (0, 0, _("WARNING: file %s appears to have mode 0000"),
+ quotearg_n_style (0, options.err_quoting_style, ent->fts_path));
+ }
+ }
+
+ /* update state.curdepth before calling digest_mode(), because digest_mode
+ * may call following_links().
+ */
+ state.curdepth = ent->fts_level;
+ if (mode)
+ {
+ if (!digest_mode (&mode, ent->fts_path, ent->fts_name, &statbuf, 0))
+ return;
+ }
+
+ /* examine this item. */
+ ignore = 0;
+ isdir = S_ISDIR(mode)
+ || (FTS_D == ent->fts_info)
+ || (FTS_DP == ent->fts_info)
+ || (FTS_DC == ent->fts_info);
+
+ if (isdir && (ent->fts_info == FTS_NSOK))
+ {
+ /* This is a directory, but fts did not stat it, so
+ * presumably would not be planning to search its
+ * children. Force a stat of the file so that the
+ * children can be checked.
+ */
+ fts_set (p, ent, FTS_AGAIN);
+ return;
+ }
+
+ if (options.maxdepth >= 0)
+ {
+ if (ent->fts_level >= options.maxdepth)
+ {
+ fts_set (p, ent, FTS_SKIP); /* descend no further */
+
+ if (ent->fts_level > options.maxdepth)
+ ignore = 1; /* don't even look at this one */
+ }
+ }
+
+ if ( (ent->fts_info == FTS_D) && !options.do_dir_first )
+ {
+ /* this is the preorder visit, but user said -depth */
+ ignore = 1;
+ }
+ else if ( (ent->fts_info == FTS_DP) && options.do_dir_first )
+ {
+ /* this is the postorder visit, but user didn't say -depth */
+ ignore = 1;
+ }
+ else if (ent->fts_level < options.mindepth)
+ {
+ ignore = 1;
+ }
+
+ if (options.debug_options & DebugSearch)
+ fprintf (stderr,
+ "consider_visiting (late): %s: "
+ "fts_info=%-6s, isdir=%d ignore=%d have_stat=%d have_type=%d \n",
+ quotearg_n_style (0, options.err_quoting_style, ent->fts_path),
+ get_fts_info_name (ent->fts_info),
+ isdir, ignore, state.have_stat, state.have_type);
+
+ if (!ignore)
+ {
+ visit (p, ent, &statbuf);
+ }
+
+ if (ent->fts_info == FTS_DP)
+ {
+ /* we're leaving a directory. */
+ state.stop_at_current_level = false;
+ }
+}
+
+
+
+static bool
+find (char *arg)
+{
+ char * arglist[2];
+ FTS *p;
+ FTSENT *ent;
+
+ state.starting_path_length = strlen (arg);
+ inside_dir (AT_FDCWD);
+
+ arglist[0] = arg;
+ arglist[1] = NULL;
+
+ switch (options.symlink_handling)
+ {
+ case SYMLINK_ALWAYS_DEREF:
+ ftsoptions |= FTS_COMFOLLOW|FTS_LOGICAL;
+ break;
+
+ case SYMLINK_DEREF_ARGSONLY:
+ ftsoptions |= FTS_COMFOLLOW|FTS_PHYSICAL;
+ break;
+
+ case SYMLINK_NEVER_DEREF:
+ ftsoptions |= FTS_PHYSICAL;
+ break;
+ }
+
+ if (options.stay_on_filesystem)
+ ftsoptions |= FTS_XDEV;
+
+ p = fts_open (arglist, ftsoptions, NULL);
+ if (NULL == p)
+ {
+ error (0, errno, _("cannot search %s"),
+ safely_quote_err_filename (0, arg));
+ error_severity (EXIT_FAILURE);
+ }
+ else
+ {
+ int level = INT_MIN;
+
+ while ( (errno=0, ent=fts_read (p)) != NULL )
+ {
+ if (state.execdirs_outstanding)
+ {
+ /* If we changed level, perform any outstanding
+ * execdirs. If we see a sequence of directory entries
+ * like this: fffdfffdfff, we could build a command line
+ * of 9 files, but this simple-minded implementation
+ * builds a command line for only 3 files at a time
+ * (since fts descends into the directories).
+ */
+ if ((int)ent->fts_level != level)
+ {
+ show_outstanding_execdirs (stderr);
+ complete_pending_execdirs ();
+ }
+ }
+ level = (int)ent->fts_level;
+
+ state.already_issued_stat_error_msg = false;
+ state.have_stat = false;
+ state.have_type = !!ent->fts_statp->st_mode;
+ state.type = state.have_type ? ent->fts_statp->st_mode : 0;
+ consider_visiting (p, ent);
+ }
+ /* fts_read returned NULL; distinguish between "finished" and "error". */
+ if (errno)
+ {
+ error (0, errno,
+ "failed to read file names from file system at or below %s",
+ safely_quote_err_filename (0, arg));
+ error_severity (EXIT_FAILURE);
+ return false;
+ }
+
+ if (0 != fts_close (p))
+ {
+ /* Here we break the abstraction of fts_close a bit, because we
+ * are going to skip the rest of the start points, and return with
+ * nonzero exit status. Hence we need to issue a diagnostic on
+ * stderr. */
+ error (0, errno,
+ _("failed to restore working directory after searching %s"),
+ arg);
+ error_severity (EXIT_FAILURE);
+ return false;
+ }
+ p = NULL;
+ }
+ return true;
+}
+
+
+static bool
+process_all_startpoints (int argc, char *argv[])
+{
+ int i;
+
+ /* figure out how many start points there are */
+ for (i = 0; i < argc && !looks_like_expression (argv[i], true); i++)
+ {
+ state.starting_path_length = strlen (argv[i]); /* TODO: is this redundant? */
+ if (!find (argv[i]))
+ return false;
+ }
+
+ if (i == 0)
+ {
+ /*
+ * We use a temporary variable here because some actions modify
+ * the path temporarily. Hence if we use a string constant,
+ * we get a coredump. The best example of this is if we say
+ * "find -printf %H" (note, not "find . -printf %H").
+ */
+ char defaultpath[2] = ".";
+ return find (defaultpath);
+ }
+ return true;
+}
+
+
+
+
+int
+main (int argc, char **argv)
+{
+ int end_of_leading_options = 0; /* First arg after any -H/-L etc. */
+ struct predicate *eval_tree;
+
+ if (argv[0])
+ set_program_name (argv[0]);
+ else
+ set_program_name ("find");
+
+ record_initial_cwd ();
+
+ state.already_issued_stat_error_msg = false;
+ state.exit_status = 0;
+ state.execdirs_outstanding = false;
+ state.cwd_dir_fd = AT_FDCWD;
+
+ if (fd_leak_check_is_enabled ())
+ {
+ remember_non_cloexec_fds ();
+ }
+
+ state.shared_files = sharefile_init ("w");
+ if (NULL == state.shared_files)
+ {
+ error (EXIT_FAILURE, errno,
+ _("Failed to initialize shared-file hash table"));
+ }
+
+ /* Set the option defaults before we do the locale initialisation as
+ * check_nofollow() needs to be executed in the POSIX locale.
+ */
+ set_option_defaults (&options);
+
+#ifdef HAVE_SETLOCALE
+ setlocale (LC_ALL, "");
+#endif
+
+ bindtextdomain (PACKAGE, LOCALEDIR);
+ textdomain (PACKAGE);
+ if (atexit (close_stdout))
+ {
+ error (EXIT_FAILURE, errno, _("The atexit library function failed"));
+ }
+
+ /* Check for -P, -H or -L options. Also -D and -O, which are
+ * both GNU extensions.
+ */
+ end_of_leading_options = process_leading_options (argc, argv);
+
+ if (options.debug_options & DebugStat)
+ options.xstat = debug_stat;
+
+#ifdef DEBUG
+ fprintf (stderr, "cur_day_start = %s", ctime (&options.cur_day_start));
+#endif /* DEBUG */
+
+
+ /* We are now processing the part of the "find" command line
+ * after the -H/-L options (if any).
+ */
+ eval_tree = build_expression_tree (argc, argv, end_of_leading_options);
+
+ /* safely_chdir() needs to check that it has ended up in the right place.
+ * To avoid bailing out when something gets automounted, it checks if
+ * the target directory appears to have had a directory mounted on it as
+ * we chdir()ed. The problem with this is that in order to notice that
+ * a file system was mounted, we would need to lstat() all the mount points.
+ * That strategy loses if our machine is a client of a dead NFS server.
+ *
+ * Hence if safely_chdir() and wd_sanity_check() can manage without needing
+ * to know the mounted device list, we do that.
+ */
+ if (!options.open_nofollow_available)
+ {
+#ifdef STAT_MOUNTPOINTS
+ init_mounted_dev_list ();
+#endif
+ }
+
+
+ /* process_all_startpoints processes the starting points named on
+ * the command line. A false return value from it means that we
+ * failed to restore the original context. That means it would not
+ * be safe to call cleanup() since we might complete an execdir in
+ * the wrong directory for example.
+ */
+ if (process_all_startpoints (argc-end_of_leading_options,
+ argv+end_of_leading_options))
+ {
+ /* If "-exec ... {} +" has been used, there may be some
+ * partially-full command lines which have been built,
+ * but which are not yet complete. Execute those now.
+ */
+ show_success_rates (eval_tree);
+ cleanup ();
+ }
+ return state.exit_status;
+}
+
+bool
+is_fts_enabled (int *fts_options)
+{
+ /* this version of find (i.e. this main()) uses fts. */
+ *fts_options = ftsoptions;
+ return true;
+}
diff --git a/find/oldfind.c b/find/oldfind.c
new file mode 100644
index 0000000..c32cbc5
--- /dev/null
+++ b/find/oldfind.c
@@ -0,0 +1,1581 @@
+/* find -- search for files in a directory hierarchy
+ Copyright (C) 1990, 1991, 1992, 1993, 1994, 2000, 2003, 2004, 2005,
+ 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+/* GNU find was written by Eric Decker <cire@soe.ucsc.edu>,
+ with enhancements by David MacKenzie <djm@gnu.org>,
+ Jay Plett <jay@silence.princeton.nj.us>,
+ and Tim Wood <axolotl!tim@toad.com>.
+ The idea for -print0 and xargs -0 came from
+ Dan Bernstein <brnstnd@kramden.acf.nyu.edu>.
+ Improvements have been made by James Youngman <jay@gnu.org>.
+*/
+
+/* config.h must be included first. */
+#include <config.h>
+
+/* system headers. */
+#include <assert.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <locale.h>
+#include <sys/stat.h>
+
+/* gnulib headers. */
+#include "canonicalize.h"
+#include "closein.h"
+#include "dirent-safer.h"
+#include "dirname.h"
+#include "error.h"
+#include "fcntl--.h"
+#include "gettext.h"
+#include "human.h"
+#include "progname.h"
+#include "save-cwd.h"
+#include "xalloc.h"
+#include "xgetcwd.h"
+
+
+/* find headers. */
+#include "buildcmd.h"
+#include "defs.h"
+#include "fdleak.h"
+
+#undef STAT_MOUNTPOINTS
+
+#ifdef CLOSEDIR_VOID
+/* Fake a return value. */
+# define CLOSEDIR(d) (closedir (d), 0)
+#else
+# define CLOSEDIR(d) closedir (d)
+#endif
+
+enum
+{
+ NOT_AN_INODE_NUMBER = 0
+};
+
+#ifdef D_INO_IN_DIRENT
+# define D_INO(dp) (dp)->d_ino
+#else
+/* Some systems don't have inodes, so fake them to avoid lots of ifdefs. */
+# define D_INO(dp) NOT_AN_INODE_NUMBER
+#endif
+
+#if ENABLE_NLS
+# include <libintl.h>
+# define _(Text) gettext (Text)
+#else
+# define _(Text) Text
+#define textdomain(Domain)
+#define bindtextdomain(Package, Directory)
+#define ngettext(singular,plural,n) ((1==n) ? singular : plural)
+#endif
+#ifdef gettext_noop
+# define N_(String) gettext_noop (String)
+#else
+/* See locate.c for explanation as to why not use (String) */
+# define N_(String) String
+#endif
+
+#ifdef STAT_MOUNTPOINTS
+static void init_mounted_dev_list (int mandatory);
+#endif
+
+static void process_top_path (char *pathname, mode_t mode, ino_t inum);
+static int process_path (char *pathname, char *name, bool leaf, char *parent, mode_t type, ino_t inum);
+static void process_dir (char *pathname, char *name, int pathlen, const struct stat *statp, char *parent);
+
+
+
+/* A file descriptor open to the initial working directory.
+ Doing it this way allows us to work when the i.w.d. has
+ unreadable parents. */
+extern int starting_desc;
+
+/* The stat buffer of the initial working directory. */
+static struct stat starting_stat_buf;
+
+enum ChdirSymlinkHandling
+ {
+ SymlinkHandleDefault, /* Normally the right choice */
+ SymlinkFollowOk /* see comment in process_top_path() */
+ };
+
+
+enum TraversalDirection
+ {
+ TraversingUp,
+ TraversingDown
+ };
+
+enum WdSanityCheckFatality
+ {
+ FATAL_IF_SANITY_CHECK_FAILS,
+ RETRY_IF_SANITY_CHECK_FAILS,
+ NON_FATAL_IF_SANITY_CHECK_FAILS
+ };
+
+#if defined HAVE_STRUCT_DIRENT_D_TYPE
+/* Convert the value of struct dirent.d_type into a value for
+ * struct stat.st_mode (at least the file type bits), or zero
+ * if the type is DT_UNKNOWN or is a value we don't know about.
+ */
+static mode_t
+type_to_mode (unsigned type)
+{
+ switch (type)
+ {
+#ifdef DT_FIFO
+ case DT_FIFO: return S_IFIFO;
+#endif
+#ifdef DT_CHR
+ case DT_CHR: return S_IFCHR;
+#endif
+#ifdef DT_DIR
+ case DT_DIR: return S_IFDIR;
+#endif
+#ifdef DT_BLK
+ case DT_BLK: return S_IFBLK;
+#endif
+#ifdef DT_REG
+ case DT_REG: return S_IFREG;
+#endif
+#ifdef DT_LNK
+ case DT_LNK: return S_IFLNK;
+#endif
+#ifdef DT_SOCK
+ case DT_SOCK: return S_IFSOCK;
+#endif
+ default:
+ return 0; /* Unknown. */
+ }
+}
+#endif
+
+
+int
+get_current_dirfd (void)
+{
+ return AT_FDCWD;
+}
+
+/* CAUTION: this is the entry point for the oldfind executable, which is not the binary that
+ * will actually get installed. See ftsfind.c. */
+int
+main (int argc, char **argv)
+{
+ int i;
+ int end_of_leading_options = 0; /* First arg after any -H/-L etc. */
+ struct predicate *eval_tree;
+
+ if (argv[0])
+ set_program_name (argv[0]);
+ else
+ set_program_name ("find");
+
+ state.exit_status = 0;
+
+ if (fd_leak_check_is_enabled ())
+ {
+ remember_non_cloexec_fds ();
+ }
+
+ record_initial_cwd ();
+
+ state.already_issued_stat_error_msg = false;
+ state.shared_files = sharefile_init ("w");
+ if (NULL == state.shared_files)
+ {
+ error (EXIT_FAILURE, errno,
+ _("Failed to initialize shared-file hash table"));
+ }
+
+ /* Set the option defaults before we do the locale
+ * initialisation as check_nofollow () needs to be executed in the
+ * POSIX locale.
+ */
+ set_option_defaults (&options);
+
+#ifdef HAVE_SETLOCALE
+ setlocale (LC_ALL, "");
+#endif
+ bindtextdomain (PACKAGE, LOCALEDIR);
+ textdomain (PACKAGE);
+ if (atexit (close_stdin))
+ {
+ error (EXIT_FAILURE, errno, _("The atexit library function failed"));
+ }
+
+ /* Check for -P, -H or -L options. */
+ end_of_leading_options = process_leading_options (argc, argv);
+
+ if (options.debug_options & DebugStat)
+ options.xstat = debug_stat;
+
+#ifdef DEBUG
+ fprintf (stderr, "cur_day_start = %s", ctime (&options.cur_day_start));
+#endif /* DEBUG */
+
+ /* state.cwd_dir_fd has to be initialized before we call build_expression_tree ()
+ * because command-line parsing may lead us to stat some files.
+ */
+ state.cwd_dir_fd = AT_FDCWD;
+
+ /* We are now processing the part of the "find" command line
+ * after the -H/-L options (if any).
+ */
+ eval_tree = build_expression_tree (argc, argv, end_of_leading_options);
+
+
+ /* safely_chdir () needs to check that it has ended up in the right place.
+ * To avoid bailing out when something gets automounted, it checks if
+ * the target directory appears to have had a directory mounted on it as
+ * we chdir ()ed. The problem with this is that in order to notice that
+ * a file system was mounted, we would need to lstat () all the mount points.
+ * That strategy loses if our machine is a client of a dead NFS server.
+ *
+ * Hence if safely_chdir () and wd_sanity_check () can manage without needing
+ * to know the mounted device list, we do that.
+ */
+ if (!options.open_nofollow_available)
+ {
+#ifdef STAT_MOUNTPOINTS
+ init_mounted_dev_list (0);
+#endif
+ }
+
+
+ set_stat_placeholders (&starting_stat_buf);
+ if ((*options.xstat) (".", &starting_stat_buf) != 0)
+ error (EXIT_FAILURE, errno, _("cannot stat current directory"));
+
+ /* If no paths are given, default to ".". */
+ for (i = end_of_leading_options; i < argc && !looks_like_expression (argv[i], true); i++)
+ {
+ process_top_path (argv[i], 0, starting_stat_buf.st_ino);
+ }
+
+ /* If there were no path arguments, default to ".". */
+ if (i == end_of_leading_options)
+ {
+ /*
+ * We use a temporary variable here because some actions modify
+ * the path temporarily. Hence if we use a string constant,
+ * we get a coredump. The best example of this is if we say
+ * "find -printf %H" (note, not "find . -printf %H").
+ */
+ char defaultpath[2] = ".";
+ process_top_path (defaultpath, 0, starting_stat_buf.st_ino);
+ }
+
+ /* If "-exec ... {} +" has been used, there may be some
+ * partially-full command lines which have been built,
+ * but which are not yet complete. Execute those now.
+ */
+ show_success_rates (eval_tree);
+ cleanup ();
+ return state.exit_status;
+}
+
+bool is_fts_enabled (int *ftsoptions)
+{
+ /* this version of find (i.e. this main ()) does not use fts. */
+ *ftsoptions = 0;
+ return false;
+}
+
+
+static char *
+specific_dirname (const char *dir)
+{
+ char dirbuf[1024];
+
+ if (0 == strcmp (".", dir))
+ {
+ /* OK, what's '.'? */
+ if (NULL != getcwd (dirbuf, sizeof (dirbuf)))
+ {
+ return strdup (dirbuf);
+ }
+ else
+ {
+ return strdup (dir);
+ }
+ }
+ else
+ {
+ char *result = canonicalize_filename_mode (dir, CAN_EXISTING);
+ if (NULL == result)
+ return strdup (dir);
+ else
+ return result;
+ }
+}
+
+
+
+/* Return non-zero if FS is the name of a file system that is likely to
+ * be automounted
+ */
+static int
+fs_likely_to_be_automounted (const char *fs)
+{
+ return ( (0==strcmp (fs, "nfs")) || (0==strcmp (fs, "autofs")) || (0==strcmp (fs, "subfs")));
+}
+
+
+
+#ifdef STAT_MOUNTPOINTS
+static dev_t *mounted_devices = NULL;
+static size_t num_mounted_devices = 0u;
+
+
+static void
+init_mounted_dev_list (int mandatory)
+{
+ assert (NULL == mounted_devices);
+ assert (0 == num_mounted_devices);
+ mounted_devices = get_mounted_devices (&num_mounted_devices);
+ if (mandatory && (NULL == mounted_devices))
+ {
+ error (EXIT_FAILURE, 0, _("Cannot read list of mounted devices."));
+ }
+}
+
+static void
+refresh_mounted_dev_list (void)
+{
+ if (mounted_devices)
+ {
+ free (mounted_devices);
+ mounted_devices = 0;
+ }
+ num_mounted_devices = 0u;
+ init_mounted_dev_list (1);
+}
+
+
+/* Search for device DEV in the array LIST, which is of size N. */
+static int
+dev_present (dev_t dev, const dev_t *list, size_t n)
+{
+ if (list)
+ {
+ while (n-- > 0u)
+ {
+ if ( (*list++) == dev )
+ return 1;
+ }
+ }
+ return 0;
+}
+
+enum MountPointStateChange
+ {
+ MountPointRecentlyMounted,
+ MountPointRecentlyUnmounted,
+ MountPointStateUnchanged
+ };
+
+
+
+static enum MountPointStateChange
+get_mount_state (dev_t newdev)
+{
+ int new_is_present, new_was_present;
+
+ new_was_present = dev_present (newdev, mounted_devices, num_mounted_devices);
+ refresh_mounted_dev_list ();
+ new_is_present = dev_present (newdev, mounted_devices, num_mounted_devices);
+
+ if (new_was_present == new_is_present)
+ return MountPointStateUnchanged;
+ else if (new_is_present)
+ return MountPointRecentlyMounted;
+ else
+ return MountPointRecentlyUnmounted;
+}
+
+
+
+/* We stat()ed a directory, chdir()ed into it (we know this
+ * since direction is TraversingDown), stat()ed it again,
+ * and noticed that the device numbers are different. Check
+ * if the file system was recently mounted.
+ *
+ * If it was, it looks like chdir()ing into the directory
+ * caused a file system to be mounted. Maybe automount is
+ * running. Anyway, that's probably OK - but it happens
+ * only when we are moving downward.
+ *
+ * We also allow for the possibility that a similar thing
+ * has happened with the unmounting of a file system. This
+ * is much rarer, as it relies on an automounter timeout
+ * occurring at exactly the wrong moment.
+ */
+static enum WdSanityCheckFatality
+dirchange_is_fatal (const char *specific_what,
+ enum WdSanityCheckFatality isfatal,
+ int silent,
+ struct stat *newinfo)
+{
+ enum MountPointStateChange transition = get_mount_state (newinfo->st_dev);
+ switch (transition)
+ {
+ case MountPointRecentlyUnmounted:
+ isfatal = NON_FATAL_IF_SANITY_CHECK_FAILS;
+ if (!silent)
+ {
+ error (0, 0,
+ _("WARNING: file system %s has recently been unmounted."),
+ safely_quote_err_filename (0, specific_what));
+ }
+ break;
+
+ case MountPointRecentlyMounted:
+ isfatal = NON_FATAL_IF_SANITY_CHECK_FAILS;
+ if (!silent)
+ {
+ error (0, 0,
+ _("WARNING: file system %s has recently been mounted."),
+ safely_quote_err_filename (0, specific_what));
+ }
+ break;
+
+ case MountPointStateUnchanged:
+ /* leave isfatal as it is */
+ break;
+ }
+
+ return isfatal;
+}
+
+
+#endif
+
+
+
+/* Examine the results of the stat() of a directory from before we
+ * entered or left it, with the results of stat()ing it afterward. If
+ * these are different, the file system tree has been modified while we
+ * were traversing it. That might be an attempt to use a race
+ * condition to persuade find to do something it didn't intend
+ * (e.g. an attempt by an ordinary user to exploit the fact that root
+ * sometimes runs find on the whole file system). However, this can
+ * also happen if automount is running (certainly on Solaris). With
+ * automount, moving into a directory can cause a file system to be
+ * mounted there.
+ *
+ * To cope sensibly with this, we will raise an error if we see the
+ * device number change unless we are chdir()ing into a subdirectory,
+ * and the directory we moved into has been mounted or unmounted "recently".
+ * Here "recently" means since we started "find" or we last re-read
+ * the /etc/mnttab file.
+ *
+ * If the device number does not change but the inode does, that is a
+ * problem.
+ *
+ * If the device number and inode are both the same, we are happy.
+ *
+ * If a file system is (un)mounted as we chdir() into the directory, that
+ * may mean that we're now examining a section of the file system that might
+ * have been excluded from consideration (via -prune or -quit for example).
+ * Hence we print a warning message to indicate that the output of find
+ * might be inconsistent due to the change in the file system.
+ */
+static bool
+wd_sanity_check (const char *thing_to_stat,
+ const char *progname,
+ const char *what,
+ dev_t old_dev,
+ ino_t old_ino,
+ struct stat *newinfo,
+ int parent,
+ int line_no,
+ enum TraversalDirection direction,
+ enum WdSanityCheckFatality isfatal,
+ bool *changed) /* output parameter */
+{
+ const char *fstype;
+ char *specific_what = NULL;
+ int silent = 0;
+ const char *current_dir = ".";
+
+ *changed = false;
+
+ set_stat_placeholders (newinfo);
+ if ((*options.xstat) (current_dir, newinfo) != 0)
+ fatal_target_file_error (errno, thing_to_stat);
+
+ if (old_dev != newinfo->st_dev)
+ {
+ *changed = true;
+ specific_what = specific_dirname (what);
+ fstype = filesystem_type (newinfo, current_dir);
+ silent = fs_likely_to_be_automounted (fstype);
+
+ /* This condition is rare, so once we are here it is
+ * reasonable to perform an expensive computation to
+ * determine if we should continue or fail.
+ */
+ if (TraversingDown == direction)
+ {
+#ifdef STAT_MOUNTPOINTS
+ isfatal = dirchange_is_fatal (specific_what,isfatal,silent,newinfo);
+#else
+ (void) silent;
+ isfatal = RETRY_IF_SANITY_CHECK_FAILS;
+#endif
+ }
+
+ switch (isfatal)
+ {
+ case FATAL_IF_SANITY_CHECK_FAILS:
+ {
+ fstype = filesystem_type (newinfo, current_dir);
+ error (EXIT_FAILURE, 0,
+ _("%s%s changed during execution of %s (old device number %ld, new device number %ld, file system type is %s) [ref %ld]"),
+ safely_quote_err_filename (0, specific_what),
+ parent ? "/.." : "",
+ safely_quote_err_filename (1, progname),
+ (long) old_dev,
+ (long) newinfo->st_dev,
+ fstype,
+ (long)line_no);
+ /*NOTREACHED*/
+ return false;
+ }
+
+ case NON_FATAL_IF_SANITY_CHECK_FAILS:
+ {
+ /* Since the device has changed under us, the inode number
+ * will almost certainly also be different. However, we have
+ * already decided that this is not a problem. Hence we return
+ * without checking the inode number.
+ */
+ free (specific_what);
+ return true;
+ }
+
+ case RETRY_IF_SANITY_CHECK_FAILS:
+ return false;
+ }
+ }
+
+ /* Device number was the same, check if the inode has changed. */
+ if (old_ino != newinfo->st_ino)
+ {
+ *changed = true;
+ specific_what = specific_dirname (what);
+ fstype = filesystem_type (newinfo, current_dir);
+
+ error ((isfatal == FATAL_IF_SANITY_CHECK_FAILS) ? 1 : 0,
+ 0, /* no relevant errno value */
+ _("%s%s changed during execution of %s "
+ "(old inode number %" PRIuMAX ", new inode number %" PRIuMAX
+ ", file system type is %s) [ref %ld]"),
+ safely_quote_err_filename (0, specific_what),
+ parent ? "/.." : "",
+ safely_quote_err_filename (1, progname),
+ (uintmax_t) old_ino,
+ (uintmax_t) newinfo->st_ino,
+ fstype,
+ (long)line_no);
+ free (specific_what);
+ return false;
+ }
+
+ return true;
+}
+
+enum SafeChdirStatus
+ {
+ SafeChdirOK,
+ SafeChdirFailSymlink,
+ SafeChdirFailNotDir,
+ SafeChdirFailStat,
+ SafeChdirFailWouldBeUnableToReturn,
+ SafeChdirFailChdirFailed,
+ SafeChdirFailNonexistent,
+ SafeChdirFailDestUnreadable
+ };
+
+/* Safely perform a change in directory. We do this by calling
+ * lstat() on the subdirectory, using chdir() to move into it, and
+ * then lstat()ing ".". We compare the results of the two stat calls
+ * to see if they are consistent. If not, we sound the alarm.
+ *
+ * If following_links() is true, we do follow symbolic links.
+ */
+static enum SafeChdirStatus
+safely_chdir_lstat (const char *dest,
+ enum TraversalDirection direction,
+ struct stat *statbuf_dest,
+ enum ChdirSymlinkHandling symlink_follow_option,
+ bool *did_stat)
+{
+ struct stat statbuf_arrived;
+ int rv, dotfd=-1;
+ int saved_errno; /* specific_dirname() changes errno. */
+ bool rv_set = false;
+ bool statflag = false;
+ int tries = 0;
+ enum WdSanityCheckFatality isfatal = RETRY_IF_SANITY_CHECK_FAILS;
+
+ saved_errno = errno = 0;
+
+ dotfd = open_cloexec (".", O_RDONLY
+#if defined O_LARGEFILE
+ |O_LARGEFILE
+#endif
+ );
+
+ /* We jump back to here if wd_sanity_check()
+ * recoverably triggers an alert.
+ */
+ retry:
+ ++tries;
+
+ if (dotfd >= 0)
+ {
+ /* Stat the directory we're going to. */
+ set_stat_placeholders (statbuf_dest);
+ if (0 == options.xstat (dest, statbuf_dest))
+ {
+ statflag = true;
+
+#ifdef S_ISLNK
+ /* symlink_follow_option might be set to SymlinkFollowOk, which
+ * would allow us to chdir() into a symbolic link. This is
+ * only useful for the case where the directory we're
+ * chdir()ing into is the basename of a command line
+ * argument, for example where "foo/bar/baz" is specified on
+ * the command line. When -P is in effect (the default),
+ * baz will not be followed if it is a symlink, but if bar
+ * is a symlink, it _should_ be followed. Hence we need the
+ * ability to override the policy set by following_links().
+ */
+ if (!following_links () && S_ISLNK(statbuf_dest->st_mode))
+ {
+ /* We're not supposed to be following links, but this is
+ * a link. Check symlink_follow_option to see if we should
+ * make a special exception.
+ */
+ if (symlink_follow_option == SymlinkFollowOk)
+ {
+ /* We need to re-stat() the file so that the
+ * sanity check can pass.
+ */
+ if (0 != stat (dest, statbuf_dest))
+ {
+ rv = SafeChdirFailNonexistent;
+ rv_set = true;
+ saved_errno = errno;
+ goto fail;
+ }
+ statflag = true;
+ }
+ else
+ {
+ /* Not following symlinks, so the attempt to
+ * chdir() into a symlink should be prevented.
+ */
+ rv = SafeChdirFailSymlink;
+ rv_set = true;
+ saved_errno = 0; /* silence the error message */
+ goto fail;
+ }
+ }
+#endif
+#ifdef S_ISDIR
+ /* Although the immediately following chdir() would detect
+ * the fact that this is not a directory for us, this would
+ * result in an extra system call that fails. Anybody
+ * examining the system-call trace should ideally not be
+ * concerned that something is actually failing.
+ */
+ if (!S_ISDIR(statbuf_dest->st_mode))
+ {
+ rv = SafeChdirFailNotDir;
+ rv_set = true;
+ saved_errno = 0; /* silence the error message */
+ goto fail;
+ }
+#endif
+
+ if (options.debug_options & DebugSearch)
+ fprintf (stderr, "safely_chdir(): chdir(\"%s\")\n", dest);
+
+ if (0 == chdir (dest))
+ {
+ /* check we ended up where we wanted to go */
+ bool changed = false;
+ if (!wd_sanity_check (".", program_name, ".",
+ statbuf_dest->st_dev,
+ statbuf_dest->st_ino,
+ &statbuf_arrived,
+ 0, __LINE__, direction,
+ isfatal,
+ &changed))
+ {
+ /* Only allow one failure. */
+ if (RETRY_IF_SANITY_CHECK_FAILS == isfatal)
+ {
+ if (0 == fchdir (dotfd))
+ {
+ isfatal = FATAL_IF_SANITY_CHECK_FAILS;
+ goto retry;
+ }
+ else
+ {
+ /* Failed to return to original directory,
+ * but we know that the current working
+ * directory is not the one that we intend
+ * to be in. Since fchdir() failed, we
+ * can't recover from this and so this error
+ * is fatal.
+ */
+ error (EXIT_FAILURE, errno,
+ _("failed to return to parent directory"));
+ }
+ }
+ else
+ {
+ /* XXX: not sure what to use as an excuse here. */
+ rv = SafeChdirFailNonexistent;
+ rv_set = true;
+ saved_errno = 0;
+ goto fail;
+ }
+ }
+
+ close (dotfd);
+ return SafeChdirOK;
+ }
+ else
+ {
+ saved_errno = errno;
+ if (ENOENT == saved_errno)
+ {
+ rv = SafeChdirFailNonexistent;
+ rv_set = true;
+ if (options.ignore_readdir_race)
+ errno = 0; /* don't issue err msg */
+ }
+ else if (ENOTDIR == saved_errno)
+ {
+ /* This can happen if the we stat a directory,
+ * and then file system activity changes it into
+ * a non-directory.
+ */
+ saved_errno = 0; /* don't issue err msg */
+ rv = SafeChdirFailNotDir;
+ rv_set = true;
+ }
+ else
+ {
+ rv = SafeChdirFailChdirFailed;
+ rv_set = true;
+ }
+ goto fail;
+ }
+ }
+ else
+ {
+ saved_errno = errno;
+ rv = SafeChdirFailStat;
+ rv_set = true;
+
+ if ( (ENOENT == saved_errno) || (0 == state.curdepth))
+ saved_errno = 0; /* don't issue err msg */
+ goto fail;
+ }
+ }
+ else
+ {
+ /* We do not have read permissions on "." */
+ rv = SafeChdirFailWouldBeUnableToReturn;
+ rv_set = true;
+ goto fail;
+ }
+
+ /* This is the success path, so we clear errno. The caller probably
+ * won't be calling error() anyway.
+ */
+ saved_errno = 0;
+
+ /* We use the same exit path for success or failure.
+ * which has occurred is recorded in RV.
+ */
+ fail:
+ /* We do not call error() as this would result in a duplicate error
+ * message when the caller does the same thing.
+ */
+ if (saved_errno)
+ errno = saved_errno;
+
+ if (dotfd >= 0)
+ {
+ close (dotfd);
+ dotfd = -1;
+ }
+
+ *did_stat = statflag;
+ assert (rv_set);
+ return rv;
+}
+
+/* Safely change working directory to the specified subdirectory. If
+ * we are not allowed to follow symbolic links, we use open() with
+ * O_NOFOLLOW, followed by fchdir(). This ensures that we don't
+ * follow symbolic links (of course, we do follow them if the -L
+ * option is in effect).
+ */
+static enum SafeChdirStatus
+safely_chdir_nofollow (const char *dest,
+ enum TraversalDirection direction,
+ struct stat *statbuf_dest,
+ enum ChdirSymlinkHandling symlink_follow_option,
+ bool *did_stat)
+{
+ int extraflags, fd;
+
+ (void) direction;
+ (void) statbuf_dest;
+
+ extraflags = 0;
+ *did_stat = false;
+
+ switch (symlink_follow_option)
+ {
+ case SymlinkFollowOk:
+ extraflags = 0;
+ break;
+
+ case SymlinkHandleDefault:
+ if (following_links ())
+ extraflags = 0;
+ else
+ extraflags = O_NOFOLLOW; /* ... which may still be 0. */
+ break;
+ }
+
+ errno = 0;
+ fd = open (dest, O_RDONLY
+#if defined O_LARGEFILE
+ |O_LARGEFILE
+#endif
+#if defined O_CLOEXEC
+ |O_CLOEXEC
+#endif
+ |extraflags);
+ if (fd < 0)
+ {
+ switch (errno)
+ {
+ case ELOOP:
+ return SafeChdirFailSymlink; /* This is why we use O_NOFOLLOW */
+ case ENOENT:
+ return SafeChdirFailNonexistent;
+ default:
+ return SafeChdirFailDestUnreadable;
+ }
+ }
+
+ errno = 0;
+ if (0 == fchdir (fd))
+ {
+ close (fd);
+ return SafeChdirOK;
+ }
+ else
+ {
+ int saved_errno = errno;
+ close (fd);
+ errno = saved_errno;
+
+ switch (errno)
+ {
+ case ENOTDIR:
+ return SafeChdirFailNotDir;
+
+ case EACCES:
+ case EBADF: /* Shouldn't happen */
+ case EINTR:
+ case EIO:
+ default:
+ return SafeChdirFailChdirFailed;
+ }
+ }
+}
+
+static enum SafeChdirStatus
+safely_chdir (const char *dest,
+ enum TraversalDirection direction,
+ struct stat *statbuf_dest,
+ enum ChdirSymlinkHandling symlink_follow_option,
+ bool *did_stat)
+{
+ enum SafeChdirStatus result;
+
+ /* We're about to leave a directory. If there are any -execdir
+ * argument lists which have been built but have not yet been
+ * processed, do them now because they must be done in the same
+ * directory.
+ */
+ complete_pending_execdirs ();
+
+ /* gnulib defines O_NOFOLLOW to 0 if the OS doesn't have it. */
+ options.open_nofollow_available = !!O_NOFOLLOW;
+ if (options.open_nofollow_available)
+ {
+ result = safely_chdir_nofollow (dest, direction, statbuf_dest,
+ symlink_follow_option, did_stat);
+ if (SafeChdirFailDestUnreadable != result)
+ {
+ return result;
+ }
+ else
+ {
+ /* Savannah bug #15384: fall through to use safely_chdir_lstat
+ * if the directory is not readable.
+ */
+ /* Do nothing. */
+ }
+ }
+ /* Even if O_NOFOLLOW is available, we may need to use the alternative
+ * method, since parent of the start point may be executable but not
+ * readable.
+ */
+ return safely_chdir_lstat (dest, direction, statbuf_dest,
+ symlink_follow_option, did_stat);
+}
+
+
+
+/* Safely go back to the starting directory. */
+static void
+chdir_back (void)
+{
+ if (options.debug_options & DebugSearch)
+ fprintf (stderr, "chdir_back(): chdir to start point\n");
+
+ restore_cwd (initial_wd);
+}
+
+/* Move to the parent of a given directory and then call a function,
+ * restoring the cwd. Don't bother changing directory if the
+ * specified directory is a child of "." or is the root directory.
+ */
+static void
+at_top (char *pathname,
+ mode_t mode,
+ ino_t inum,
+ struct stat *pstat,
+ void (*action)(char *pathname,
+ char *basename,
+ int mode,
+ ino_t inum,
+ struct stat *pstat))
+{
+ int dirchange;
+ char *parent_dir = dir_name (pathname);
+ char *base = last_component (pathname);
+
+ state.curdepth = 0;
+ state.starting_path_length = strlen (pathname);
+
+ if (0 == *base
+ || 0 == strcmp (parent_dir, "."))
+ {
+ dirchange = 0;
+ base = pathname;
+ }
+ else
+ {
+ enum TraversalDirection direction;
+ enum SafeChdirStatus chdir_status;
+ struct stat st;
+ bool did_stat = false;
+
+ dirchange = 1;
+ if (0 == strcmp (base, ".."))
+ direction = TraversingUp;
+ else
+ direction = TraversingDown;
+
+ /* We pass SymlinkFollowOk to safely_chdir(), which allows it to
+ * chdir() into a symbolic link. This is only useful for the
+ * case where the directory we're chdir()ing into is the
+ * basename of a command line argument, for example where
+ * "foo/bar/baz" is specified on the command line. When -P is
+ * in effect (the default), baz will not be followed if it is a
+ * symlink, but if bar is a symlink, it _should_ be followed.
+ * Hence we need the ability to override the policy set by
+ * following_links().
+ */
+ chdir_status = safely_chdir (parent_dir, direction, &st, SymlinkFollowOk, &did_stat);
+ if (SafeChdirOK != chdir_status)
+ {
+ const char *what = (SafeChdirFailWouldBeUnableToReturn == chdir_status) ? "." : parent_dir;
+ if (errno)
+ error (0, errno, "%s",
+ safely_quote_err_filename (0, what));
+ else
+ error (0, 0, _("Failed to safely change directory into %s"),
+ safely_quote_err_filename (0, parent_dir));
+
+ /* We can't process this command-line argument. */
+ state.exit_status = 1;
+ return;
+ }
+ }
+
+ free (parent_dir);
+ parent_dir = NULL;
+
+ action (pathname, base, mode, inum, pstat);
+
+ if (dirchange)
+ {
+ chdir_back ();
+ }
+}
+
+
+static void do_process_top_dir (char *pathname,
+ char *base,
+ int mode,
+ ino_t inum,
+ struct stat *pstat)
+{
+ (void) pstat;
+
+ process_path (pathname, base, false, ".", mode, inum);
+ complete_pending_execdirs ();
+}
+
+static void
+do_process_predicate (char *pathname,
+ char *base,
+ int mode,
+ ino_t inum,
+ struct stat *pstat)
+{
+ (void) mode;
+ (void) inum;
+ state.rel_pathname = base; /* cwd_dir_fd was already set by safely_chdir */
+ apply_predicate (pathname, pstat, get_eval_tree ());
+}
+
+
+
+
+/* Descend PATHNAME, which is a command-line argument.
+
+ Actions like -execdir assume that we are in the
+ parent directory of the file we're examining,
+ and on entry to this function our working directory
+ is whatever it was when find was invoked. Therefore
+ If PATHNAME is "." we just leave things as they are.
+ Otherwise, we figure out what the parent directory is,
+ and move to that.
+*/
+static void
+process_top_path (char *pathname, mode_t mode, ino_t inum)
+{
+ at_top (pathname, mode, inum, NULL, do_process_top_dir);
+}
+
+
+/* Info on each directory in the current tree branch, to avoid
+ getting stuck in symbolic link loops. */
+static struct dir_id *dir_ids = NULL;
+/* Entries allocated in `dir_ids'. */
+static int dir_alloc = 0;
+/* Index in `dir_ids' of directory currently being searched.
+ This is always the last valid entry. */
+static int dir_curr = -1;
+/* (Arbitrary) number of entries to grow `dir_ids' by. */
+#define DIR_ALLOC_STEP 32
+
+
+
+/* We've detected a file system loop. This is caused by one of
+ * two things:
+ *
+ * 1. Option -L is in effect and we've hit a symbolic link that
+ * points to an ancestor. This is harmless. We won't traverse the
+ * symbolic link.
+ *
+ * 2. We have hit a real cycle in the directory hierarchy. In this
+ * case, we issue a diagnostic message (POSIX requires this) and we
+ * skip that directory entry.
+ */
+static void
+issue_loop_warning (const char *name, const char *pathname, int level)
+{
+ struct stat stbuf_link;
+ if (lstat (name, &stbuf_link) != 0)
+ stbuf_link.st_mode = S_IFREG;
+
+ if (S_ISLNK(stbuf_link.st_mode))
+ {
+ error (0, 0,
+ _("Symbolic link %s is part of a loop in the directory hierarchy; we have already visited the directory to which it points."),
+ safely_quote_err_filename (0, pathname));
+ /* XXX: POSIX appears to require that the exit status be non-zero if a
+ * diagnostic is issued.
+ */
+ }
+ else
+ {
+ int distance = 1 + (dir_curr-level);
+ /* We have found an infinite loop. POSIX requires us to
+ * issue a diagnostic. Usually we won't get to here
+ * because when the leaf optimisation is on, it will cause
+ * the subdirectory to be skipped. If /a/b/c/d is a hard
+ * link to /a/b, then the link count of /a/b/c is 2,
+ * because the ".." entry of /b/b/c/d points to /a, not
+ * to /a/b/c.
+ */
+ error (0, 0,
+ ngettext (
+ "Filesystem loop detected; %s has the same device number and inode as "
+ "a directory which is %d level higher in the file system hierarchy",
+ "Filesystem loop detected; %s has the same device number and inode as "
+ "a directory which is %d levels higher in the file system hierarchy",
+ (long)distance),
+ safely_quote_err_filename (0, pathname),
+ distance);
+ }
+}
+
+
+
+/* Recursively descend path PATHNAME, applying the predicates.
+ LEAF is true if PATHNAME is known to be in a directory that has no
+ more unexamined subdirectories, and therefore it is not a directory.
+ Knowing this allows us to avoid calling stat as long as possible for
+ leaf files.
+
+ NAME is PATHNAME relative to the current directory. We access NAME
+ but print PATHNAME.
+
+ PARENT is the path of the parent of NAME, relative to find's
+ starting directory.
+
+ Return nonzero iff PATHNAME is a directory. */
+
+static int
+process_path (char *pathname, char *name, bool leaf, char *parent,
+ mode_t mode, ino_t inum)
+{
+ struct stat stat_buf;
+ static dev_t root_dev; /* Device ID of current argument pathname. */
+ int i;
+ struct predicate *eval_tree;
+
+ eval_tree = get_eval_tree ();
+ /* Assume it is a non-directory initially. */
+ stat_buf.st_mode = 0;
+
+ /* The caller usually knows the inode number, either from readdir or
+ * a *stat call. We use that value (the caller passes 0 to indicate
+ * ignorance of the inode number).
+ */
+ stat_buf.st_ino = inum;
+
+ state.rel_pathname = name;
+ state.type = 0;
+ state.have_stat = false;
+ state.have_type = false;
+ state.already_issued_stat_error_msg = false;
+
+ if (!digest_mode (&mode, pathname, name, &stat_buf, leaf))
+ return 0;
+
+ if (!S_ISDIR (state.type))
+ {
+ if (state.curdepth >= options.mindepth)
+ apply_predicate (pathname, &stat_buf, eval_tree);
+ return 0;
+ }
+
+ /* From here on, we're working on a directory. */
+
+
+ /* Now we really need to stat the directory, even if we know the
+ * type, because we need information like struct stat.st_rdev.
+ */
+ if (get_statinfo (pathname, name, &stat_buf) != 0)
+ return 0;
+
+ state.have_stat = true;
+ mode = state.type = stat_buf.st_mode; /* use full info now that we have it. */
+ state.stop_at_current_level =
+ options.maxdepth >= 0
+ && state.curdepth >= options.maxdepth;
+
+ /* If we've already seen this directory on this branch,
+ don't descend it again. */
+ for (i = 0; i <= dir_curr; i++)
+ if (stat_buf.st_ino == dir_ids[i].ino &&
+ stat_buf.st_dev == dir_ids[i].dev)
+ {
+ state.stop_at_current_level = true;
+ issue_loop_warning (name, pathname, i);
+ }
+
+ if (dir_alloc <= ++dir_curr)
+ {
+ dir_alloc += DIR_ALLOC_STEP;
+ dir_ids = (struct dir_id *)
+ xrealloc ((char *) dir_ids, dir_alloc * sizeof (struct dir_id));
+ }
+ dir_ids[dir_curr].ino = stat_buf.st_ino;
+ dir_ids[dir_curr].dev = stat_buf.st_dev;
+
+ if (options.stay_on_filesystem)
+ {
+ if (state.curdepth == 0)
+ root_dev = stat_buf.st_dev;
+ else if (stat_buf.st_dev != root_dev)
+ state.stop_at_current_level = true;
+ }
+
+ if (options.do_dir_first && state.curdepth >= options.mindepth)
+ apply_predicate (pathname, &stat_buf, eval_tree);
+
+ if (options.debug_options & DebugSearch)
+ fprintf (stderr, "pathname = %s, stop_at_current_level = %d\n",
+ pathname, state.stop_at_current_level);
+
+ if (state.stop_at_current_level == false)
+ {
+ /* Scan directory on disk. */
+ process_dir (pathname, name, strlen (pathname), &stat_buf, parent);
+ }
+
+ if (options.do_dir_first == false && state.curdepth >= options.mindepth)
+ {
+ /* The fields in 'state' are now out of date. Correct them.
+ */
+ if (!digest_mode (&mode, pathname, name, &stat_buf, leaf))
+ return 0;
+
+ if (0 == dir_curr)
+ {
+ at_top (pathname, mode, stat_buf.st_ino, &stat_buf,
+ do_process_predicate);
+ }
+ else
+ {
+ do_process_predicate (pathname, name, mode, stat_buf.st_ino,
+ &stat_buf);
+ }
+ }
+
+ dir_curr--;
+
+ return 1;
+}
+
+
+/* Scan directory PATHNAME and recurse through process_path for each entry.
+
+ PATHLEN is the length of PATHNAME.
+
+ NAME is PATHNAME relative to the current directory.
+
+ STATP is the results of *options.xstat on it.
+
+ PARENT is the path of the parent of NAME, relative to find's
+ starting directory. */
+
+static void
+process_dir (char *pathname, char *name, int pathlen, const struct stat *statp, char *parent)
+{
+ int subdirs_left; /* Number of unexamined subdirs in PATHNAME. */
+ bool subdirs_unreliable; /* if true, cannot use dir link count as subdir limif (if false, it may STILL be unreliable) */
+ struct stat stat_buf;
+ size_t dircount = 0u;
+ DIR *dirp;
+
+ if (statp->st_nlink < 2)
+ {
+ subdirs_unreliable = true;
+ subdirs_left = 0;
+ }
+ else
+ {
+ subdirs_unreliable = false; /* not necessarily right */
+ subdirs_left = statp->st_nlink - 2; /* Account for name and ".". */
+ }
+
+ errno = 0;
+ dirp = opendir_safer (name);
+
+ if (dirp == NULL)
+ {
+ assert (errno != 0);
+ error (0, errno, "%s", safely_quote_err_filename (0, pathname));
+ state.exit_status = 1;
+ }
+ else
+ {
+ char *cur_path; /* Full path of each file to process. */
+ char *cur_name; /* Base name of each file to process. */
+ unsigned cur_path_size; /* Bytes allocated for `cur_path'. */
+ register unsigned file_len; /* Length of each path to process. */
+ register unsigned pathname_len; /* PATHLEN plus trailing '/'. */
+ bool did_stat = false;
+
+ if (pathname[pathlen - 1] == '/')
+ pathname_len = pathlen + 1; /* For '\0'; already have '/'. */
+ else
+ pathname_len = pathlen + 2; /* For '/' and '\0'. */
+ cur_path_size = 0;
+ cur_path = NULL;
+
+ /* We're about to leave the directory. If there are any
+ * -execdir argument lists which have been built but have not
+ * yet been processed, do them now because they must be done in
+ * the same directory.
+ */
+ complete_pending_execdirs ();
+
+ if (strcmp (name, "."))
+ {
+ enum SafeChdirStatus status = safely_chdir (name, TraversingDown, &stat_buf, SymlinkHandleDefault, &did_stat);
+ switch (status)
+ {
+ case SafeChdirOK:
+ /* If there had been a change but wd_sanity_check()
+ * accepted it, we need to accept that on the
+ * way back up as well, so modify our record
+ * of what we think we should see later.
+ * If there was no change, the assignments are a no-op.
+ *
+ * However, before performing the assignment, we need to
+ * check that we have the stat information. If O_NOFOLLOW
+ * is available, safely_chdir() will not have needed to use
+ * stat(), and so stat_buf will just contain random data.
+ */
+ if (!did_stat)
+ {
+ /* If there is a link we need to follow it. Hence
+ * the direct call to stat() not through (options.xstat)
+ */
+ set_stat_placeholders (&stat_buf);
+ if (0 != stat (".", &stat_buf))
+ break; /* skip the assignment. */
+ }
+ dir_ids[dir_curr].dev = stat_buf.st_dev;
+ dir_ids[dir_curr].ino = stat_buf.st_ino;
+
+ break;
+
+ case SafeChdirFailWouldBeUnableToReturn:
+ error (0, errno, ".");
+ state.exit_status = 1;
+ break;
+
+ case SafeChdirFailNonexistent:
+ case SafeChdirFailDestUnreadable:
+ case SafeChdirFailStat:
+ case SafeChdirFailNotDir:
+ case SafeChdirFailChdirFailed:
+ error (0, errno, "%s",
+ safely_quote_err_filename (0, pathname));
+ state.exit_status = 1;
+ return;
+
+ case SafeChdirFailSymlink:
+ error (0, 0,
+ _("warning: not following the symbolic link %s"),
+ safely_quote_err_filename (0, pathname));
+ state.exit_status = 1;
+ return;
+ }
+ }
+
+ while (1)
+ {
+ const char *namep;
+ mode_t mode = 0;
+ const struct dirent *dp;
+
+ /* We reset errno here to distinguish between end-of-directory and an error */
+ errno = 0;
+ dp = readdir (dirp);
+ if (NULL == dp)
+ {
+ if (errno)
+ {
+ /* an error occurred, but we are not yet at the end
+ of the directory stream. */
+ error (0, errno, "%s", safely_quote_err_filename (0, pathname));
+ continue;
+ }
+ else
+ {
+ break; /* End of the directory stream. */
+ }
+ }
+ else
+ {
+ namep = dp->d_name;
+ /* Skip "", ".", and "..". "" is returned by at least one buggy
+ implementation: Solaris 2.4 readdir on NFS file systems. */
+ if (!namep[0] ||
+ (namep[0] == '.' && (namep[1] == 0 ||
+ (namep[1] == '.' && namep[2] == 0))))
+ continue;
+ }
+
+#if defined HAVE_STRUCT_DIRENT_D_TYPE
+ if (dp->d_type != DT_UNKNOWN)
+ mode = type_to_mode (dp->d_type);
+#endif
+
+ /* Append this directory entry's name to the path being searched. */
+ file_len = pathname_len + strlen (namep);
+ if (file_len > cur_path_size)
+ {
+ while (file_len > cur_path_size)
+ cur_path_size += 1024;
+ free (cur_path);
+ cur_path = xmalloc (cur_path_size);
+ strcpy (cur_path, pathname);
+ cur_path[pathname_len - 2] = '/';
+ }
+ cur_name = cur_path + pathname_len - 1;
+ strcpy (cur_name, namep);
+
+ state.curdepth++;
+ if (!options.no_leaf_check && !subdirs_unreliable)
+ {
+ if (mode && S_ISDIR(mode) && (subdirs_left == 0))
+ {
+ /* This is a subdirectory, but the number of directories we
+ * have found now exceeds the number we would expect given
+ * the hard link count on the parent. This is likely to be
+ * a bug in the file system driver (e.g. Linux's
+ * /proc file system) or may just be a fact that the OS
+ * doesn't really handle hard links with Unix semantics.
+ * In the latter case, -noleaf should be used routinely.
+ */
+ error (0, 0, _("WARNING: Hard link count is wrong for %s (saw only st_nlink=%" PRIuMAX " but we already saw %" PRIuMAX " subdirectories): this may be a bug in your file system driver. Automatically turning on find's -noleaf option. Earlier results may have failed to include directories that should have been searched."),
+ safely_quote_err_filename(0, pathname),
+ (uintmax_t) statp->st_nlink,
+ (uintmax_t) dircount);
+ state.exit_status = 1; /* We know the result is wrong, now */
+ options.no_leaf_check = true; /* Don't make same
+ mistake again */
+ subdirs_unreliable = 1;
+ subdirs_left = 1; /* band-aid for this iteration. */
+ }
+
+ /* Normal case optimization. On normal Unix
+ file systems, a directory that has no subdirectories
+ has two links: its name, and ".". Any additional
+ links are to the ".." entries of its subdirectories.
+ Once we have processed as many subdirectories as
+ there are additional links, we know that the rest of
+ the entries are non-directories -- in other words,
+ leaf files. */
+ {
+ int count;
+ count = process_path (cur_path, cur_name,
+ subdirs_left == 0, pathname,
+ mode, D_INO(dp));
+ subdirs_left -= count;
+ dircount += count;
+ }
+ }
+ else
+ {
+ /* There might be weird (e.g., CD-ROM or MS-DOS) file systems
+ mounted, which don't have Unix-like directory link counts. */
+ process_path (cur_path, cur_name, false, pathname, mode,
+ D_INO(dp));
+ }
+
+ state.curdepth--;
+ }
+
+
+ /* We're about to leave the directory. If there are any
+ * -execdir argument lists which have been built but have not
+ * yet been processed, do them now because they must be done in
+ * the same directory.
+ */
+ complete_pending_execdirs ();
+
+ if (strcmp (name, "."))
+ {
+ enum SafeChdirStatus status;
+
+ /* We could go back and do the next command-line arg
+ instead, maybe using longjmp. */
+ char const *dir;
+ bool deref = following_links () ? true : false;
+
+ if ( (state.curdepth>0) && !deref)
+ dir = "..";
+ else
+ {
+ chdir_back ();
+ dir = parent;
+ }
+
+ did_stat = false;
+ status = safely_chdir (dir, TraversingUp, &stat_buf, SymlinkHandleDefault, &did_stat);
+ switch (status)
+ {
+ case SafeChdirOK:
+ break;
+
+ case SafeChdirFailWouldBeUnableToReturn:
+ error (EXIT_FAILURE, errno, ".");
+ return;
+
+ case SafeChdirFailNonexistent:
+ case SafeChdirFailDestUnreadable:
+ case SafeChdirFailStat:
+ case SafeChdirFailSymlink:
+ case SafeChdirFailNotDir:
+ case SafeChdirFailChdirFailed:
+ error (EXIT_FAILURE, errno,
+ "%s", safely_quote_err_filename (0, pathname));
+ return;
+ }
+ }
+
+ free (cur_path);
+ CLOSEDIR (dirp);
+ }
+
+ if (subdirs_unreliable)
+ {
+ /* Make sure we hasn't used the variable subdirs_left if we knew
+ * we shouldn't do so.
+ */
+ assert (0 == subdirs_left || options.no_leaf_check);
+ }
+}
diff --git a/find/parser.c b/find/parser.c
new file mode 100644
index 0000000..b57cdda
--- /dev/null
+++ b/find/parser.c
@@ -0,0 +1,3424 @@
+/* parser.c -- convert the command line args into an expression tree.
+ Copyright (C) 1990, 1991, 1992, 1993, 1994, 2000, 2001, 2003, 2004,
+ 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software Foundation,
+ Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/* config.h must always come first. */
+#include <config.h>
+
+/* system headers. */
+#include <assert.h>
+#include <ctype.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <grp.h>
+#include <math.h>
+#include <pwd.h>
+#include <regex.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
+
+/* gnulib headers. */
+#include "error.h"
+#include "fnmatch.h"
+#include "fts_.h"
+#include "gettext.h"
+#include "modechange.h"
+#include "mountlist.h"
+#include "parse-datetime.h"
+#include "print.h"
+#include "quotearg.h"
+#include "regextype.h"
+#include "safe-atoi.h"
+#include "selinux-at.h"
+#include "splitstring.h"
+#include "stat-time.h"
+#include "xalloc.h"
+#include "xstrtod.h"
+#include "xstrtol.h"
+
+/* find headers. */
+#include "buildcmd.h"
+#include "defs.h"
+#include "fdleak.h"
+#include "findutils-version.h"
+
+
+
+
+#if ENABLE_NLS
+# include <libintl.h>
+# define _(Text) gettext (Text)
+#else
+# define _(Text) Text
+#endif
+#ifdef gettext_noop
+# define N_(String) gettext_noop (String)
+#else
+/* See locate.c for explanation as to why not use (String) */
+# define N_(String) String
+#endif
+
+#ifndef HAVE_ENDGRENT
+#define endgrent ()
+#endif
+#ifndef HAVE_ENDPWENT
+#define endpwent ()
+#endif
+
+static bool parse_accesscheck (const struct parser_table*, char *argv[], int *arg_ptr);
+static bool parse_amin (const struct parser_table*, char *argv[], int *arg_ptr);
+static bool parse_and (const struct parser_table*, char *argv[], int *arg_ptr);
+static bool parse_anewer (const struct parser_table*, char *argv[], int *arg_ptr);
+static bool parse_cmin (const struct parser_table*, char *argv[], int *arg_ptr);
+static bool parse_cnewer (const struct parser_table*, char *argv[], int *arg_ptr);
+static bool parse_comma (const struct parser_table*, char *argv[], int *arg_ptr);
+static bool parse_daystart (const struct parser_table*, char *argv[], int *arg_ptr);
+static bool parse_delete (const struct parser_table*, char *argv[], int *arg_ptr);
+static bool parse_d (const struct parser_table*, char *argv[], int *arg_ptr);
+static bool parse_depth (const struct parser_table*, char *argv[], int *arg_ptr);
+static bool parse_empty (const struct parser_table*, char *argv[], int *arg_ptr);
+static bool parse_exec (const struct parser_table*, char *argv[], int *arg_ptr);
+static bool parse_execdir (const struct parser_table*, char *argv[], int *arg_ptr);
+static bool parse_false (const struct parser_table*, char *argv[], int *arg_ptr);
+static bool parse_fls (const struct parser_table*, char *argv[], int *arg_ptr);
+static bool parse_fprintf (const struct parser_table*, char *argv[], int *arg_ptr);
+static bool parse_follow (const struct parser_table*, char *argv[], int *arg_ptr);
+static bool parse_fprint (const struct parser_table*, char *argv[], int *arg_ptr);
+static bool parse_fprint0 (const struct parser_table*, char *argv[], int *arg_ptr);
+static bool parse_fstype (const struct parser_table*, char *argv[], int *arg_ptr);
+static bool parse_gid (const struct parser_table*, char *argv[], int *arg_ptr);
+static bool parse_group (const struct parser_table*, char *argv[], int *arg_ptr);
+static bool parse_help (const struct parser_table*, char *argv[], int *arg_ptr);
+static bool parse_ilname (const struct parser_table*, char *argv[], int *arg_ptr);
+static bool parse_iname (const struct parser_table*, char *argv[], int *arg_ptr);
+static bool parse_inum (const struct parser_table*, char *argv[], int *arg_ptr);
+static bool parse_ipath (const struct parser_table*, char *argv[], int *arg_ptr);
+static bool parse_iregex (const struct parser_table*, char *argv[], int *arg_ptr);
+static bool parse_iwholename (const struct parser_table*, char *argv[], int *arg_ptr);
+static bool parse_links (const struct parser_table*, char *argv[], int *arg_ptr);
+static bool parse_lname (const struct parser_table*, char *argv[], int *arg_ptr);
+static bool parse_ls (const struct parser_table*, char *argv[], int *arg_ptr);
+static bool parse_maxdepth (const struct parser_table*, char *argv[], int *arg_ptr);
+static bool parse_mindepth (const struct parser_table*, char *argv[], int *arg_ptr);
+static bool parse_mmin (const struct parser_table*, char *argv[], int *arg_ptr);
+static bool parse_name (const struct parser_table*, char *argv[], int *arg_ptr);
+static bool parse_negate (const struct parser_table*, char *argv[], int *arg_ptr);
+static bool parse_newer (const struct parser_table*, char *argv[], int *arg_ptr);
+static bool parse_newerXY (const struct parser_table*, char *argv[], int *arg_ptr);
+static bool parse_noleaf (const struct parser_table*, char *argv[], int *arg_ptr);
+static bool parse_nogroup (const struct parser_table*, char *argv[], int *arg_ptr);
+static bool parse_nouser (const struct parser_table*, char *argv[], int *arg_ptr);
+static bool parse_nowarn (const struct parser_table*, char *argv[], int *arg_ptr);
+static bool parse_ok (const struct parser_table*, char *argv[], int *arg_ptr);
+static bool parse_okdir (const struct parser_table*, char *argv[], int *arg_ptr);
+static bool parse_or (const struct parser_table*, char *argv[], int *arg_ptr);
+static bool parse_path (const struct parser_table*, char *argv[], int *arg_ptr);
+static bool parse_perm (const struct parser_table*, char *argv[], int *arg_ptr);
+static bool parse_print0 (const struct parser_table*, char *argv[], int *arg_ptr);
+static bool parse_printf (const struct parser_table*, char *argv[], int *arg_ptr);
+static bool parse_prune (const struct parser_table*, char *argv[], int *arg_ptr);
+static bool parse_regex (const struct parser_table*, char *argv[], int *arg_ptr);
+static bool parse_regextype (const struct parser_table*, char *argv[], int *arg_ptr);
+static bool parse_samefile (const struct parser_table*, char *argv[], int *arg_ptr);
+static bool parse_size (const struct parser_table*, char *argv[], int *arg_ptr);
+static bool parse_time (const struct parser_table*, char *argv[], int *arg_ptr);
+static bool parse_true (const struct parser_table*, char *argv[], int *arg_ptr);
+static bool parse_type (const struct parser_table*, char *argv[], int *arg_ptr);
+static bool parse_uid (const struct parser_table*, char *argv[], int *arg_ptr);
+static bool parse_used (const struct parser_table*, char *argv[], int *arg_ptr);
+static bool parse_user (const struct parser_table*, char *argv[], int *arg_ptr);
+static bool parse_version (const struct parser_table*, char *argv[], int *arg_ptr);
+static bool parse_wholename (const struct parser_table*, char *argv[], int *arg_ptr);
+static bool parse_xdev (const struct parser_table*, char *argv[], int *arg_ptr);
+static bool parse_ignore_race (const struct parser_table*, char *argv[], int *arg_ptr);
+static bool parse_noignore_race (const struct parser_table*, char *argv[], int *arg_ptr);
+static bool parse_warn (const struct parser_table*, char *argv[], int *arg_ptr);
+static bool parse_xtype (const struct parser_table*, char *argv[], int *arg_ptr);
+static bool parse_quit (const struct parser_table*, char *argv[], int *arg_ptr);
+static bool parse_context (const struct parser_table*, char *argv[], int *arg_ptr);
+#if 0
+static bool parse_show_control_chars (const struct parser_table*, char *argv[], int *arg_ptr);
+#endif
+
+
+
+static bool insert_type (char **argv, int *arg_ptr,
+ const struct parser_table *entry,
+ PRED_FUNC which_pred);
+static bool insert_regex (char *argv[], int *arg_ptr,
+ const struct parser_table *entry,
+ int regex_options);
+static bool insert_exec_ok (const char *action,
+ const struct parser_table *entry,
+ char *argv[],
+ int *arg_ptr);
+static bool get_comp_type (const char **str,
+ enum comparison_type *comp_type);
+static bool get_relative_timestamp (const char *str,
+ struct time_val *tval,
+ struct timespec origin,
+ double sec_per_unit,
+ const char *overflowmessage);
+static bool get_num (const char *str,
+ uintmax_t *num,
+ enum comparison_type *comp_type);
+static struct predicate* insert_num (char *argv[], int *arg_ptr,
+ const struct parser_table *entry);
+static void open_output_file (const char *path, struct format_val *p);
+static void open_stdout (struct format_val *p);
+static bool stream_is_tty(FILE *fp);
+static bool parse_noop (const struct parser_table* entry,
+ char **argv, int *arg_ptr);
+
+#define PASTE(x,y) x##y
+
+
+#define PARSE_OPTION(what,suffix) \
+ { (ARG_OPTION), (what), PASTE(parse_,suffix), NULL }
+
+#define PARSE_POSOPT(what,suffix) \
+ { (ARG_POSITIONAL_OPTION), (what), PASTE(parse_,suffix), NULL }
+
+#define PARSE_TEST(what,suffix) \
+ { (ARG_TEST), (what), PASTE(parse_,suffix), PASTE(pred_,suffix) }
+
+#define PARSE_TEST_NP(what,suffix) \
+ { (ARG_TEST), (what), PASTE(parse_,suffix), NULL }
+
+#define PARSE_ACTION(what,suffix) \
+ { (ARG_ACTION), (what), PASTE(parse_,suffix), PASTE(pred_,suffix) }
+
+#define PARSE_PUNCTUATION(what,suffix) \
+ { (ARG_PUNCTUATION), (what), PASTE(parse_,suffix), PASTE(pred_,suffix) }
+
+
+/* Predicates we cannot handle in the usual way. If you add an entry
+ * to this table, double-check the switch statement in
+ * pred_sanity_check() to make sure that the new case is being
+ * correctly handled.
+ */
+static struct parser_table const parse_entry_newerXY =
+ {
+ ARG_SPECIAL_PARSE, "newerXY", parse_newerXY, pred_newerXY /* BSD */
+ };
+
+/* GNU find predicates that are not mentioned in POSIX.2 are marked `GNU'.
+ If they are in some Unix versions of find, they are marked `Unix'. */
+
+static struct parser_table const parse_table[] =
+{
+ PARSE_PUNCTUATION("!", negate), /* POSIX */
+ PARSE_PUNCTUATION("not", negate), /* GNU */
+ PARSE_PUNCTUATION("(", openparen), /* POSIX */
+ PARSE_PUNCTUATION(")", closeparen), /* POSIX */
+ PARSE_PUNCTUATION(",", comma), /* GNU */
+ PARSE_PUNCTUATION("a", and), /* POSIX */
+ PARSE_TEST ("amin", amin), /* GNU */
+ PARSE_PUNCTUATION("and", and), /* GNU */
+ PARSE_TEST ("anewer", anewer), /* GNU */
+ {ARG_TEST, "atime", parse_time, pred_atime}, /* POSIX */
+ PARSE_TEST ("cmin", cmin), /* GNU */
+ PARSE_TEST ("cnewer", cnewer), /* GNU */
+ {ARG_TEST, "ctime", parse_time, pred_ctime}, /* POSIX */
+ PARSE_TEST ("context", context), /* GNU */
+ PARSE_POSOPT ("daystart", daystart), /* GNU */
+ PARSE_ACTION ("delete", delete), /* GNU, Mac OS, FreeBSD */
+ PARSE_OPTION ("d", d), /* Mac OS X, FreeBSD, NetBSD, OpenBSD, but deprecated in favour of -depth */
+ PARSE_OPTION ("depth", depth), /* POSIX */
+ PARSE_TEST ("empty", empty), /* GNU */
+ {ARG_ACTION, "exec", parse_exec, pred_exec}, /* POSIX */
+ {ARG_TEST, "executable", parse_accesscheck, pred_executable}, /* GNU, 4.3.0+ */
+ PARSE_ACTION ("execdir", execdir), /* *BSD, GNU */
+ PARSE_ACTION ("fls", fls), /* GNU */
+ PARSE_POSOPT ("follow", follow), /* GNU, Unix */
+ PARSE_ACTION ("fprint", fprint), /* GNU */
+ PARSE_ACTION ("fprint0", fprint0), /* GNU */
+ {ARG_ACTION, "fprintf", parse_fprintf, pred_fprintf}, /* GNU */
+ PARSE_TEST ("fstype", fstype), /* GNU, Unix */
+ PARSE_TEST ("gid", gid), /* GNU */
+ PARSE_TEST ("group", group), /* POSIX */
+ PARSE_OPTION ("ignore_readdir_race", ignore_race), /* GNU */
+ PARSE_TEST ("ilname", ilname), /* GNU */
+ PARSE_TEST ("iname", iname), /* GNU */
+ PARSE_TEST ("inum", inum), /* GNU, Unix */
+ PARSE_TEST ("ipath", ipath), /* GNU, deprecated in favour of iwholename */
+ PARSE_TEST_NP ("iregex", iregex), /* GNU */
+ PARSE_TEST_NP ("iwholename", iwholename), /* GNU */
+ PARSE_TEST ("links", links), /* POSIX */
+ PARSE_TEST ("lname", lname), /* GNU */
+ PARSE_ACTION ("ls", ls), /* GNU, Unix */
+ PARSE_OPTION ("maxdepth", maxdepth), /* GNU */
+ PARSE_OPTION ("mindepth", mindepth), /* GNU */
+ PARSE_TEST ("mmin", mmin), /* GNU */
+ PARSE_OPTION ("mount", xdev), /* Unix */
+ {ARG_TEST, "mtime", parse_time, pred_mtime}, /* POSIX */
+ PARSE_TEST ("name", name),
+#ifdef UNIMPLEMENTED_UNIX
+ PARSE(ARG_UNIMPLEMENTED, "ncpio", ncpio), /* Unix */
+#endif
+ PARSE_TEST ("newer", newer), /* POSIX */
+ {ARG_TEST, "atime", parse_time, pred_atime}, /* POSIX */
+ PARSE_OPTION ("noleaf", noleaf), /* GNU */
+ PARSE_TEST ("nogroup", nogroup), /* POSIX */
+ PARSE_TEST ("nouser", nouser), /* POSIX */
+ PARSE_OPTION ("noignore_readdir_race", noignore_race), /* GNU */
+ PARSE_POSOPT ("nowarn", nowarn), /* GNU */
+ PARSE_POSOPT ("warn", warn), /* GNU */
+ PARSE_PUNCTUATION("o", or), /* POSIX */
+ PARSE_PUNCTUATION("or", or), /* GNU */
+ PARSE_ACTION ("ok", ok), /* POSIX */
+ PARSE_ACTION ("okdir", okdir), /* GNU (-execdir is BSD) */
+ PARSE_TEST ("path", path), /* GNU, HP-UX, RMS prefers wholename, but anyway soon POSIX */
+ PARSE_TEST ("perm", perm), /* POSIX */
+ PARSE_ACTION ("print", print), /* POSIX */
+ PARSE_ACTION ("print0", print0), /* GNU */
+ {ARG_ACTION, "printf", parse_printf, NULL}, /* GNU */
+ PARSE_ACTION ("prune", prune), /* POSIX */
+ PARSE_ACTION ("quit", quit), /* GNU */
+ {ARG_TEST, "readable", parse_accesscheck, pred_readable}, /* GNU, 4.3.0+ */
+ PARSE_TEST ("regex", regex), /* GNU */
+ PARSE_POSOPT ("regextype", regextype), /* GNU */
+ PARSE_TEST ("samefile", samefile), /* GNU */
+#if 0
+ PARSE_OPTION ("show-control-chars", show_control_chars), /* GNU, 4.3.0+ */
+#endif
+ PARSE_TEST ("size", size), /* POSIX */
+ PARSE_TEST ("type", type), /* POSIX */
+ PARSE_TEST ("uid", uid), /* GNU */
+ PARSE_TEST ("used", used), /* GNU */
+ PARSE_TEST ("user", user), /* POSIX */
+ PARSE_TEST_NP ("wholename", wholename), /* GNU, replaced -path, but anyway -path will soon be in POSIX */
+ {ARG_TEST, "writable", parse_accesscheck, pred_writable}, /* GNU, 4.3.0+ */
+ PARSE_OPTION ("xdev", xdev), /* POSIX */
+ PARSE_TEST ("xtype", xtype), /* GNU */
+#ifdef UNIMPLEMENTED_UNIX
+ /* It's pretty ugly for find to know about archive formats.
+ Plus what it could do with cpio archives is very limited.
+ Better to leave it out. */
+ PARSE(ARG_UNIMPLEMENTED, "cpio", cpio), /* Unix */
+#endif
+ /* gnulib's stdbool.h might have made true and false into macros,
+ * so we can't leave named 'true' and 'false' tokens, so we have
+ * to expeant the relevant entries longhand.
+ */
+ {ARG_TEST, "false", parse_false, pred_false}, /* GNU */
+ {ARG_TEST, "true", parse_true, pred_true }, /* GNU */
+ {ARG_NOOP, "noop", NULL, pred_true }, /* GNU, internal use only */
+
+ /* Various other cases that don't fit neatly into our macro scheme. */
+ {ARG_TEST, "help", parse_help, NULL}, /* GNU */
+ {ARG_TEST, "-help", parse_help, NULL}, /* GNU */
+ {ARG_TEST, "version", parse_version, NULL}, /* GNU */
+ {ARG_TEST, "-version", parse_version, NULL}, /* GNU */
+ {0, 0, 0, 0}
+};
+
+
+static const char *first_nonoption_arg = NULL;
+static const struct parser_table *noop = NULL;
+
+static int
+fallback_getfilecon (int fd, const char *name, security_context_t *p,
+ int prev_rv)
+{
+ /* Our original getfilecon () call failed. Perhaps we can't follow a
+ * symbolic link. If that might be the problem, lgetfilecon () the link.
+ * Otherwise, admit defeat. */
+ switch (errno)
+ {
+ case ENOENT:
+ case ENOTDIR:
+#ifdef DEBUG_STAT
+ fprintf (stderr, "fallback_getfilecon(): getfilecon(%s) failed; falling "
+ "back on lgetfilecon()\n", name);
+#endif
+ return lgetfileconat (fd, name, p);
+
+ case EACCES:
+ case EIO:
+ case ELOOP:
+ case ENAMETOOLONG:
+#ifdef EOVERFLOW
+ case EOVERFLOW: /* EOVERFLOW is not #defined on UNICOS. */
+#endif
+ default:
+ return prev_rv;
+ }
+}
+
+/* optionh_getfilecon () implements the getfilecon operation when the
+ * -H option is in effect.
+ *
+ * If the item to be examined is a command-line argument, we follow
+ * symbolic links. If the getfilecon () call fails on the command-line
+ * item, we fall back on the properties of the symbolic link.
+ *
+ * If the item to be examined is not a command-line argument, we
+ * examine the link itself. */
+static int
+optionh_getfilecon (int fd, const char *name, security_context_t *p)
+{
+ int rv;
+ if (0 == state.curdepth)
+ {
+ /* This file is from the command line; dereference the link (if it is
+ a link). */
+ rv = getfileconat (fd, name, p);
+ if (0 == rv)
+ return 0; /* success */
+ else
+ return fallback_getfilecon (fd, name, p, rv);
+ }
+ else
+ {
+ /* Not a file on the command line; do not dereference the link. */
+ return lgetfileconat (fd, name, p);
+ }
+}
+
+/* optionl_getfilecon () implements the getfilecon operation when the
+ * -L option is in effect. That option makes us examine the thing the
+ * symbolic link points to, not the symbolic link itself. */
+static int
+optionl_getfilecon (int fd, const char *name, security_context_t *p)
+{
+ int rv = getfileconat (fd, name, p);
+ if (0 == rv)
+ return 0; /* normal case. */
+ else
+ return fallback_getfilecon (fd, name, p, rv);
+}
+
+/* optionp_getfilecon () implements the stat operation when the -P
+ * option is in effect (this is also the default). That option makes
+ * us examine the symbolic link itself, not the thing it points to. */
+static int
+optionp_getfilecon (int fd, const char *name, security_context_t *p)
+{
+ return lgetfileconat (fd, name, p);
+}
+
+void
+check_option_combinations (const struct predicate *p)
+{
+ enum { seen_delete=1u, seen_prune=2u };
+ unsigned int predicates = 0u;
+
+ while (p)
+ {
+ if (p->pred_func == pred_delete)
+ predicates |= seen_delete;
+ else if (p->pred_func == pred_prune)
+ predicates |= seen_prune;
+ p = p->pred_next;
+ }
+
+ if ((predicates & seen_prune) && (predicates & seen_delete))
+ {
+ /* The user specified both -delete and -prune. One might test
+ * this by first doing
+ * find dirs .... -prune ..... -print
+ * to fnd out what's going to get deleted, and then switch to
+ * find dirs .... -prune ..... -delete
+ * once we are happy. Unfortunately, the -delete action also
+ * implicitly turns on -depth, which will affect the behaviour
+ * of -prune (in fact, it makes it a no-op). In this case we
+ * would like to prevent unfortunate accidents, so we require
+ * the user to have explicitly used -depth.
+ *
+ * We only get away with this because the -delete predicate is not
+ * in POSIX. If it was, we couldn't issue a fatal error here.
+ */
+ if (!options.explicit_depth)
+ {
+ /* This fixes Savannah bug #20865. */
+ error (EXIT_FAILURE, 0,
+ _("The -delete action automatically turns on -depth, "
+ "but -prune does nothing when -depth is in effect. "
+ "If you want to carry on anyway, just explicitly use "
+ "the -depth option."));
+ }
+ }
+}
+
+
+static const struct parser_table*
+get_noop (void)
+{
+ int i;
+ if (NULL == noop)
+ {
+ for (i = 0; parse_table[i].parser_name != 0; i++)
+ {
+ if (ARG_NOOP ==parse_table[i].type)
+ {
+ noop = &(parse_table[i]);
+ break;
+ }
+ }
+ }
+ return noop;
+}
+
+static int
+get_stat_Ytime (const struct stat *p,
+ char what,
+ struct timespec *ret)
+{
+ switch (what)
+ {
+ case 'a':
+ *ret = get_stat_atime (p);
+ return 1;
+ case 'B':
+ *ret = get_stat_birthtime (p);
+ return (ret->tv_nsec >= 0);
+ case 'c':
+ *ret = get_stat_ctime (p);
+ return 1;
+ case 'm':
+ *ret = get_stat_mtime (p);
+ return 1;
+ default:
+ assert (0);
+ abort ();
+ }
+}
+
+void
+set_follow_state (enum SymlinkOption opt)
+{
+ if (options.debug_options & DebugStat)
+ {
+ /* For DebugStat, the choice is made at runtime within debug_stat()
+ * by checking the contents of the symlink_handling variable.
+ */
+ options.xstat = debug_stat;
+ }
+ else
+ {
+ switch (opt)
+ {
+ case SYMLINK_ALWAYS_DEREF: /* -L */
+ options.xstat = optionl_stat;
+ options.x_getfilecon = optionl_getfilecon;
+ options.no_leaf_check = true;
+ break;
+
+ case SYMLINK_NEVER_DEREF: /* -P (default) */
+ options.xstat = optionp_stat;
+ options.x_getfilecon = optionp_getfilecon;
+ /* Can't turn no_leaf_check off because the user might have specified
+ * -noleaf anyway
+ */
+ break;
+
+ case SYMLINK_DEREF_ARGSONLY: /* -H */
+ options.xstat = optionh_stat;
+ options.x_getfilecon = optionh_getfilecon;
+ options.no_leaf_check = true;
+ }
+ }
+ options.symlink_handling = opt;
+}
+
+
+void
+parse_begin_user_args (char **args, int argno,
+ const struct predicate *last,
+ const struct predicate *predicates)
+{
+ (void) args;
+ (void) argno;
+ (void) last;
+ (void) predicates;
+ first_nonoption_arg = NULL;
+}
+
+void
+parse_end_user_args (char **args, int argno,
+ const struct predicate *last,
+ const struct predicate *predicates)
+{
+ /* does nothing */
+ (void) args;
+ (void) argno;
+ (void) last;
+ (void) predicates;
+}
+
+static bool
+should_issue_warnings (void)
+{
+ if (options.posixly_correct)
+ return false;
+ else
+ return options.warnings;
+}
+
+
+/* Check that it is legal to fid the given primary in its
+ * position and return it.
+ */
+static const struct parser_table*
+found_parser (const char *original_arg, const struct parser_table *entry)
+{
+ /* If this is an option, but we have already had a
+ * non-option argument, the user may be under the
+ * impression that the behaviour of the option
+ * argument is conditional on some preceding
+ * tests. This might typically be the case with,
+ * for example, -maxdepth.
+ *
+ * The options -daystart and -follow are exempt
+ * from this treatment, since their positioning
+ * in the command line does have an effect on
+ * subsequent tests but not previous ones. That
+ * might be intentional on the part of the user.
+ */
+ if (entry->type != ARG_POSITIONAL_OPTION)
+ {
+ /* Something other than -follow/-daystart.
+ * If this is an option, check if it followed
+ * a non-option and if so, issue a warning.
+ */
+ if (entry->type == ARG_OPTION)
+ {
+ if ((first_nonoption_arg != NULL)
+ && should_issue_warnings ())
+ {
+ /* option which follows a non-option */
+ error (0, 0,
+ _("warning: you have specified the %s "
+ "option after a non-option argument %s, "
+ "but options are not positional (%s affects "
+ "tests specified before it as well as those "
+ "specified after it). Please specify options "
+ "before other arguments.\n"),
+ original_arg,
+ first_nonoption_arg,
+ original_arg);
+ }
+ }
+ else
+ {
+ /* Not an option or a positional option,
+ * so remember we've seen it in order to
+ * use it in a possible future warning message.
+ */
+ if (first_nonoption_arg == NULL)
+ {
+ first_nonoption_arg = original_arg;
+ }
+ }
+ }
+
+ return entry;
+}
+
+
+/* Return a pointer to the parser function to invoke for predicate
+ SEARCH_NAME.
+ Return NULL if SEARCH_NAME is not a valid predicate name. */
+
+const struct parser_table*
+find_parser (const char *search_name)
+{
+ int i;
+ const char *original_arg = search_name;
+
+ /* Ugh. Special case -newerXY. */
+ if (0 == strncmp ("-newer", search_name, 6)
+ && (8 == strlen (search_name)))
+ {
+ return found_parser (original_arg, &parse_entry_newerXY);
+ }
+
+ if (*search_name == '-')
+ search_name++;
+
+ for (i = 0; parse_table[i].parser_name != 0; i++)
+ {
+ if (strcmp (parse_table[i].parser_name, search_name) == 0)
+ {
+ return found_parser (original_arg, &parse_table[i]);
+ }
+ }
+ return NULL;
+}
+
+static float
+estimate_file_age_success_rate (float num_days)
+{
+ if (num_days < 0.1)
+ {
+ /* Assume 1% of files have timestamps in the future */
+ return 0.01f;
+ }
+ else if (num_days < 1)
+ {
+ /* Assume 30% of files have timestamps today */
+ return 0.3f;
+ }
+ else if (num_days > 100)
+ {
+ /* Assume 30% of files are very old */
+ return 0.3f;
+ }
+ else
+ {
+ /* Assume 39% of files are between 1 and 100 days old. */
+ return 0.39f;
+ }
+}
+
+static float
+estimate_timestamp_success_rate (time_t when)
+{
+ /* This calculation ignores the nanoseconds field of the
+ * origin, but I don't think that makes much difference
+ * to our estimate.
+ */
+ int num_days = (options.cur_day_start.tv_sec - when) / 86400;
+ return estimate_file_age_success_rate (num_days);
+}
+
+/* Collect an argument from the argument list, or
+ * return false.
+ */
+static bool
+collect_arg_nonconst (char **argv, int *arg_ptr, char **collected_arg)
+{
+ if ((argv == NULL) || (argv[*arg_ptr] == NULL))
+ {
+ *collected_arg = NULL;
+ return false;
+ }
+ else
+ {
+ *collected_arg = argv[*arg_ptr];
+ (*arg_ptr)++;
+ return true;
+ }
+}
+
+static bool
+collect_arg (char **argv, int *arg_ptr, const char **collected_arg)
+{
+ char *arg;
+ const bool result = collect_arg_nonconst (argv, arg_ptr, &arg);
+ *collected_arg = arg;
+ return result;
+}
+
+
+
+static bool
+collect_arg_stat_info (char **argv, int *arg_ptr, struct stat *p,
+ const char **argument)
+{
+ const char *filename;
+ if (collect_arg (argv, arg_ptr, &filename))
+ {
+ *argument = filename;
+ if (0 == (options.xstat)(filename, p))
+ {
+ return true;
+ }
+ else
+ {
+ fatal_target_file_error (errno, filename);
+ }
+ }
+ else
+ {
+ *argument = NULL;
+ return false;
+ }
+}
+
+/* The parsers are responsible to continue scanning ARGV for
+ their arguments. Each parser knows what is and isn't
+ allowed for itself.
+
+ ARGV is the argument array.
+ *ARG_PTR is the index to start at in ARGV,
+ updated to point beyond the last element consumed.
+
+ The predicate structure is updated with the new information. */
+
+
+static bool
+parse_and (const struct parser_table* entry, char **argv, int *arg_ptr)
+{
+ struct predicate *our_pred;
+
+ (void) argv;
+ (void) arg_ptr;
+
+ our_pred = get_new_pred_noarg (entry);
+ our_pred->pred_func = pred_and;
+ our_pred->p_type = BI_OP;
+ our_pred->p_prec = AND_PREC;
+ our_pred->need_stat = our_pred->need_type = false;
+ return true;
+}
+
+static bool
+parse_anewer (const struct parser_table* entry, char **argv, int *arg_ptr)
+{
+ struct stat stat_newer;
+ const char *arg;
+
+ set_stat_placeholders (&stat_newer);
+ if (collect_arg_stat_info (argv, arg_ptr, &stat_newer, &arg))
+ {
+ struct predicate *our_pred = insert_primary (entry, arg);
+ our_pred->args.reftime.xval = XVAL_ATIME;
+ our_pred->args.reftime.ts = get_stat_mtime (&stat_newer);
+ our_pred->args.reftime.kind = COMP_GT;
+ our_pred->est_success_rate = estimate_timestamp_success_rate (stat_newer.st_mtime);
+ return true;
+ }
+ return false;
+}
+
+bool
+parse_closeparen (const struct parser_table* entry, char **argv, int *arg_ptr)
+{
+ struct predicate *our_pred;
+
+ (void) argv;
+ (void) arg_ptr;
+
+ our_pred = get_new_pred_noarg (entry);
+ our_pred->pred_func = pred_closeparen;
+ our_pred->p_type = CLOSE_PAREN;
+ our_pred->p_prec = NO_PREC;
+ our_pred->need_stat = our_pred->need_type = false;
+ return true;
+}
+
+static bool
+parse_cnewer (const struct parser_table* entry, char **argv, int *arg_ptr)
+{
+ struct stat stat_newer;
+ const char *arg;
+
+ set_stat_placeholders (&stat_newer);
+ if (collect_arg_stat_info (argv, arg_ptr, &stat_newer, &arg))
+ {
+ struct predicate *our_pred = insert_primary (entry, arg);
+ our_pred->args.reftime.xval = XVAL_CTIME; /* like -newercm */
+ our_pred->args.reftime.ts = get_stat_mtime (&stat_newer);
+ our_pred->args.reftime.kind = COMP_GT;
+ our_pred->est_success_rate = estimate_timestamp_success_rate (stat_newer.st_mtime);
+ return true;
+ }
+ return false;
+}
+
+static bool
+parse_comma (const struct parser_table* entry, char **argv, int *arg_ptr)
+{
+ struct predicate *our_pred;
+
+ (void) argv;
+ (void) arg_ptr;
+
+ our_pred = get_new_pred_noarg (entry);
+ our_pred->pred_func = pred_comma;
+ our_pred->p_type = BI_OP;
+ our_pred->p_prec = COMMA_PREC;
+ our_pred->need_stat = our_pred->need_type = false;
+ our_pred->est_success_rate = 1.0f;
+ return true;
+}
+
+static bool
+parse_daystart (const struct parser_table* entry, char **argv, int *arg_ptr)
+{
+ struct tm *local;
+
+ (void) entry;
+ (void) argv;
+ (void) arg_ptr;
+
+ if (options.full_days == false)
+ {
+ options.cur_day_start.tv_sec += DAYSECS;
+ options.cur_day_start.tv_nsec = 0;
+ local = localtime (&options.cur_day_start.tv_sec);
+ options.cur_day_start.tv_sec -= (local
+ ? (local->tm_sec + local->tm_min * 60
+ + local->tm_hour * 3600)
+ : options.cur_day_start.tv_sec % DAYSECS);
+ options.full_days = true;
+ }
+ return true;
+}
+
+static bool
+parse_delete (const struct parser_table* entry, char *argv[], int *arg_ptr)
+{
+ struct predicate *our_pred;
+ (void) argv;
+ (void) arg_ptr;
+
+ our_pred = insert_primary_noarg (entry);
+ our_pred->side_effects = our_pred->no_default_print = true;
+ /* -delete implies -depth */
+ options.do_dir_first = false;
+
+ /* We do not need stat information because we check for the case
+ * (errno==EISDIR) in pred_delete.
+ */
+ our_pred->need_stat = our_pred->need_type = false;
+
+ our_pred->est_success_rate = 1.0f;
+ return true;
+}
+
+static bool
+parse_depth (const struct parser_table* entry, char **argv, int *arg_ptr)
+{
+ (void) entry;
+ (void) argv;
+
+ options.do_dir_first = false;
+ options.explicit_depth = true;
+ return parse_noop (entry, argv, arg_ptr);
+}
+
+static bool
+parse_d (const struct parser_table* entry, char **argv, int *arg_ptr)
+{
+ if (should_issue_warnings ())
+ {
+ error (0, 0,
+ _("warning: the -d option is deprecated; please use "
+ "-depth instead, because the latter is a "
+ "POSIX-compliant feature."));
+ }
+ return parse_depth (entry, argv, arg_ptr);
+}
+
+static bool
+parse_empty (const struct parser_table* entry, char **argv, int *arg_ptr)
+{
+ struct predicate *our_pred;
+ (void) argv;
+ (void) arg_ptr;
+
+ our_pred = insert_primary_noarg (entry);
+ our_pred->est_success_rate = 0.01f; /* assume 1% of files are empty. */
+ return true;
+}
+
+static bool
+parse_exec (const struct parser_table* entry, char **argv, int *arg_ptr)
+{
+ return insert_exec_ok ("-exec", entry, argv, arg_ptr);
+}
+
+static bool
+parse_execdir (const struct parser_table* entry, char **argv, int *arg_ptr)
+{
+ return insert_exec_ok ("-execdir", entry, argv, arg_ptr);
+}
+
+static bool
+insert_false(void)
+{
+ struct predicate *our_pred;
+ const struct parser_table *entry_false;
+
+ entry_false = find_parser("false");
+ our_pred = insert_primary_noarg (entry_false);
+ our_pred->need_stat = our_pred->need_type = false;
+ our_pred->side_effects = our_pred->no_default_print = false;
+ our_pred->est_success_rate = 0.0f;
+ return true;
+}
+
+
+static bool
+parse_false (const struct parser_table* entry, char **argv, int *arg_ptr)
+{
+ (void) entry;
+ (void) argv;
+ (void) arg_ptr;
+ return insert_false ();
+}
+
+static bool
+insert_fls (const struct parser_table* entry, const char *filename)
+{
+ struct predicate *our_pred = insert_primary_noarg (entry);
+ if (filename)
+ open_output_file (filename, &our_pred->args.printf_vec);
+ else
+ open_stdout (&our_pred->args.printf_vec);
+ our_pred->side_effects = our_pred->no_default_print = true;
+ our_pred->est_success_rate = 1.0f;
+ return true;
+}
+
+
+static bool
+parse_fls (const struct parser_table* entry, char **argv, int *arg_ptr)
+{
+ const char *filename;
+ if (collect_arg (argv, arg_ptr, &filename))
+ {
+ if (insert_fls (entry, filename))
+ return true;
+ else
+ --*arg_ptr; /* don't consume the invalid arg. */
+ }
+ return false;
+}
+
+static bool
+parse_follow (const struct parser_table* entry, char **argv, int *arg_ptr)
+{
+ set_follow_state (SYMLINK_ALWAYS_DEREF);
+ return parse_noop (entry, argv, arg_ptr);
+}
+
+static bool
+parse_fprint (const struct parser_table* entry, char **argv, int *arg_ptr)
+{
+ struct predicate *our_pred;
+ const char *filename;
+ if (collect_arg (argv, arg_ptr, &filename))
+ {
+ our_pred = insert_primary (entry, filename);
+ open_output_file (filename, &our_pred->args.printf_vec);
+ our_pred->side_effects = our_pred->no_default_print = true;
+ our_pred->need_stat = our_pred->need_type = false;
+ our_pred->est_success_rate = 1.0f;
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+}
+
+static bool
+insert_fprint (const struct parser_table* entry, const char *filename)
+{
+ struct predicate *our_pred = insert_primary (entry, filename);
+ if (filename)
+ open_output_file (filename, &our_pred->args.printf_vec);
+ else
+ open_stdout (&our_pred->args.printf_vec);
+ our_pred->side_effects = our_pred->no_default_print = true;
+ our_pred->need_stat = our_pred->need_type = false;
+ our_pred->est_success_rate = 1.0f;
+ return true;
+}
+
+
+static bool
+parse_fprint0 (const struct parser_table* entry, char **argv, int *arg_ptr)
+{
+ const char *filename;
+ if (collect_arg (argv, arg_ptr, &filename))
+ {
+ if (insert_fprint (entry, filename))
+ return true;
+ else
+ --*arg_ptr; /* don't consume the bad arg. */
+ }
+ return false;
+}
+
+static float estimate_fstype_success_rate (const char *fsname)
+{
+ struct stat dir_stat;
+ const char *the_root_dir = "/";
+ if (0 == stat (the_root_dir, &dir_stat)) /* it's an absolute path anyway */
+ {
+ const char *fstype = filesystem_type (&dir_stat, the_root_dir);
+ /* Assume most files are on the same file system type as the root fs. */
+ if (0 == strcmp (fsname, fstype))
+ return 0.7f;
+ else
+ return 0.3f;
+ }
+ return 1.0f;
+}
+
+
+
+static bool
+is_used_fs_type(const char *name)
+{
+ if (0 == strcmp("afs", name))
+ {
+ /* I guess AFS may not appear in /etc/mtab (or equivalent) but still be in use,
+ so assume we always need to check for AFS. */
+ return true;
+ }
+ else
+ {
+ const struct mount_entry *entries = read_file_system_list(false);
+ if (entries)
+ {
+ const struct mount_entry *entry;
+ for (entry = entries; entry; entry = entry->me_next)
+ {
+ if (0 == strcmp(name, entry->me_type))
+ return true;
+ }
+ }
+ else
+ {
+ return true;
+ }
+ }
+ return false;
+}
+
+
+static bool
+parse_fstype (const struct parser_table* entry, char **argv, int *arg_ptr)
+{
+ const char *typename;
+ if (collect_arg (argv, arg_ptr, &typename))
+ {
+ if (options.optimisation_level < 2 || is_used_fs_type (typename))
+ {
+ struct predicate *our_pred = insert_primary (entry, typename);
+ our_pred->args.str = typename;
+
+ /* This is an expensive operation, so although there are
+ * circumstances where it is selective, we ignore this fact
+ * because we probably don't want to promote this test to the
+ * front anyway.
+ */
+ our_pred->est_success_rate = estimate_fstype_success_rate (typename);
+ return true;
+ }
+ else
+ {
+ /* This filesystem type is not listed in the mount table.
+ * Hence this predicate will always return false (with this argument).
+ * Substitute a predicate with the same effect as -false.
+ */
+ if (options.debug_options & DebugTreeOpt)
+ {
+ fprintf (stderr,
+ "-fstype %s can never succeed, substituting -false\n",
+ typename);
+ }
+ return insert_false ();
+ }
+ }
+ else
+ {
+ return false;
+ }
+}
+
+static bool
+parse_gid (const struct parser_table* entry, char **argv, int *arg_ptr)
+{
+ struct predicate *p = insert_num (argv, arg_ptr, entry);
+ if (p)
+ {
+ p->est_success_rate = (p->args.numinfo.l_val < 100) ? 0.99 : 0.2;
+ return true;
+ }
+ else
+ {
+ --*arg_ptr; /* don't consume the invalid argument. */
+ return false;
+ }
+}
+
+
+static bool
+parse_group (const struct parser_table* entry, char **argv, int *arg_ptr)
+{
+ const char *groupname;
+ const int saved_argc = *arg_ptr;
+
+ if (collect_arg (argv, arg_ptr, &groupname))
+ {
+ gid_t gid;
+ struct predicate *our_pred;
+ struct group *cur_gr = getgrnam (groupname);
+ endgrent ();
+ if (cur_gr)
+ {
+ gid = cur_gr->gr_gid;
+ }
+ else
+ {
+ const int gid_len = strspn (groupname, "0123456789");
+ if (gid_len)
+ {
+ if (groupname[gid_len] == 0)
+ {
+ gid = safe_atoi (groupname, options.err_quoting_style);
+ }
+ else
+ {
+ /* XXX: no test in test suite for this */
+ error (EXIT_FAILURE, 0,
+ _("%s is not the name of an existing group and"
+ " it does not look like a numeric group ID "
+ "because it has the unexpected suffix %s"),
+ quotearg_n_style (0, options.err_quoting_style, groupname),
+ quotearg_n_style (1, options.err_quoting_style, groupname+gid_len));
+ *arg_ptr = saved_argc; /* don't consume the invalid argument. */
+ return false;
+ }
+ }
+ else
+ {
+ if (*groupname)
+ {
+ /* XXX: no test in test suite for this */
+ error (EXIT_FAILURE, 0,
+ _("%s is not the name of an existing group"),
+ quotearg_n_style (0, options.err_quoting_style, groupname));
+ }
+ else
+ {
+ error (EXIT_FAILURE, 0,
+ _("argument to -group is empty, but should be a group name"));
+ }
+ *arg_ptr = saved_argc; /* don't consume the invalid argument. */
+ return false;
+ }
+ }
+ our_pred = insert_primary (entry, groupname);
+ our_pred->args.gid = gid;
+ our_pred->est_success_rate = (our_pred->args.numinfo.l_val < 100) ? 0.99 : 0.2;
+ return true;
+ }
+ return false;
+}
+
+static bool
+parse_help (const struct parser_table* entry, char **argv, int *arg_ptr)
+{
+ (void) entry;
+ (void) argv;
+ (void) arg_ptr;
+
+ usage (stdout, 0, NULL);
+ puts (_("\n\
+default path is the current directory; default expression is -print\n\
+expression may consist of: operators, options, tests, and actions:\n"));
+ puts (_("\
+operators (decreasing precedence; -and is implicit where no others are given):\n\
+ ( EXPR ) ! EXPR -not EXPR EXPR1 -a EXPR2 EXPR1 -and EXPR2\n\
+ EXPR1 -o EXPR2 EXPR1 -or EXPR2 EXPR1 , EXPR2\n"));
+ puts (_("\
+positional options (always true): -daystart -follow -regextype\n\n\
+normal options (always true, specified before other expressions):\n\
+ -depth --help -maxdepth LEVELS -mindepth LEVELS -mount -noleaf\n\
+ --version -xdev -ignore_readdir_race -noignore_readdir_race\n"));
+ puts (_("\
+tests (N can be +N or -N or N): -amin N -anewer FILE -atime N -cmin N\n\
+ -cnewer FILE -ctime N -empty -false -fstype TYPE -gid N -group NAME\n\
+ -ilname PATTERN -iname PATTERN -inum N -iwholename PATTERN -iregex PATTERN\n\
+ -links N -lname PATTERN -mmin N -mtime N -name PATTERN -newer FILE"));
+ puts (_("\
+ -nouser -nogroup -path PATTERN -perm [-/]MODE -regex PATTERN\n\
+ -readable -writable -executable\n\
+ -wholename PATTERN -size N[bcwkMG] -true -type [bcdpflsD] -uid N\n\
+ -used N -user NAME -xtype [bcdpfls]"));
+ puts (_("\
+ -context CONTEXT\n"));
+ puts (_("\n\
+actions: -delete -print0 -printf FORMAT -fprintf FILE FORMAT -print \n\
+ -fprint0 FILE -fprint FILE -ls -fls FILE -prune -quit\n\
+ -exec COMMAND ; -exec COMMAND {} + -ok COMMAND ;\n\
+ -execdir COMMAND ; -execdir COMMAND {} + -okdir COMMAND ;\n\
+"));
+ puts (_("Report (and track progress on fixing) bugs via the findutils bug-reporting\n\
+page at http://savannah.gnu.org/ or, if you have no web access, by sending\n\
+email to <bug-findutils@gnu.org>."));
+ exit (EXIT_SUCCESS);
+}
+
+static float
+estimate_pattern_match_rate (const char *pattern, int is_regex)
+{
+ if (strpbrk (pattern, "*?[") || (is_regex && strpbrk(pattern, ".")))
+ {
+ /* A wildcard; assume the pattern matches most files. */
+ return 0.8f;
+ }
+ else
+ {
+ return 0.1f;
+ }
+}
+
+static bool
+parse_ilname (const struct parser_table* entry, char **argv, int *arg_ptr)
+{
+ const char *name;
+ if (collect_arg (argv, arg_ptr, &name))
+ {
+ struct predicate *our_pred = insert_primary (entry, name);
+ our_pred->args.str = name;
+ /* Use the generic glob pattern estimator to figure out how many
+ * links will match, but bear in mind that most files won't be links.
+ */
+ our_pred->est_success_rate = 0.1 * estimate_pattern_match_rate (name, 0);
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+}
+
+
+/* sanity check the fnmatch() function to make sure that case folding
+ * is supported (as opposed to just having the flag ignored).
+ */
+static bool
+fnmatch_sanitycheck (void)
+{
+ static bool checked = false;
+ if (!checked)
+ {
+ if (0 != fnmatch ("foo", "foo", 0)
+ || 0 == fnmatch ("Foo", "foo", 0)
+ || 0 != fnmatch ("Foo", "foo", FNM_CASEFOLD))
+ {
+ error (EXIT_FAILURE, 0,
+ _("sanity check of the fnmatch() library function failed."));
+ return false;
+ }
+ checked = true;
+ }
+ return checked;
+}
+
+
+static bool
+check_name_arg (const char *pred, const char *arg)
+{
+ if (should_issue_warnings () && strchr (arg, '/'))
+ {
+ error (0, 0,_("warning: Unix filenames usually don't contain slashes "
+ "(though pathnames do). That means that '%s %s' will "
+ "probably evaluate to false all the time on this system. "
+ "You might find the '-wholename' test more useful, or "
+ "perhaps '-samefile'. Alternatively, if you are using "
+ "GNU grep, you could "
+ "use 'find ... -print0 | grep -FzZ %s'."),
+ pred,
+ safely_quote_err_filename (0, arg),
+ safely_quote_err_filename (1, arg));
+ }
+ return true; /* allow it anyway */
+}
+
+
+
+static bool
+parse_iname (const struct parser_table* entry, char **argv, int *arg_ptr)
+{
+ const char *name;
+ fnmatch_sanitycheck ();
+ if (collect_arg (argv, arg_ptr, &name))
+ {
+ if (check_name_arg ("-iname", name))
+ {
+ struct predicate *our_pred = insert_primary (entry, name);
+ our_pred->need_stat = our_pred->need_type = false;
+ our_pred->args.str = name;
+ our_pred->est_success_rate = estimate_pattern_match_rate (name, 0);
+ return true;
+ }
+ }
+ return false;
+}
+
+static bool
+parse_inum (const struct parser_table* entry, char **argv, int *arg_ptr)
+{
+ struct predicate *p = insert_num (argv, arg_ptr, entry);
+ if (p)
+ {
+ /* inode number is exact match only, so very low proportions of
+ * files match
+ */
+ p->est_success_rate = 1e-6;
+ p->need_inum = true;
+ p->need_stat = false;
+ p->need_type = false;
+ return true;
+ }
+ else
+ {
+ --*arg_ptr; /* don't consume the invalid argument. */
+ return false;
+ }
+}
+
+static bool
+parse_iregex (const struct parser_table* entry, char **argv, int *arg_ptr)
+{
+ return insert_regex (argv, arg_ptr, entry, RE_ICASE|options.regex_options);
+}
+
+static bool
+parse_links (const struct parser_table* entry, char **argv, int *arg_ptr)
+{
+ struct predicate *p = insert_num (argv, arg_ptr, entry);
+ if (p)
+ {
+ if (p->args.numinfo.l_val == 1)
+ p->est_success_rate = 0.99;
+ else if (p->args.numinfo.l_val == 2)
+ p->est_success_rate = 0.01;
+ else
+ p->est_success_rate = 1e-3;
+ return true;
+ }
+ else
+ {
+ --*arg_ptr; /* don't consume the invalid argument. */
+ return false;
+ }
+}
+
+static bool
+parse_lname (const struct parser_table* entry, char **argv, int *arg_ptr)
+{
+ const char *name;
+ fnmatch_sanitycheck ();
+ if (collect_arg (argv, arg_ptr, &name))
+ {
+ struct predicate *our_pred = insert_primary (entry, name);
+ our_pred->args.str = name;
+ our_pred->est_success_rate = 0.1 * estimate_pattern_match_rate (name, 0);
+ return true;
+ }
+ return false;
+}
+
+static bool
+parse_ls (const struct parser_table* entry, char **argv, int *arg_ptr)
+{
+ (void) &argv;
+ (void) &arg_ptr;
+ return insert_fls (entry, NULL);
+}
+
+static bool
+insert_depthspec (const struct parser_table* entry, char **argv, int *arg_ptr,
+ int *limitptr)
+{
+ const char *depthstr;
+ int depth_len;
+ const char *predicate = argv[(*arg_ptr)-1];
+ if (collect_arg (argv, arg_ptr, &depthstr))
+ {
+ depth_len = strspn (depthstr, "0123456789");
+ if ((depth_len > 0) && (depthstr[depth_len] == 0))
+ {
+ (*limitptr) = safe_atoi (depthstr, options.err_quoting_style);
+ if (*limitptr >= 0)
+ {
+ return parse_noop (entry, argv, arg_ptr);
+ }
+ }
+ error (EXIT_FAILURE, 0,
+ _("Expected a positive decimal integer argument to %s, but got %s"),
+ predicate,
+ quotearg_n_style (0, options.err_quoting_style, depthstr));
+ /* NOTREACHED */
+ return false;
+ }
+ /* missing argument */
+ return false;
+}
+
+
+static bool
+parse_maxdepth (const struct parser_table* entry, char **argv, int *arg_ptr)
+{
+ return insert_depthspec (entry, argv, arg_ptr, &options.maxdepth);
+}
+
+static bool
+parse_mindepth (const struct parser_table* entry, char **argv, int *arg_ptr)
+{
+ return insert_depthspec (entry, argv, arg_ptr, &options.mindepth);
+}
+
+
+static bool
+do_parse_xmin (const struct parser_table* entry,
+ char **argv,
+ int *arg_ptr,
+ enum xval xv)
+{
+ const char *minutes;
+ const int saved_argc = *arg_ptr;
+
+ if (collect_arg (argv, arg_ptr, &minutes))
+ {
+ struct time_val tval;
+ struct timespec origin = options.cur_day_start;
+ tval.xval = xv;
+ origin.tv_sec += DAYSECS;
+ if (get_relative_timestamp (minutes, &tval, origin, 60,
+ "arithmetic overflow while converting %s "
+ "minutes to a number of seconds"))
+ {
+ struct predicate *our_pred = insert_primary (entry, minutes);
+ our_pred->args.reftime = tval;
+ our_pred->est_success_rate = estimate_timestamp_success_rate (tval.ts.tv_sec);
+ return true;
+ }
+ else
+ {
+ /* Don't consume the invalid argument. */
+ *arg_ptr = saved_argc;
+ }
+ }
+ return false;
+}
+static bool
+parse_amin (const struct parser_table* entry, char **argv, int *arg_ptr)
+{
+ return do_parse_xmin (entry, argv, arg_ptr, XVAL_ATIME);
+}
+
+static bool
+parse_cmin (const struct parser_table* entry, char **argv, int *arg_ptr)
+{
+ return do_parse_xmin (entry, argv, arg_ptr, XVAL_CTIME);
+}
+
+
+static bool
+parse_mmin (const struct parser_table* entry, char **argv, int *arg_ptr)
+{
+ return do_parse_xmin (entry, argv, arg_ptr, XVAL_MTIME);
+}
+
+static bool
+parse_name (const struct parser_table* entry, char **argv, int *arg_ptr)
+{
+ const char *name;
+ const int saved_argc = *arg_ptr;
+
+ if (collect_arg (argv, arg_ptr, &name))
+ {
+ fnmatch_sanitycheck ();
+ if (check_name_arg ("-name", name))
+ {
+ struct predicate *our_pred = insert_primary (entry, name);
+ our_pred->need_stat = our_pred->need_type = false;
+ our_pred->args.str = name;
+ our_pred->est_success_rate = estimate_pattern_match_rate (name, 0);
+ return true;
+ }
+ else
+ {
+ *arg_ptr = saved_argc; /* don't consume the invalid argument. */
+ }
+ }
+ return false;
+}
+
+static bool
+parse_negate (const struct parser_table* entry, char **argv, int *arg_ptr)
+{
+ struct predicate *our_pred;
+
+ (void) &argv;
+ (void) &arg_ptr;
+
+ our_pred = get_new_pred_chk_op (entry, NULL);
+ our_pred->pred_func = pred_negate;
+ our_pred->p_type = UNI_OP;
+ our_pred->p_prec = NEGATE_PREC;
+ our_pred->need_stat = our_pred->need_type = false;
+ return true;
+}
+
+static bool
+parse_newer (const struct parser_table* entry, char **argv, int *arg_ptr)
+{
+ struct predicate *our_pred;
+ struct stat stat_newer;
+ const char *arg;
+
+ set_stat_placeholders (&stat_newer);
+ if (collect_arg_stat_info (argv, arg_ptr, &stat_newer, &arg))
+ {
+ our_pred = insert_primary (entry, arg);
+ our_pred->args.reftime.ts = get_stat_mtime (&stat_newer);
+ our_pred->args.reftime.xval = XVAL_MTIME;
+ our_pred->args.reftime.kind = COMP_GT;
+ our_pred->est_success_rate = estimate_timestamp_success_rate (stat_newer.st_mtime);
+ return true;
+ }
+ return false;
+}
+
+
+static bool
+parse_newerXY (const struct parser_table* entry, char **argv, int *arg_ptr)
+{
+ (void) argv;
+ (void) arg_ptr;
+
+ if ((argv == NULL) || (argv[*arg_ptr] == NULL))
+ {
+ return false;
+ }
+ else if (8u != strlen (argv[*arg_ptr]))
+ {
+ return false;
+ }
+ else
+ {
+ char x, y;
+ const char validchars[] = "aBcmt";
+
+ assert (0 == strncmp ("-newer", argv[*arg_ptr], 6));
+ x = argv[*arg_ptr][6];
+ y = argv[*arg_ptr][7];
+
+
+#if !defined HAVE_STRUCT_STAT_ST_BIRTHTIME && !defined HAVE_STRUCT_STAT_ST_BIRTHTIMENSEC && !defined HAVE_STRUCT_STAT_ST_BIRTHTIMESPEC_TV_NSEC && !defined HAVE_STRUCT_STAT_ST_BIRTHTIM_TV_NSEC
+ if ('B' == x || 'B' == y)
+ {
+ error (0, 0,
+ _("This system does not provide a way to find the birth time of a file."));
+ return false;
+ }
+#endif
+
+ /* -newertY (for any Y) is invalid. */
+ if (x == 't'
+ || (NULL == strchr (validchars, x))
+ || (NULL == strchr ( validchars, y)))
+ {
+ return false;
+ }
+ else
+ {
+ struct predicate *our_pred;
+
+ /* Because this item is ARG_SPECIAL_PARSE, we have to advance arg_ptr
+ * past the test name (for most other tests, this is already done)
+ */
+ if (argv[1+*arg_ptr] == NULL)
+ {
+ error (EXIT_FAILURE, 0, _("The %s test needs an argument"),
+ quotearg_n_style (0, options.err_quoting_style, argv[*arg_ptr]));
+ }
+ else
+ {
+ (*arg_ptr)++;
+ }
+
+ our_pred = insert_primary (entry, argv[*arg_ptr]);
+
+
+ switch (x)
+ {
+ case 'a':
+ our_pred->args.reftime.xval = XVAL_ATIME;
+ break;
+ case 'B':
+ our_pred->args.reftime.xval = XVAL_BIRTHTIME;
+ break;
+ case 'c':
+ our_pred->args.reftime.xval = XVAL_CTIME;
+ break;
+ case 'm':
+ our_pred->args.reftime.xval = XVAL_MTIME;
+ break;
+ default:
+ assert (strchr (validchars, x));
+ assert (0);
+ }
+
+ if ('t' == y)
+ {
+ if (!parse_datetime (&our_pred->args.reftime.ts,
+ argv[*arg_ptr],
+ &options.start_time))
+ {
+ error (EXIT_FAILURE, 0,
+ _("I cannot figure out how to interpret %s as a date or time"),
+ quotearg_n_style (0, options.err_quoting_style, argv[*arg_ptr]));
+ }
+ }
+ else
+ {
+ struct stat stat_newer;
+
+ /* Stat the named file. */
+ set_stat_placeholders (&stat_newer);
+ if ((*options.xstat) (argv[*arg_ptr], &stat_newer))
+ fatal_target_file_error (errno, argv[*arg_ptr]);
+
+ if (!get_stat_Ytime (&stat_newer, y, &our_pred->args.reftime.ts))
+ {
+ /* We cannot extract a timestamp from the struct stat. */
+ error (EXIT_FAILURE, 0,
+ _("Cannot obtain birth time of file %s"),
+ safely_quote_err_filename (0, argv[*arg_ptr]));
+ }
+ }
+ our_pred->args.reftime.kind = COMP_GT;
+ our_pred->est_success_rate = estimate_timestamp_success_rate (our_pred->args.reftime.ts.tv_sec);
+ (*arg_ptr)++;
+
+ assert (our_pred->pred_func != NULL);
+ assert (our_pred->pred_func == pred_newerXY);
+ assert (our_pred->need_stat);
+ return true;
+ }
+ }
+}
+
+
+static bool
+parse_noleaf (const struct parser_table* entry, char **argv, int *arg_ptr)
+{
+ options.no_leaf_check = true;
+ return parse_noop (entry, argv, arg_ptr);
+}
+
+static bool
+parse_nogroup (const struct parser_table* entry, char **argv, int *arg_ptr)
+{
+ struct predicate *our_pred;
+
+ (void) &argv;
+ (void) &arg_ptr;
+
+ our_pred = insert_primary (entry, NULL);
+ our_pred->est_success_rate = 1e-4;
+ return true;
+}
+
+static bool
+parse_nouser (const struct parser_table* entry, char **argv, int *arg_ptr)
+{
+ struct predicate *our_pred;
+ (void) argv;
+ (void) arg_ptr;
+
+
+ our_pred = insert_primary_noarg (entry);
+ our_pred->est_success_rate = 1e-3;
+ return true;
+}
+
+static bool
+parse_nowarn (const struct parser_table* entry, char **argv, int *arg_ptr)
+{
+ options.warnings = false;
+ return parse_noop (entry, argv, arg_ptr);
+}
+
+static bool
+parse_ok (const struct parser_table* entry, char **argv, int *arg_ptr)
+{
+ return insert_exec_ok ("-ok", entry, argv, arg_ptr);
+}
+
+static bool
+parse_okdir (const struct parser_table* entry, char **argv, int *arg_ptr)
+{
+ return insert_exec_ok ("-okdir", entry, argv, arg_ptr);
+}
+
+bool
+parse_openparen (const struct parser_table* entry, char **argv, int *arg_ptr)
+{
+ struct predicate *our_pred;
+
+ (void) argv;
+ (void) arg_ptr;
+
+ our_pred = get_new_pred_chk_op (entry, NULL);
+ our_pred->pred_func = pred_openparen;
+ our_pred->p_type = OPEN_PAREN;
+ our_pred->p_prec = NO_PREC;
+ our_pred->need_stat = our_pred->need_type = false;
+ return true;
+}
+
+static bool
+parse_or (const struct parser_table* entry, char **argv, int *arg_ptr)
+{
+ struct predicate *our_pred;
+
+ (void) argv;
+ (void) arg_ptr;
+
+ our_pred = get_new_pred_noarg (entry);
+ our_pred->pred_func = pred_or;
+ our_pred->p_type = BI_OP;
+ our_pred->p_prec = OR_PREC;
+ our_pred->need_stat = our_pred->need_type = false;
+ return true;
+}
+
+static bool
+is_feasible_path_argument (const char *arg, bool foldcase)
+{
+ const char *last = strrchr (arg, '/');
+ if (last && !last[1])
+ {
+ /* The name ends with "/". */
+ if (matches_start_point (arg, foldcase))
+ {
+ /* "-path foo/" can succeed if one of the start points is "foo/". */
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+ }
+ return true;
+}
+
+
+static bool
+insert_path_check (const struct parser_table* entry, char **argv, int *arg_ptr,
+ const char *predicate_name, PREDICATEFUNCTION pred)
+{
+ const char *name;
+ bool foldcase = false;
+
+ if (pred == pred_ipath)
+ foldcase = true;
+
+ fnmatch_sanitycheck ();
+
+ if (collect_arg (argv, arg_ptr, &name))
+ {
+ struct predicate *our_pred = insert_primary_withpred (entry, pred, name);
+ our_pred->need_stat = our_pred->need_type = false;
+ our_pred->args.str = name;
+ our_pred->est_success_rate = estimate_pattern_match_rate (name, 0);
+
+ if (!options.posixly_correct
+ && !is_feasible_path_argument (name, foldcase))
+ {
+ error (0, 0, _("warning: -%s %s will not match anything "
+ "because it ends with /."),
+ predicate_name, name);
+ our_pred->est_success_rate = 1.0e-8;
+ }
+ return true;
+ }
+ return false;
+}
+
+/* For some time, -path was deprecated (at RMS's request) in favour of
+ * -iwholename. See the node "GNU Manuals" in standards.texi for the
+ * rationale for this (basically, GNU prefers the use of the phrase
+ * "file name" to "path name".
+ *
+ * We do not issue a warning that this usage is deprecated
+ * since
+ * (a) HPUX find supports this predicate also and
+ * (b) it will soon be in POSIX anyway.
+ */
+static bool
+parse_path (const struct parser_table* entry, char **argv, int *arg_ptr)
+{
+ return insert_path_check (entry, argv, arg_ptr, "path", pred_path);
+}
+
+static bool
+parse_wholename (const struct parser_table* entry, char **argv, int *arg_ptr)
+{
+ return insert_path_check (entry, argv, arg_ptr, "wholename", pred_path);
+}
+
+/* -ipath was deprecated (at RMS's request) in favour of
+ * -iwholename. See the node "GNU Manuals" in standards.texi
+ * for the rationale for this (basically, GNU prefers the use
+ * of the phrase "file name" to "path name".
+ * However, -path is now standardised so I un-deprecated -ipath.
+ */
+static bool
+parse_ipath (const struct parser_table* entry, char **argv, int *arg_ptr)
+{
+ return insert_path_check (entry, argv, arg_ptr, "ipath", pred_ipath);
+}
+
+static bool
+parse_iwholename (const struct parser_table* entry, char **argv, int *arg_ptr)
+{
+ return insert_path_check (entry, argv, arg_ptr, "iwholename", pred_ipath);
+}
+
+
+static bool
+parse_perm (const struct parser_table* entry, char **argv, int *arg_ptr)
+{
+ mode_t perm_val[2];
+ float rate;
+ int mode_start = 0;
+ enum permissions_type kind = PERM_EXACT;
+ struct mode_change *change;
+ struct predicate *our_pred;
+ const char *perm_expr;
+
+ if (!collect_arg (argv, arg_ptr, &perm_expr))
+ return false;
+
+ switch (perm_expr[0])
+ {
+ case '-':
+ mode_start = 1;
+ kind = PERM_AT_LEAST;
+ rate = 0.2;
+ break;
+
+ case '/': /* GNU extension */
+ mode_start = 1;
+ kind = PERM_ANY;
+ rate = 0.3;
+ break;
+
+ default:
+ /* For example, '-perm 0644', which is valid and matches
+ * only files whose mode is exactly 0644.
+ */
+ mode_start = 0;
+ kind = PERM_EXACT;
+ rate = 0.01;
+ break;
+ }
+
+ change = mode_compile (perm_expr + mode_start);
+
+ /* Reject invalid modes, or modes of the form +NUMERICMODE.
+ The latter were formerly accepted as a GNU extension, but that
+ extension was incompatible with how GNU 'chmod' treats these modes now,
+ and it would be confusing if 'find' continued to support it. */
+ if (NULL == change
+ || (perm_expr[0] == '+' && '0' <= perm_expr[1] && perm_expr[1] < '8'))
+ error (EXIT_FAILURE, 0, _("invalid mode %s"),
+ quotearg_n_style (0, options.err_quoting_style, perm_expr));
+ perm_val[0] = mode_adjust (0, false, 0, change, NULL);
+ perm_val[1] = mode_adjust (0, true, 0, change, NULL);
+ free (change);
+
+ if (('/' == perm_expr[0]) && (0 == perm_val[0]) && (0 == perm_val[1]))
+ {
+ /* The meaning of -perm /000 will change in the future. It
+ * currently matches no files, but like -perm -000 it should
+ * match all files.
+ *
+ * Starting in 2005, we used to issue a warning message
+ * informing the user that the behaviour would change in the
+ * future. We have now changed the behaviour and issue a
+ * warning message that the behaviour recently changed.
+ */
+ error (0, 0,
+ _("warning: you have specified a mode pattern %s (which is "
+ "equivalent to /000). The meaning of -perm /000 has now been "
+ "changed to be consistent with -perm -000; that is, while it "
+ "used to match no files, it now matches all files."),
+ perm_expr);
+
+ kind = PERM_AT_LEAST;
+
+ /* The "magic" number below is just the fraction of files on my
+ * own system that "-type l -xtype l" fails for (i.e. unbroken symlinks).
+ * Actual totals are 1472 and 1073833.
+ */
+ rate = 0.9986; /* probably matches anything but a broken symlink */
+ }
+
+ our_pred = insert_primary (entry, perm_expr);
+ our_pred->est_success_rate = rate;
+ our_pred->args.perm.kind = kind;
+ memcpy (our_pred->args.perm.val, perm_val, sizeof perm_val);
+ return true;
+}
+
+bool
+parse_print (const struct parser_table* entry, char **argv, int *arg_ptr)
+{
+ struct predicate *our_pred;
+
+ (void) argv;
+ (void) arg_ptr;
+
+ our_pred = insert_primary_noarg (entry);
+ /* -print has the side effect of printing. This prevents us
+ from doing undesired multiple printing when the user has
+ already specified -print. */
+ our_pred->side_effects = our_pred->no_default_print = true;
+ our_pred->need_stat = our_pred->need_type = false;
+ open_stdout (&our_pred->args.printf_vec);
+ return true;
+}
+
+static bool
+parse_print0 (const struct parser_table* entry, char **argv, int *arg_ptr)
+{
+ (void) entry;
+ (void) argv;
+ (void) arg_ptr;
+ return insert_fprint (entry, NULL);
+}
+
+static bool
+parse_printf (const struct parser_table* entry, char **argv, int *arg_ptr)
+{
+ char *format;
+ const int saved_argc = *arg_ptr;
+
+ if (collect_arg_nonconst (argv, arg_ptr, &format))
+ {
+ struct format_val fmt;
+ open_stdout (&fmt);
+ if (insert_fprintf (&fmt, entry, format))
+ {
+ return true;
+ }
+ else
+ {
+ *arg_ptr = saved_argc; /* don't consume the invalid argument. */
+ return false;
+ }
+ }
+ return false;
+}
+
+static bool
+parse_fprintf (const struct parser_table* entry, char **argv, int *arg_ptr)
+{
+ const char *filename;
+ char *format;
+ int saved_argc = *arg_ptr;
+
+ if (collect_arg (argv, arg_ptr, &filename))
+ {
+ if (collect_arg_nonconst (argv, arg_ptr, &format))
+ {
+ struct format_val fmt;
+ open_output_file (filename, &fmt);
+ saved_argc = *arg_ptr;
+
+ if (insert_fprintf (&fmt, entry, format))
+ return true;
+ }
+ }
+ *arg_ptr = saved_argc; /* don't consume the invalid argument. */
+ return false;
+}
+
+static bool
+parse_prune (const struct parser_table* entry, char **argv, int *arg_ptr)
+{
+ struct predicate *our_pred;
+
+ (void) argv;
+ (void) arg_ptr;
+
+ our_pred = insert_primary_noarg (entry);
+ if (options.do_dir_first == false)
+ our_pred->need_stat = our_pred->need_type = false;
+ /* -prune has a side effect that it does not descend into
+ the current directory. */
+ our_pred->side_effects = true;
+ our_pred->no_default_print = false;
+ return true;
+}
+
+static bool
+parse_quit (const struct parser_table* entry, char **argv, int *arg_ptr)
+{
+ struct predicate *our_pred = insert_primary_noarg (entry);
+ (void) argv;
+ (void) arg_ptr;
+ our_pred->need_stat = our_pred->need_type = false;
+ our_pred->side_effects = true; /* Exiting is a side effect... */
+ our_pred->no_default_print = false; /* Don't inhibit the default print, though. */
+ our_pred->est_success_rate = 1.0f;
+ return true;
+}
+
+
+static bool
+parse_regextype (const struct parser_table* entry, char **argv, int *arg_ptr)
+{
+ const char *type_name;
+ if (collect_arg (argv, arg_ptr, &type_name))
+ {
+ /* collect the regex type name */
+ options.regex_options = get_regex_type (type_name);
+ return parse_noop (entry, argv, arg_ptr);
+ }
+ return false;
+}
+
+
+static bool
+parse_regex (const struct parser_table* entry, char **argv, int *arg_ptr)
+{
+ return insert_regex (argv, arg_ptr, entry, options.regex_options);
+}
+
+static bool
+insert_regex (char **argv,
+ int *arg_ptr,
+ const struct parser_table *entry,
+ int regex_options)
+{
+ const char *rx;
+ if (collect_arg (argv, arg_ptr, &rx))
+ {
+ struct re_pattern_buffer *re;
+ const char *error_message;
+ struct predicate *our_pred = insert_primary_withpred (entry, pred_regex, rx);
+ our_pred->need_stat = our_pred->need_type = false;
+ re = xmalloc (sizeof (struct re_pattern_buffer));
+ our_pred->args.regex = re;
+ re->allocated = 100;
+ re->buffer = xmalloc (re->allocated);
+ re->fastmap = NULL;
+
+ re_set_syntax (regex_options);
+ re->syntax = regex_options;
+ re->translate = NULL;
+
+ error_message = re_compile_pattern (rx, strlen (rx), re);
+ if (error_message)
+ error (EXIT_FAILURE, 0,
+ _("failed to compile regular expression '%s': %s"),
+ rx, error_message);
+ our_pred->est_success_rate = estimate_pattern_match_rate (rx, 1);
+ return true;
+ }
+ return false;
+}
+
+static bool
+parse_size (const struct parser_table* entry, char **argv, int *arg_ptr)
+{
+ struct predicate *our_pred;
+ char *arg;
+ uintmax_t num;
+ char suffix;
+ enum comparison_type c_type;
+
+ int blksize = 512;
+ int len;
+
+ /* XXX: cannot (yet) convert to ue collect_arg() as this
+ * function modifies the args in-place.
+ */
+ if ((argv == NULL) || (argv[*arg_ptr] == NULL))
+ return false;
+ arg = argv[*arg_ptr];
+
+ len = strlen (arg);
+ if (len == 0)
+ error (EXIT_FAILURE, 0, _("invalid null argument to -size"));
+
+ suffix = arg[len - 1];
+ switch (suffix)
+ {
+ case 'b':
+ blksize = 512;
+ arg[len - 1] = '\0';
+ break;
+
+ case 'c':
+ blksize = 1;
+ arg[len - 1] = '\0';
+ break;
+
+ case 'k':
+ blksize = 1024;
+ arg[len - 1] = '\0';
+ break;
+
+ case 'M': /* Megabytes */
+ blksize = 1024*1024;
+ arg[len - 1] = '\0';
+ break;
+
+ case 'G': /* Gigabytes */
+ blksize = 1024*1024*1024;
+ arg[len - 1] = '\0';
+ break;
+
+ case 'w':
+ blksize = 2;
+ arg[len - 1] = '\0';
+ break;
+
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+ suffix = 0;
+ break;
+
+ default:
+ error (EXIT_FAILURE, 0,
+ _("invalid -size type `%c'"), argv[*arg_ptr][len - 1]);
+ }
+ /* TODO: accept fractional megabytes etc. ? */
+ if (!get_num (arg, &num, &c_type))
+ {
+ char tail[2];
+ tail[0] = suffix;
+ tail[1] = 0;
+
+ error (EXIT_FAILURE, 0,
+ _("Invalid argument `%s%s' to -size"),
+ arg, tail);
+ return false;
+ }
+ our_pred = insert_primary (entry, arg);
+ our_pred->args.size.kind = c_type;
+ our_pred->args.size.blocksize = blksize;
+ our_pred->args.size.size = num;
+ our_pred->need_stat = true;
+ our_pred->need_type = false;
+
+ if (COMP_GT == c_type)
+ our_pred->est_success_rate = (num*blksize > 20480) ? 0.1 : 0.9;
+ else if (COMP_LT == c_type)
+ our_pred->est_success_rate = (num*blksize > 20480) ? 0.9 : 0.1;
+ else
+ our_pred->est_success_rate = 0.01;
+
+ (*arg_ptr)++;
+ return true;
+}
+
+
+static bool
+parse_samefile (const struct parser_table* entry, char **argv, int *arg_ptr)
+{
+ /* General idea: stat the file, remember device and inode numbers.
+ * If a candidate file matches those, it's the same file.
+ */
+ struct predicate *our_pred;
+ struct stat st, fst;
+ int fd, openflags;
+ const char *filename;
+
+ set_stat_placeholders (&st);
+ if (!collect_arg_stat_info (argv, arg_ptr, &st, &filename))
+ return false;
+
+ set_stat_placeholders (&fst);
+ /* POSIX systems are free to re-use the inode number of a deleted
+ * file. To ensure that we are not fooled by inode reuse, we hold
+ * the file open if we can. This would prevent the system reusing
+ * the file.
+ */
+ fd = -3; /* -3 means uninitialized */
+ openflags = O_RDONLY;
+
+ if (options.symlink_handling == SYMLINK_NEVER_DEREF)
+ {
+ if (options.open_nofollow_available)
+ {
+ assert (O_NOFOLLOW != 0);
+ openflags |= O_NOFOLLOW;
+ fd = -1; /* safe to open it. */
+ }
+ else
+ {
+ if (S_ISLNK(st.st_mode))
+ {
+ /* no way to ensure that a symlink will not be followed
+ * by open(2), so fall back on using lstat(). Accept
+ * the risk that the named file will be deleted and
+ * replaced with another having the same inode.
+ *
+ * Avoid opening the file.
+ */
+ fd = -2; /* Do not open it */
+ }
+ else
+ {
+ fd = -1;
+ /* Race condition here: the file might become a symlink here. */
+ }
+ }
+ }
+ else
+ {
+ /* We want to dereference the symlink anyway */
+ fd = -1; /* safe to open it without O_NOFOLLOW */
+ }
+
+ assert (fd != -3); /* check we made a decision */
+ if (fd == -1)
+ {
+ /* Race condition here. The file might become a
+ * symbolic link in between our call to stat and
+ * the call to open_cloexec.
+ */
+ fd = open_cloexec (filename, openflags);
+
+ if (fd >= 0)
+ {
+ /* We stat the file again here to prevent a race condition
+ * between the first stat and the call to open(2).
+ */
+ if (0 != fstat (fd, &fst))
+ {
+ fatal_target_file_error (errno, filename);
+ }
+ else
+ {
+ /* Worry about the race condition. If the file became a
+ * symlink after our first stat and before our call to
+ * open, fst may contain the stat information for the
+ * destination of the link, not the link itself.
+ */
+ if ((*options.xstat) (filename, &st))
+ fatal_target_file_error (errno, filename);
+
+ if ((options.symlink_handling == SYMLINK_NEVER_DEREF)
+ && (!options.open_nofollow_available))
+ {
+ if (S_ISLNK(st.st_mode))
+ {
+ /* We lost the race. Leave the data in st. The
+ * file descriptor points to the wrong thing.
+ */
+ close (fd);
+ fd = -1;
+ }
+ else
+ {
+ /* Several possibilities here:
+ * 1. There was no race
+ * 2. The file changed into a symlink after the stat and
+ * before the open, and then back into a non-symlink
+ * before the second stat.
+ *
+ * In case (1) there is no problem. In case (2),
+ * the stat() and fstat() calls will have returned
+ * different data. O_NOFOLLOW was not available,
+ * so the open() call may have followed a symlink
+ * even if the -P option is in effect.
+ */
+ if ((st.st_dev == fst.st_dev)
+ && (st.st_ino == fst.st_ino))
+ {
+ /* No race. No need to copy fst to st,
+ * since they should be identical (modulo
+ * differences in padding bytes).
+ */
+ }
+ else
+ {
+ /* We lost the race. Leave the data in st. The
+ * file descriptor points to the wrong thing.
+ */
+ close (fd);
+ fd = -1;
+ }
+ }
+ }
+ else
+ {
+ st = fst;
+ }
+ }
+ }
+ }
+
+ our_pred = insert_primary (entry, filename);
+ our_pred->args.samefileid.ino = st.st_ino;
+ our_pred->args.samefileid.dev = st.st_dev;
+ our_pred->args.samefileid.fd = fd;
+ our_pred->need_type = false;
+ /* smarter way: compare type and inode number first. */
+ /* TODO: maybe optimise this away by being optimistic */
+ our_pred->need_stat = true;
+ our_pred->est_success_rate = 0.01f;
+ return true;
+}
+
+#if 0
+/* This function is commented out partly because support for it is
+ * uneven.
+ */
+static bool
+parse_show_control_chars (const struct parser_table* entry,
+ char **argv,
+ int *arg_ptr)
+{
+ const char *arg;
+ const char *errmsg = _("The -show-control-chars option takes "
+ "a single argument which "
+ "must be 'literal' or 'safe'");
+
+ if ((argv == NULL) || (argv[*arg_ptr] == NULL))
+ {
+ error (EXIT_FAILURE, errno, "%s", errmsg);
+ return false;
+ }
+ else
+ {
+ arg = argv[*arg_ptr];
+
+ if (0 == strcmp ("literal", arg))
+ {
+ options.literal_control_chars = true;
+ }
+ else if (0 == strcmp ("safe", arg))
+ {
+ options.literal_control_chars = false;
+ }
+ else
+ {
+ error (EXIT_FAILURE, errno, "%s", errmsg);
+ return false;
+ }
+ (*arg_ptr)++; /* consume the argument. */
+ return true;
+ }
+}
+#endif
+
+
+static bool
+parse_true (const struct parser_table* entry, char **argv, int *arg_ptr)
+{
+ struct predicate *our_pred;
+
+ (void) argv;
+ (void) arg_ptr;
+
+ our_pred = insert_primary_noarg (entry);
+ our_pred->need_stat = our_pred->need_type = false;
+ our_pred->est_success_rate = 1.0f;
+ return true;
+}
+
+static bool
+parse_noop (const struct parser_table* entry, char **argv, int *arg_ptr)
+{
+ (void) entry;
+ return parse_true (get_noop (), argv, arg_ptr);
+}
+
+static bool
+parse_accesscheck (const struct parser_table* entry, char **argv, int *arg_ptr)
+{
+ struct predicate *our_pred;
+ (void) argv;
+ (void) arg_ptr;
+ our_pred = insert_primary_noarg (entry);
+ our_pred->need_stat = our_pred->need_type = false;
+ our_pred->side_effects = our_pred->no_default_print = false;
+ if (pred_is(our_pred, pred_executable))
+ our_pred->est_success_rate = 0.2;
+ else
+ our_pred->est_success_rate = 0.9;
+ return true;
+}
+
+static bool
+parse_type (const struct parser_table* entry, char **argv, int *arg_ptr)
+{
+ return insert_type (argv, arg_ptr, entry, pred_type);
+}
+
+static bool
+parse_uid (const struct parser_table* entry, char **argv, int *arg_ptr)
+{
+ struct predicate *p = insert_num (argv, arg_ptr, entry);
+ if (p)
+ {
+ p->est_success_rate = (p->args.numinfo.l_val < 100) ? 0.99 : 0.2;
+ return true;
+ }
+ else
+ {
+ --*arg_ptr; /* don't consume the invalid argument. */
+ return false;
+ }
+}
+
+static bool
+parse_used (const struct parser_table* entry, char **argv, int *arg_ptr)
+{
+ struct predicate *our_pred;
+ struct time_val tval;
+ const char *offset_str;
+ const char *errmsg = "arithmetic overflow while converting %s days to a number of seconds";
+
+ if (collect_arg (argv, arg_ptr, &offset_str))
+ {
+ /* The timespec is actually a delta value, so we use an origin of 0. */
+ struct timespec zero = {0,0};
+ if (get_relative_timestamp (offset_str, &tval, zero, DAYSECS, errmsg))
+ {
+ our_pred = insert_primary (entry, offset_str);
+ our_pred->args.reftime = tval;
+ our_pred->est_success_rate = estimate_file_age_success_rate (tval.ts.tv_sec / DAYSECS);
+ return true;
+ }
+ else
+ {
+ error (EXIT_FAILURE, 0,
+ _("Invalid argument %s to -used"), offset_str);
+ /*NOTREACHED*/
+ return false;
+ }
+ }
+ else
+ {
+ return false; /* missing argument */
+ }
+}
+
+static bool
+parse_user (const struct parser_table* entry, char **argv, int *arg_ptr)
+{
+ const char *username;
+
+ if (collect_arg (argv, arg_ptr, &username))
+ {
+ struct predicate *our_pred;
+ uid_t uid;
+ struct passwd *cur_pwd = getpwnam (username);
+ endpwent ();
+ if (cur_pwd != NULL)
+ {
+ uid = cur_pwd->pw_uid;
+ }
+ else
+ {
+ const size_t uid_len = strspn (username, "0123456789");
+ if (uid_len && (username[uid_len]==0))
+ {
+ uid = safe_atoi (username, options.err_quoting_style);
+ }
+ else
+ {
+ /* This is a fatal error (if we just return false, the caller
+ * will say "invalid argument `username' to -user", which is
+ * not as helpful). */
+ if (username[0])
+ {
+ error (EXIT_FAILURE, 0,
+ _("%s is not the name of a known user"),
+ quotearg_n_style (0, options.err_quoting_style,
+ username));
+ }
+ else
+ {
+ error (EXIT_FAILURE, 0,
+ _("The argument to -user should not be empty"));
+ }
+ /*NOTREACHED*/
+ return false;
+ }
+ }
+ our_pred = insert_primary (entry, username);
+ our_pred->args.uid = uid;
+ our_pred->est_success_rate = (our_pred->args.uid < 100) ? 0.99 : 0.2;
+ return true;
+ }
+ return false;
+}
+
+static bool
+parse_version (const struct parser_table* entry, char **argv, int *arg_ptr)
+{
+ bool has_features = false;
+ int flags;
+
+ (void) argv;
+ (void) arg_ptr;
+ (void) entry;
+
+ display_findutils_version ("find");
+ printf (_("Features enabled: "));
+
+#if CACHE_IDS
+ printf ("CACHE_IDS(ignored) ");
+ has_features = true;
+#endif
+#if DEBUG
+ printf ("DEBUG ");
+ has_features = true;
+#endif
+#if DEBUG_STAT
+ printf ("DEBUG_STAT ");
+ has_features = true;
+#endif
+#if defined HAVE_STRUCT_DIRENT_D_TYPE
+ printf ("D_TYPE ");
+ has_features = true;
+#endif
+#if defined O_NOFOLLOW
+ printf ("O_NOFOLLOW(%s) ",
+ (options.open_nofollow_available ? "enabled" : "disabled"));
+ has_features = true;
+#endif
+#if defined LEAF_OPTIMISATION
+ printf ("LEAF_OPTIMISATION ");
+ has_features = true;
+#endif
+ if (0 < is_selinux_enabled ())
+ {
+ printf ("SELINUX ");
+ has_features = true;
+ }
+
+ flags = 0;
+ if (is_fts_enabled (&flags))
+ {
+ int nflags = 0;
+ printf ("FTS(");
+ has_features = true;
+
+ if (flags & FTS_CWDFD)
+ {
+ if (nflags)
+ {
+ printf (",");
+ }
+ printf ("FTS_CWDFD");
+ has_features = true;
+ }
+ printf (") ");
+ }
+
+ printf ("CBO(level=%d) ", (int)(options.optimisation_level));
+ has_features = true;
+
+ if (!has_features)
+ {
+ /* For the moment, leave this as English in case someone wants
+ to parse these strings. */
+ printf ("none");
+ }
+ printf ("\n");
+
+ exit (EXIT_SUCCESS);
+}
+
+static bool
+parse_context (const struct parser_table* entry, char **argv, int *arg_ptr)
+{
+ struct predicate *our_pred;
+
+ if ((argv == NULL) || (argv[*arg_ptr] == NULL))
+ return false;
+
+ if (is_selinux_enabled () <= 0)
+ {
+ error (EXIT_FAILURE, 0,
+ _("invalid predicate -context: SELinux is not enabled."));
+ return false;
+ }
+ our_pred = insert_primary (entry, NULL);
+ our_pred->est_success_rate = 0.01f;
+ our_pred->need_stat = false;
+#ifdef DEBUG
+ our_pred->p_name = find_pred_name (pred_context);
+#endif /*DEBUG*/
+ our_pred->args.scontext = argv[*arg_ptr];
+
+ (*arg_ptr)++;
+ return true;
+}
+
+static bool
+parse_xdev (const struct parser_table* entry, char **argv, int *arg_ptr)
+{
+ options.stay_on_filesystem = true;
+ return parse_noop (entry, argv, arg_ptr);
+}
+
+static bool
+parse_ignore_race (const struct parser_table* entry, char **argv, int *arg_ptr)
+{
+ options.ignore_readdir_race = true;
+ return parse_noop (entry, argv, arg_ptr);
+}
+
+static bool
+parse_noignore_race (const struct parser_table* entry, char **argv, int *arg_ptr)
+{
+ options.ignore_readdir_race = false;
+ return parse_noop (entry, argv, arg_ptr);
+}
+
+static bool
+parse_warn (const struct parser_table* entry, char **argv, int *arg_ptr)
+{
+ options.warnings = true;
+ return parse_noop (entry, argv, arg_ptr);
+}
+
+static bool
+parse_xtype (const struct parser_table* entry, char **argv, int *arg_ptr)
+{
+ return insert_type (argv, arg_ptr, entry, pred_xtype);
+}
+
+static bool
+insert_type (char **argv, int *arg_ptr,
+ const struct parser_table *entry,
+ PRED_FUNC which_pred)
+{
+ mode_t type_cell;
+ struct predicate *our_pred;
+ float rate = 0.5;
+ const char *typeletter;
+
+ if (collect_arg (argv, arg_ptr, &typeletter))
+ {
+ if (strlen (typeletter) != 1u)
+ {
+ error (EXIT_FAILURE, 0,
+ _("Arguments to -type should contain only one letter"));
+ /*NOTREACHED*/
+ return false;
+ }
+
+ switch (typeletter[0])
+ {
+ case 'b': /* block special */
+ type_cell = S_IFBLK;
+ rate = 0.01f;
+ break;
+ case 'c': /* character special */
+ type_cell = S_IFCHR;
+ rate = 0.01f;
+ break;
+ case 'd': /* directory */
+ type_cell = S_IFDIR;
+ rate = 0.4f;
+ break;
+ case 'f': /* regular file */
+ type_cell = S_IFREG;
+ rate = 0.95f;
+ break;
+ case 'l': /* symbolic link */
+#ifdef S_IFLNK
+ type_cell = S_IFLNK;
+ rate = 0.1f;
+#else
+ error (EXIT_FAILURE, 0,
+ _("-type %c is not supported because symbolic links "
+ "are not supported on the platform find was compiled on."),
+ (*typeletter));
+#endif
+ break;
+ case 'p': /* pipe */
+#ifdef S_IFIFO
+ type_cell = S_IFIFO;
+ rate = 0.01f;
+#else
+ error (EXIT_FAILURE, 0,
+ _("-type %c is not supported because FIFOs "
+ "are not supported on the platform find was compiled on."),
+ (*typeletter));
+#endif
+ break;
+ case 's': /* socket */
+#ifdef S_IFSOCK
+ type_cell = S_IFSOCK;
+ rate = 0.01f;
+#else
+ error (EXIT_FAILURE, 0,
+ _("-type %c is not supported because named sockets "
+ "are not supported on the platform find was compiled on."),
+ (*typeletter));
+#endif
+ break;
+ case 'D': /* Solaris door */
+#ifdef S_IFDOOR
+ type_cell = S_IFDOOR;
+ rate = 0.01f;
+#else
+ error (EXIT_FAILURE, 0,
+ _("-type %c is not supported because Solaris doors "
+ "are not supported on the platform find was compiled on."),
+ (*typeletter));
+#endif
+ break;
+ default: /* None of the above ... nuke 'em. */
+ error (EXIT_FAILURE, 0,
+ _("Unknown argument to -type: %c"), (*typeletter));
+ /*NOTREACHED*/
+ return false;
+ }
+ our_pred = insert_primary_withpred (entry, which_pred, typeletter);
+ our_pred->est_success_rate = rate;
+
+ /* Figure out if we will need to stat the file, because if we don't
+ * need to follow symlinks, we can avoid a stat call by using
+ * struct dirent.d_type.
+ */
+ if (which_pred == pred_xtype)
+ {
+ our_pred->need_stat = true;
+ our_pred->need_type = false;
+ }
+ else
+ {
+ our_pred->need_stat = false; /* struct dirent is enough */
+ our_pred->need_type = true;
+ }
+ our_pred->args.type = type_cell;
+ return true;
+ }
+ return false;
+}
+
+
+/* Return true if the file accessed via FP is a terminal.
+ */
+static bool
+stream_is_tty (FILE *fp)
+{
+ int fd = fileno (fp);
+ if (-1 == fd)
+ {
+ return false; /* not a valid stream */
+ }
+ else
+ {
+ return isatty (fd) ? true : false;
+ }
+
+}
+
+
+
+
+
+
+static void
+check_path_safety (const char *action)
+{
+ const char *path = getenv ("PATH");
+ const char *path_separators = ":";
+ size_t pos, len;
+
+ if (NULL == path)
+ {
+ /* $PATH is not set. Assume the OS default is safe.
+ * That may not be true on Windows, but I'm not aware
+ * of a way to get Windows to avoid searching the
+ * current directory anyway.
+ */
+ return;
+ }
+
+ splitstring (path, path_separators, true, &pos, &len);
+ do
+ {
+ if (0 == len || (1 == len && path[pos] == '.'))
+ {
+ /* empty field signifies . */
+ error (EXIT_FAILURE, 0,
+ _("The current directory is included in the PATH "
+ "environment variable, which is insecure in "
+ "combination with the %s action of find. "
+ "Please remove the current directory from your "
+ "$PATH (that is, remove \".\", doubled colons, "
+ "or leading or trailing colons)"),
+ action);
+ }
+ else if (path[pos] != '/')
+ {
+ char *relpath = strndup (&path[pos], len);
+ error (EXIT_FAILURE, 0,
+ _("The relative path %s is included in the PATH "
+ "environment variable, which is insecure in "
+ "combination with the %s action of find. "
+ "Please remove that entry from $PATH"),
+ safely_quote_err_filename (0, relpath ? relpath : &path[pos]),
+ action);
+ /*NOTREACHED*/
+ free (relpath);
+ }
+ } while (splitstring (path, path_separators, false, &pos, &len));
+}
+
+
+/* handles both exec and ok predicate */
+static bool
+insert_exec_ok (const char *action,
+ const struct parser_table *entry,
+ char **argv,
+ int *arg_ptr)
+{
+ int start, end; /* Indexes in ARGV of start & end of cmd. */
+ int i; /* Index into cmd args */
+ int saw_braces; /* True if previous arg was '{}'. */
+ bool allow_plus; /* True if + is a valid terminator */
+ int brace_count; /* Number of instances of {}. */
+ const char *brace_arg; /* Which arg did {} appear in? */
+ PRED_FUNC func = entry->pred_func;
+ enum BC_INIT_STATUS bcstatus;
+
+ struct predicate *our_pred;
+ struct exec_val *execp; /* Pointer for efficiency. */
+
+ if ((argv == NULL) || (argv[*arg_ptr] == NULL))
+ return false;
+
+ our_pred = insert_primary_withpred (entry, func, "(some -exec* arguments)");
+ our_pred->side_effects = our_pred->no_default_print = true;
+ our_pred->need_type = our_pred->need_stat = false;
+
+ execp = &our_pred->args.exec_vec;
+ execp->wd_for_exec = NULL;
+
+ if ((func != pred_okdir) && (func != pred_ok))
+ {
+ allow_plus = true;
+ execp->close_stdin = false;
+ }
+ else
+ {
+ allow_plus = false;
+ /* If find reads stdin (i.e. for -ok and similar), close stdin
+ * in the child to prevent some script from consiming the output
+ * intended for find.
+ */
+ execp->close_stdin = true;
+ }
+
+
+ if ((func == pred_execdir) || (func == pred_okdir))
+ {
+ execp->wd_for_exec = NULL;
+ options.ignore_readdir_race = false;
+ check_path_safety (action);
+ }
+ else
+ {
+ assert (NULL != initial_wd);
+ execp->wd_for_exec = initial_wd;
+ }
+
+ our_pred->args.exec_vec.multiple = 0;
+
+ /* Count the number of args with path replacements, up until the ';'.
+ * Also figure out if the command is terminated by ";" or by "+".
+ */
+ start = *arg_ptr;
+ for (end = start, saw_braces=0, brace_count=0, brace_arg=NULL;
+ (argv[end] != NULL)
+ && ((argv[end][0] != ';') || (argv[end][1] != '\0'));
+ end++)
+ {
+ /* For -exec and -execdir, "{} +" can terminate the command. */
+ if ( allow_plus
+ && argv[end][0] == '+' && argv[end][1] == 0
+ && saw_braces)
+ {
+ our_pred->args.exec_vec.multiple = 1;
+ break;
+ }
+
+ saw_braces = 0;
+ if (mbsstr (argv[end], "{}"))
+ {
+ saw_braces = 1;
+ brace_arg = argv[end];
+ ++brace_count;
+
+ if (0 == end && (func == pred_execdir || func == pred_okdir))
+ {
+ /* The POSIX standard says that {} replacement should
+ * occur even in the utility name. This is insecure
+ * since it means we will be executing a command whose
+ * name is chosen according to whatever find finds in
+ * the file system. That can be influenced by an
+ * attacker. Hence for -execdir and -okdir this is not
+ * allowed. We can specify this as those options are
+ * not defined by POSIX.
+ */
+ error (EXIT_FAILURE, 0,
+ _("You may not use {} within the utility name for "
+ "-execdir and -okdir, because this is a potential "
+ "security problem."));
+ }
+ }
+ }
+
+ /* Fail if no command given or no semicolon found. */
+ if ((end == start) || (argv[end] == NULL))
+ {
+ *arg_ptr = end;
+ free (our_pred);
+ return false;
+ }
+
+ if (our_pred->args.exec_vec.multiple)
+ {
+ const char *suffix;
+ if (func == pred_execdir)
+ suffix = "dir";
+ else
+ suffix = "";
+
+ if (brace_count > 1)
+ {
+ error (EXIT_FAILURE, 0,
+ _("Only one instance of {} is supported with -exec%s ... +"),
+ suffix);
+ }
+ else if (strlen (brace_arg) != 2u)
+ {
+ enum { MsgBufSize = 19 };
+ char buf[MsgBufSize];
+ const size_t needed = snprintf (buf, MsgBufSize, "-exec%s ... {} +", suffix);
+ assert (needed <= MsgBufSize); /* If this assertion fails, correct the value of MsgBufSize. */
+ error (EXIT_FAILURE, 0,
+ _("In %s the %s must appear by itself, but you specified %s"),
+ quotearg_n_style (0, options.err_quoting_style, buf),
+ quotearg_n_style (1, options.err_quoting_style, "{}"),
+ quotearg_n_style (2, options.err_quoting_style, brace_arg));
+ }
+ }
+
+ /* We use a switch statement here so that the compiler warns us when
+ * we forget to handle a newly invented enum value.
+ *
+ * Like xargs, we allow 2KiB of headroom for the launched utility to
+ * export its own environment variables before calling something
+ * else.
+ */
+ bcstatus = bc_init_controlinfo (&execp->ctl, 2048u);
+ switch (bcstatus)
+ {
+ case BC_INIT_ENV_TOO_BIG:
+ case BC_INIT_CANNOT_ACCOMODATE_HEADROOM:
+ error (EXIT_FAILURE, 0,
+ _("The environment is too large for exec()."));
+ break;
+ case BC_INIT_OK:
+ /* Good news. Carry on. */
+ break;
+ }
+ bc_use_sensible_arg_max (&execp->ctl);
+
+
+ execp->ctl.exec_callback = launch;
+
+ if (our_pred->args.exec_vec.multiple)
+ {
+ /* "+" terminator, so we can just append our arguments after the
+ * command and initial arguments.
+ */
+ execp->replace_vec = NULL;
+ execp->ctl.replace_pat = NULL;
+ execp->ctl.rplen = 0;
+ execp->ctl.lines_per_exec = 0; /* no limit */
+ execp->ctl.args_per_exec = 0; /* no limit */
+
+ /* remember how many arguments there are */
+ execp->ctl.initial_argc = (end-start) - 1;
+
+ /* execp->state = xmalloc(sizeof struct buildcmd_state); */
+ bc_init_state (&execp->ctl, &execp->state, execp);
+
+ /* Gather the initial arguments. Skip the {}. */
+ for (i=start; i<end-1; ++i)
+ {
+ bc_push_arg (&execp->ctl, &execp->state,
+ argv[i], strlen (argv[i])+1,
+ NULL, 0,
+ 1);
+ }
+ }
+ else
+ {
+ /* Semicolon terminator - more than one {} is supported, so we
+ * have to do brace-replacement.
+ */
+ execp->num_args = end - start;
+
+ execp->ctl.replace_pat = "{}";
+ execp->ctl.rplen = strlen (execp->ctl.replace_pat);
+ execp->ctl.lines_per_exec = 0; /* no limit */
+ execp->ctl.args_per_exec = 0; /* no limit */
+ execp->replace_vec = xmalloc (sizeof(char*)*execp->num_args);
+
+
+ /* execp->state = xmalloc(sizeof(*(execp->state))); */
+ bc_init_state (&execp->ctl, &execp->state, execp);
+
+ /* Remember the (pre-replacement) arguments for later. */
+ for (i=0; i<execp->num_args; ++i)
+ {
+ execp->replace_vec[i] = argv[i+start];
+ }
+ }
+
+ if (argv[end] == NULL)
+ *arg_ptr = end;
+ else
+ *arg_ptr = end + 1;
+
+ return true;
+}
+
+
+
+/* Get a timestamp and comparison type.
+
+ STR is the ASCII representation.
+ Set *NUM_DAYS to the number of days/minutes/whatever, taken as being
+ relative to ORIGIN (usually the current moment or midnight).
+ Thus the sense of the comparison type appears to be reversed.
+ Set *COMP_TYPE to the kind of comparison that is requested.
+ Issue OVERFLOWMESSAGE if overflow occurs.
+ Return true if all okay, false if input error.
+
+ Used by -atime, -ctime and -mtime (parsers) to
+ get the appropriate information for a time predicate processor. */
+
+static bool
+get_relative_timestamp (const char *str,
+ struct time_val *result,
+ struct timespec origin,
+ double sec_per_unit,
+ const char *overflowmessage)
+{
+ double offset, seconds, nanosec;
+ static const long nanosec_per_sec = 1000000000;
+
+ if (get_comp_type (&str, &result->kind))
+ {
+ /* Invert the sense of the comparison */
+ switch (result->kind)
+ {
+ case COMP_LT: result->kind = COMP_GT; break;
+ case COMP_GT: result->kind = COMP_LT; break;
+ case COMP_EQ:
+ break; /* inversion leaves it unchanged */
+ }
+
+ /* Convert the ASCII number into floating-point. */
+ if (xstrtod (str, NULL, &offset, strtod))
+ {
+ /* Separate the floating point number the user specified
+ * (which is a number of days, or minutes, etc) into an
+ * integral number of seconds (SECONDS) and a fraction (NANOSEC).
+ */
+ nanosec = modf (offset * sec_per_unit, &seconds);
+ nanosec *= 1.0e9; /* convert from fractional seconds to ns. */
+ assert (nanosec < nanosec_per_sec);
+
+ /* Perform the subtraction, and then check for overflow.
+ * On systems where signed aritmetic overflow does not
+ * wrap, this check may be unreliable. The C standard
+ * does not require this approach to work, but I am aware
+ * of no platforms where it fails.
+ */
+ result->ts.tv_sec = origin.tv_sec - seconds;
+ if ((origin.tv_sec < result->ts.tv_sec) != (seconds < 0))
+ {
+ /* an overflow has occurred. */
+ error (EXIT_FAILURE, 0, overflowmessage, str);
+ }
+
+ result->ts.tv_nsec = origin.tv_nsec - nanosec;
+ if (origin.tv_nsec < nanosec)
+ {
+ /* Perform a carry operation */
+ result->ts.tv_nsec += nanosec_per_sec;
+ result->ts.tv_sec -= 1;
+ }
+ return true;
+ }
+ else
+ {
+ /* Conversion from ASCII to double failed. */
+ return false;
+ }
+ }
+ else
+ {
+ return false;
+ }
+}
+
+/* Insert a time predicate based on the information in ENTRY.
+ ARGV is a pointer to the argument array.
+ ARG_PTR is a pointer to an index into the array, incremented if
+ all went well.
+
+ Return true if input is valid, false if not.
+
+ A new predicate node is assigned, along with an argument node
+ obtained with malloc.
+
+ Used by -atime, -ctime, and -mtime parsers. */
+
+static bool
+parse_time (const struct parser_table* entry, char *argv[], int *arg_ptr)
+{
+ struct predicate *our_pred;
+ struct time_val tval;
+ enum comparison_type comp;
+ const char *timearg, *orig_timearg;
+ const char *errmsg = _("arithmetic overflow while converting %s "
+ "days to a number of seconds");
+ struct timespec origin;
+ const int saved_argc = *arg_ptr;
+
+ if (!collect_arg (argv, arg_ptr, &timearg))
+ return false;
+ orig_timearg = timearg;
+
+ /* Decide the origin by previewing the comparison type. */
+ origin = options.cur_day_start;
+
+ if (get_comp_type (&timearg, &comp))
+ {
+ /* Remember, we invert the sense of the comparison, so this tests
+ * against COMP_LT instead of COMP_GT...
+ */
+ if (COMP_LT == comp)
+ {
+ uintmax_t expected = origin.tv_sec + (DAYSECS-1);
+ origin.tv_sec += (DAYSECS-1);
+ if (origin.tv_sec != expected)
+ {
+ error (EXIT_FAILURE, 0,
+ _("arithmetic overflow when trying to calculate the end of today"));
+ }
+ }
+ }
+ /* We discard the value of comp here, as get_relative_timestamp
+ * will set tval.kind. For that to work, we have to restore
+ * timearg so that it points to the +/- prefix, if any. get_comp_type()
+ * will have advanced timearg, so we restore it.
+ */
+ timearg = orig_timearg;
+
+ if (!get_relative_timestamp (timearg, &tval, origin, DAYSECS, errmsg))
+ {
+ *arg_ptr = saved_argc; /* don't consume the invalid argument */
+ return false;
+ }
+
+ our_pred = insert_primary (entry, orig_timearg);
+ our_pred->args.reftime = tval;
+ our_pred->est_success_rate = estimate_timestamp_success_rate (tval.ts.tv_sec);
+
+ if (options.debug_options & DebugExpressionTree)
+ {
+ time_t t;
+
+ fprintf (stderr, "inserting %s\n", our_pred->p_name);
+ fprintf (stderr, " type: %s %s ",
+ (tval.kind == COMP_GT) ? "gt" :
+ ((tval.kind == COMP_LT) ? "lt" : ((tval.kind == COMP_EQ) ? "eq" : "?")),
+ (tval.kind == COMP_GT) ? " >" :
+ ((tval.kind == COMP_LT) ? " <" : ((tval.kind == COMP_EQ) ? ">=" : " ?")));
+ t = our_pred->args.reftime.ts.tv_sec;
+ fprintf (stderr, "%ju %s",
+ (uintmax_t) our_pred->args.reftime.ts.tv_sec,
+ ctime (&t));
+ if (tval.kind == COMP_EQ)
+ {
+ t = our_pred->args.reftime.ts.tv_sec + DAYSECS;
+ fprintf (stderr, " < %ju %s",
+ (uintmax_t) t, ctime (&t));
+ }
+ }
+
+ return true;
+}
+
+/* Get the comparison type prefix (if any) from a number argument.
+ The prefix is at *STR.
+ Set *COMP_TYPE to the kind of comparison that is requested.
+ Advance *STR beyond any initial comparison prefix.
+
+ Return true if all okay, false if input error. */
+static bool
+get_comp_type (const char **str, enum comparison_type *comp_type)
+{
+ switch (**str)
+ {
+ case '+':
+ *comp_type = COMP_GT;
+ (*str)++;
+ break;
+ case '-':
+ *comp_type = COMP_LT;
+ (*str)++;
+ break;
+ default:
+ *comp_type = COMP_EQ;
+ break;
+ }
+ return true;
+}
+
+
+
+
+
+/* Get a number with comparison information.
+ The sense of the comparison information is 'normal'; that is,
+ '+' looks for a count > than the number and '-' less than.
+
+ STR is the ASCII representation of the number.
+ Set *NUM to the number.
+ Set *COMP_TYPE to the kind of comparison that is requested.
+
+ Return true if all okay, false if input error. */
+
+static bool
+get_num (const char *str,
+ uintmax_t *num,
+ enum comparison_type *comp_type)
+{
+ char *pend;
+
+ if (str == NULL)
+ return false;
+
+ /* Figure out the comparison type if the caller accepts one. */
+ if (comp_type)
+ {
+ if (!get_comp_type (&str, comp_type))
+ return false;
+ }
+
+ return xstrtoumax (str, &pend, 10, num, "") == LONGINT_OK;
+}
+
+/* Insert a number predicate.
+ ARGV is a pointer to the argument array.
+ *ARG_PTR is an index into ARGV, incremented if all went well.
+ *PRED is the predicate processor to insert.
+
+ Return true if input is valid, false if error.
+
+ A new predicate node is assigned, along with an argument node
+ obtained with malloc.
+
+ Used by -inum and -links parsers. */
+
+static struct predicate *
+insert_num (char **argv, int *arg_ptr, const struct parser_table *entry)
+{
+ const char *numstr;
+
+ if (collect_arg (argv, arg_ptr, &numstr))
+ {
+ uintmax_t num;
+ enum comparison_type c_type;
+
+ if (get_num (numstr, &num, &c_type))
+ {
+ struct predicate *our_pred = insert_primary (entry, numstr);
+ our_pred->args.numinfo.kind = c_type;
+ our_pred->args.numinfo.l_val = num;
+
+ if (options.debug_options & DebugExpressionTree)
+ {
+ fprintf (stderr, "inserting %s\n", our_pred->p_name);
+ fprintf (stderr, " type: %s %s ",
+ (c_type == COMP_GT) ? "gt" :
+ ((c_type == COMP_LT) ? "lt" : ((c_type == COMP_EQ) ? "eq" : "?")),
+ (c_type == COMP_GT) ? " >" :
+ ((c_type == COMP_LT) ? " <" : ((c_type == COMP_EQ) ? " =" : " ?")));
+ fprintf (stderr, "%ju\n", our_pred->args.numinfo.l_val);
+ }
+ return our_pred;
+ }
+ }
+ return NULL;
+}
+
+static void
+open_output_file (const char *path, struct format_val *p)
+{
+ p->segment = NULL;
+ p->quote_opts = clone_quoting_options (NULL);
+
+ if (!strcmp (path, "/dev/stderr"))
+ {
+ p->stream = stderr;
+ p->filename = _("standard error");
+ }
+ else if (!strcmp (path, "/dev/stdout"))
+ {
+ p->stream = stdout;
+ p->filename = _("standard output");
+ }
+ else
+ {
+ p->stream = sharefile_fopen (state.shared_files, path);
+ p->filename = path;
+
+ if (p->stream == NULL)
+ {
+ fatal_nontarget_file_error (errno, path);
+ }
+ }
+
+ p->dest_is_tty = stream_is_tty (p->stream);
+}
+
+static void
+open_stdout (struct format_val *p)
+{
+ open_output_file ("/dev/stdout", p);
+}
diff --git a/find/pred.c b/find/pred.c
new file mode 100644
index 0000000..32938fb
--- /dev/null
+++ b/find/pred.c
@@ -0,0 +1,1388 @@
+/* pred.c -- execute the expression tree.
+ Copyright (C) 1990, 1991, 1992, 1993, 1994, 2000, 2003, 2004, 2005,
+ 2006, 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/* config.h always comes first. */
+#include <config.h>
+
+/* system headers. */
+#include <assert.h>
+#include <ctype.h>
+#include <dirent.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <grp.h>
+#include <locale.h>
+#include <math.h>
+#include <pwd.h>
+#include <selinux/selinux.h>
+#include <stdarg.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <unistd.h> /* for unlinkat() */
+
+/* gnulib headers. */
+#include "areadlink.h"
+#include "dirname.h"
+#include "error.h"
+#include "fnmatch.h"
+#include "gettext.h"
+#include "stat-size.h"
+#include "stat-time.h"
+#include "yesno.h"
+
+/* find headers. */
+#include "defs.h"
+#include "dircallback.h"
+#include "listfile.h"
+#include "printquoted.h"
+
+
+
+#if ENABLE_NLS
+# include <libintl.h>
+# define _(Text) gettext (Text)
+#else
+# define _(Text) Text
+#endif
+#ifdef gettext_noop
+# define N_(String) gettext_noop (String)
+#else
+/* See locate.c for explanation as to why not use (String) */
+# define N_(String) String
+#endif
+
+#ifdef CLOSEDIR_VOID
+/* Fake a return value. */
+#define CLOSEDIR(d) (closedir (d), 0)
+#else
+#define CLOSEDIR(d) closedir (d)
+#endif
+
+static bool match_lname (const char *pathname, struct stat *stat_buf, struct predicate *pred_ptr, bool ignore_case);
+
+#ifdef DEBUG
+struct pred_assoc
+{
+ PRED_FUNC pred_func;
+ char *pred_name;
+};
+
+struct pred_assoc pred_table[] =
+{
+ {pred_amin, "amin "},
+ {pred_and, "and "},
+ {pred_anewer, "anewer "},
+ {pred_atime, "atime "},
+ {pred_closeparen, ") "},
+ {pred_cmin, "cmin "},
+ {pred_cnewer, "cnewer "},
+ {pred_comma, ", "},
+ {pred_ctime, "ctime "},
+ {pred_delete, "delete "},
+ {pred_empty, "empty "},
+ {pred_exec, "exec "},
+ {pred_execdir, "execdir "},
+ {pred_executable, "executable "},
+ {pred_false, "false "},
+ {pred_fprint, "fprint "},
+ {pred_fprint0, "fprint0 "},
+ {pred_fprintf, "fprintf "},
+ {pred_fstype, "fstype "},
+ {pred_gid, "gid "},
+ {pred_group, "group "},
+ {pred_ilname, "ilname "},
+ {pred_iname, "iname "},
+ {pred_inum, "inum "},
+ {pred_ipath, "ipath "},
+ {pred_links, "links "},
+ {pred_lname, "lname "},
+ {pred_ls, "ls "},
+ {pred_mmin, "mmin "},
+ {pred_mtime, "mtime "},
+ {pred_name, "name "},
+ {pred_negate, "not "},
+ {pred_newer, "newer "},
+ {pred_newerXY, "newerXY "},
+ {pred_nogroup, "nogroup "},
+ {pred_nouser, "nouser "},
+ {pred_ok, "ok "},
+ {pred_okdir, "okdir "},
+ {pred_openparen, "( "},
+ {pred_or, "or "},
+ {pred_path, "path "},
+ {pred_perm, "perm "},
+ {pred_print, "print "},
+ {pred_print0, "print0 "},
+ {pred_prune, "prune "},
+ {pred_quit, "quit "},
+ {pred_readable, "readable "},
+ {pred_regex, "regex "},
+ {pred_samefile,"samefile "},
+ {pred_size, "size "},
+ {pred_true, "true "},
+ {pred_type, "type "},
+ {pred_uid, "uid "},
+ {pred_used, "used "},
+ {pred_user, "user "},
+ {pred_writable, "writable "},
+ {pred_xtype, "xtype "},
+ {pred_context, "context"},
+ {0, "none "}
+};
+#endif
+
+/* Returns ts1 - ts2 */
+static double ts_difference (struct timespec ts1,
+ struct timespec ts2)
+{
+ double d = difftime (ts1.tv_sec, ts2.tv_sec)
+ + (1.0e-9 * (ts1.tv_nsec - ts2.tv_nsec));
+ return d;
+}
+
+
+static int
+compare_ts (struct timespec ts1,
+ struct timespec ts2)
+{
+ if ((ts1.tv_sec == ts2.tv_sec) &&
+ (ts1.tv_nsec == ts2.tv_nsec))
+ {
+ return 0;
+ }
+ else
+ {
+ double diff = ts_difference (ts1, ts2);
+ return diff < 0.0 ? -1 : +1;
+ }
+}
+
+/* Predicate processing routines.
+
+ PATHNAME is the full pathname of the file being checked.
+ *STAT_BUF contains information about PATHNAME.
+ *PRED_PTR contains information for applying the predicate.
+
+ Return true if the file passes this predicate, false if not. */
+
+
+/* pred_timewindow
+ *
+ * Returns true if THE_TIME is
+ * COMP_GT: after the specified time
+ * COMP_LT: before the specified time
+ * COMP_EQ: after the specified time but by not more than WINDOW seconds.
+ */
+static bool
+pred_timewindow (struct timespec ts, struct predicate const *pred_ptr, int window)
+{
+ switch (pred_ptr->args.reftime.kind)
+ {
+ case COMP_GT:
+ return compare_ts (ts, pred_ptr->args.reftime.ts) > 0;
+
+ case COMP_LT:
+ return compare_ts (ts, pred_ptr->args.reftime.ts) < 0;
+
+ case COMP_EQ:
+ {
+ /* consider "find . -mtime 0".
+ *
+ * Here, the origin is exactly 86400 seconds before the start
+ * of the program (since -daystart was not specified). This
+ * function will be called with window=86400 and
+ * pred_ptr->args.reftime.ts as the origin. Hence a file
+ * created the instant the program starts will show a time
+ * difference (value of delta) of 86400. Similarly, a file
+ * created exactly 24h ago would be the newest file which was
+ * _not_ created today. So, if delta is 0.0, the file
+ * was not created today. If the delta is 86400, the file
+ * was created this instant.
+ */
+ double delta = ts_difference (ts, pred_ptr->args.reftime.ts);
+ return (delta > 0.0 && delta <= window);
+ }
+ }
+ assert (0);
+ abort ();
+}
+
+
+bool
+pred_amin (const char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
+{
+ (void) &pathname;
+ return pred_timewindow (get_stat_atime(stat_buf), pred_ptr, 60);
+}
+
+bool
+pred_and (const char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
+{
+ if (pred_ptr->pred_left == NULL
+ || apply_predicate (pathname, stat_buf, pred_ptr->pred_left))
+ {
+ return apply_predicate (pathname, stat_buf, pred_ptr->pred_right);
+ }
+ else
+ return false;
+}
+
+bool
+pred_anewer (const char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
+{
+ (void) &pathname;
+ assert (COMP_GT == pred_ptr->args.reftime.kind);
+ return compare_ts (get_stat_atime(stat_buf), pred_ptr->args.reftime.ts) > 0;
+}
+
+bool
+pred_atime (const char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
+{
+ (void) &pathname;
+ return pred_timewindow (get_stat_atime(stat_buf), pred_ptr, DAYSECS);
+}
+
+bool
+pred_closeparen (const char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
+{
+ (void) &pathname;
+ (void) &stat_buf;
+ (void) &pred_ptr;
+
+ return true;
+}
+
+bool
+pred_cmin (const char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
+{
+ (void) pathname;
+ return pred_timewindow (get_stat_ctime(stat_buf), pred_ptr, 60);
+}
+
+bool
+pred_cnewer (const char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
+{
+ (void) pathname;
+
+ assert (COMP_GT == pred_ptr->args.reftime.kind);
+ return compare_ts (get_stat_ctime(stat_buf), pred_ptr->args.reftime.ts) > 0;
+}
+
+bool
+pred_comma (const char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
+{
+ if (pred_ptr->pred_left != NULL)
+ {
+ apply_predicate (pathname, stat_buf,pred_ptr->pred_left);
+ }
+ return apply_predicate (pathname, stat_buf, pred_ptr->pred_right);
+}
+
+bool
+pred_ctime (const char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
+{
+ (void) &pathname;
+ return pred_timewindow (get_stat_ctime(stat_buf), pred_ptr, DAYSECS);
+}
+
+static bool
+perform_delete (int flags)
+{
+ return 0 == unlinkat (state.cwd_dir_fd, state.rel_pathname, flags);
+}
+
+
+bool
+pred_delete (const char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
+{
+ (void) pred_ptr;
+ (void) stat_buf;
+ if (strcmp (state.rel_pathname, "."))
+ {
+ int flags=0;
+ if (state.have_stat && S_ISDIR(stat_buf->st_mode))
+ flags |= AT_REMOVEDIR;
+ if (perform_delete (flags))
+ {
+ return true;
+ }
+ else
+ {
+ if (EISDIR == errno)
+ {
+ if ((flags & AT_REMOVEDIR) == 0)
+ {
+ /* unlink() operation failed because we should have done rmdir(). */
+ flags |= AT_REMOVEDIR;
+ if (perform_delete (flags))
+ return true;
+ }
+ }
+ }
+ error (0, errno, _("cannot delete %s"),
+ safely_quote_err_filename (0, pathname));
+ /* Previously I had believed that having the -delete action
+ * return false provided the user with control over whether an
+ * error message is issued. While this is true, the policy of
+ * not affecting the exit status is contrary to the POSIX
+ * requirement that diagnostic messages are accompanied by a
+ * nonzero exit status. While -delete is not a POSIX option and
+ * we can therefore opt not to follow POSIX in this case, that
+ * seems somewhat arbitrary and confusing. So, as of
+ * findutils-4.3.11, we also set the exit status in this case.
+ */
+ state.exit_status = 1;
+ return false;
+ }
+ else
+ {
+ /* nothing to do. */
+ return true;
+ }
+}
+
+bool
+pred_empty (const char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
+{
+ (void) pathname;
+ (void) pred_ptr;
+
+ if (S_ISDIR (stat_buf->st_mode))
+ {
+ int fd;
+ DIR *d;
+ struct dirent *dp;
+ bool empty = true;
+
+ errno = 0;
+ if ((fd = openat (state.cwd_dir_fd, state.rel_pathname, O_RDONLY
+#if defined O_LARGEFILE
+ |O_LARGEFILE
+#endif
+ )) < 0)
+ {
+ error (0, errno, "%s", safely_quote_err_filename (0, pathname));
+ state.exit_status = 1;
+ return false;
+ }
+ d = fdopendir (fd);
+ if (d == NULL)
+ {
+ error (0, errno, "%s", safely_quote_err_filename (0, pathname));
+ state.exit_status = 1;
+ return false;
+ }
+ for (dp = readdir (d); dp; dp = readdir (d))
+ {
+ if (dp->d_name[0] != '.'
+ || (dp->d_name[1] != '\0'
+ && (dp->d_name[1] != '.' || dp->d_name[2] != '\0')))
+ {
+ empty = false;
+ break;
+ }
+ }
+ if (CLOSEDIR (d))
+ {
+ error (0, errno, "%s", safely_quote_err_filename (0, pathname));
+ state.exit_status = 1;
+ return false;
+ }
+ return (empty);
+ }
+ else if (S_ISREG (stat_buf->st_mode))
+ return (stat_buf->st_size == 0);
+ else
+ return (false);
+}
+
+
+bool
+pred_exec (const char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
+{
+ return impl_pred_exec (pathname, stat_buf, pred_ptr);
+}
+
+bool
+pred_execdir (const char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
+{
+ (void) &pathname;
+ return impl_pred_exec (state.rel_pathname, stat_buf, pred_ptr);
+}
+
+bool
+pred_false (const char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
+{
+ (void) &pathname;
+ (void) &stat_buf;
+ (void) &pred_ptr;
+
+
+ return (false);
+}
+
+bool
+pred_fls (const char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
+{
+ FILE * stream = pred_ptr->args.printf_vec.stream;
+ list_file (pathname, state.cwd_dir_fd, state.rel_pathname, stat_buf,
+ options.start_time.tv_sec,
+ options.output_block_size,
+ pred_ptr->literal_control_chars, stream);
+ return true;
+}
+
+bool
+pred_fprint (const char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
+{
+ (void) &pathname;
+ (void) &stat_buf;
+
+ print_quoted (pred_ptr->args.printf_vec.stream,
+ pred_ptr->args.printf_vec.quote_opts,
+ pred_ptr->args.printf_vec.dest_is_tty,
+ "%s\n",
+ pathname);
+ return true;
+}
+
+bool
+pred_fprint0 (const char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
+{
+ FILE * fp = pred_ptr->args.printf_vec.stream;
+
+ (void) &stat_buf;
+
+ fputs (pathname, fp);
+ putc (0, fp);
+ return true;
+}
+
+
+
+bool
+pred_fstype (const char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
+{
+ (void) pathname;
+
+ if (strcmp (filesystem_type (stat_buf, pathname), pred_ptr->args.str) == 0)
+ return true;
+ else
+ return false;
+}
+
+bool
+pred_gid (const char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
+{
+ (void) pathname;
+
+ switch (pred_ptr->args.numinfo.kind)
+ {
+ case COMP_GT:
+ if (stat_buf->st_gid > pred_ptr->args.numinfo.l_val)
+ return (true);
+ break;
+ case COMP_LT:
+ if (stat_buf->st_gid < pred_ptr->args.numinfo.l_val)
+ return (true);
+ break;
+ case COMP_EQ:
+ if (stat_buf->st_gid == pred_ptr->args.numinfo.l_val)
+ return (true);
+ break;
+ }
+ return (false);
+}
+
+bool
+pred_group (const char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
+{
+ (void) pathname;
+
+ if (pred_ptr->args.gid == stat_buf->st_gid)
+ return (true);
+ else
+ return (false);
+}
+
+bool
+pred_ilname (const char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
+{
+ return match_lname (pathname, stat_buf, pred_ptr, true);
+}
+
+/* Common code between -name, -iname. PATHNAME is being visited, STR
+ is name to compare basename against, and FLAGS are passed to
+ fnmatch. Recall that 'find / -name /' is one of the few times where a '/'
+ in the -name must actually find something. */
+static bool
+pred_name_common (const char *pathname, const char *str, int flags)
+{
+ bool b;
+ /* We used to use last_component() here, but that would not allow us to modify the
+ * input string, which is const. We could optimise by duplicating the string only
+ * if we need to modify it, and I'll do that if there is a measurable
+ * performance difference on a machine built after 1990...
+ */
+ char *base = base_name (pathname);
+ /* remove trailing slashes, but leave "/" or "//foo" unchanged. */
+ strip_trailing_slashes (base);
+
+ /* FNM_PERIOD is not used here because POSIX requires that it not be.
+ * See http://standards.ieee.org/reading/ieee/interp/1003-2-92_int/pasc-1003.2-126.html
+ */
+ b = fnmatch (str, base, flags) == 0;
+ free (base);
+ return b;
+}
+
+bool
+pred_iname (const char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
+{
+ (void) stat_buf;
+ return pred_name_common (pathname, pred_ptr->args.str, FNM_CASEFOLD);
+}
+
+bool
+pred_inum (const char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
+{
+ (void) pathname;
+
+ assert (stat_buf->st_ino != 0);
+
+ switch (pred_ptr->args.numinfo.kind)
+ {
+ case COMP_GT:
+ if (stat_buf->st_ino > pred_ptr->args.numinfo.l_val)
+ return (true);
+ break;
+ case COMP_LT:
+ if (stat_buf->st_ino < pred_ptr->args.numinfo.l_val)
+ return (true);
+ break;
+ case COMP_EQ:
+ if (stat_buf->st_ino == pred_ptr->args.numinfo.l_val)
+ return (true);
+ break;
+ }
+ return (false);
+}
+
+bool
+pred_ipath (const char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
+{
+ (void) stat_buf;
+
+ if (fnmatch (pred_ptr->args.str, pathname, FNM_CASEFOLD) == 0)
+ return (true);
+ return (false);
+}
+
+bool
+pred_links (const char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
+{
+ (void) pathname;
+
+ switch (pred_ptr->args.numinfo.kind)
+ {
+ case COMP_GT:
+ if (stat_buf->st_nlink > pred_ptr->args.numinfo.l_val)
+ return (true);
+ break;
+ case COMP_LT:
+ if (stat_buf->st_nlink < pred_ptr->args.numinfo.l_val)
+ return (true);
+ break;
+ case COMP_EQ:
+ if (stat_buf->st_nlink == pred_ptr->args.numinfo.l_val)
+ return (true);
+ break;
+ }
+ return (false);
+}
+
+bool
+pred_lname (const char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
+{
+ return match_lname (pathname, stat_buf, pred_ptr, false);
+}
+
+static bool
+match_lname (const char *pathname, struct stat *stat_buf, struct predicate *pred_ptr, bool ignore_case)
+{
+ bool ret = false;
+#ifdef S_ISLNK
+ if (S_ISLNK (stat_buf->st_mode))
+ {
+ char *linkname = areadlinkat (state.cwd_dir_fd, state.rel_pathname);
+ if (linkname)
+ {
+ if (fnmatch (pred_ptr->args.str, linkname,
+ ignore_case ? FNM_CASEFOLD : 0) == 0)
+ ret = true;
+ }
+ else
+ {
+ nonfatal_target_file_error (errno, pathname);
+ state.exit_status = 1;
+ }
+ free (linkname);
+ }
+#endif /* S_ISLNK */
+ return ret;
+}
+
+bool
+pred_ls (const char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
+{
+ return pred_fls (pathname, stat_buf, pred_ptr);
+}
+
+bool
+pred_mmin (const char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
+{
+ (void) &pathname;
+ return pred_timewindow (get_stat_mtime(stat_buf), pred_ptr, 60);
+}
+
+bool
+pred_mtime (const char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
+{
+ (void) pathname;
+ return pred_timewindow (get_stat_mtime(stat_buf), pred_ptr, DAYSECS);
+}
+
+bool
+pred_name (const char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
+{
+ (void) stat_buf;
+ return pred_name_common (pathname, pred_ptr->args.str, 0);
+}
+
+bool
+pred_negate (const char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
+{
+ return !apply_predicate (pathname, stat_buf, pred_ptr->pred_right);
+}
+
+bool
+pred_newer (const char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
+{
+ (void) pathname;
+
+ assert (COMP_GT == pred_ptr->args.reftime.kind);
+ return compare_ts (get_stat_mtime(stat_buf), pred_ptr->args.reftime.ts) > 0;
+}
+
+bool
+pred_newerXY (const char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
+{
+ struct timespec ts;
+ bool collected = false;
+
+ assert (COMP_GT == pred_ptr->args.reftime.kind);
+
+ switch (pred_ptr->args.reftime.xval)
+ {
+ case XVAL_TIME:
+ assert (pred_ptr->args.reftime.xval != XVAL_TIME);
+ return false;
+
+ case XVAL_ATIME:
+ ts = get_stat_atime (stat_buf);
+ collected = true;
+ break;
+
+ case XVAL_BIRTHTIME:
+ ts = get_stat_birthtime (stat_buf);
+ collected = true;
+ if (ts.tv_nsec < 0)
+ {
+ /* XXX: Cannot determine birth time. Warn once. */
+ error (0, 0, _("WARNING: cannot determine birth time of file %s"),
+ safely_quote_err_filename (0, pathname));
+ return false;
+ }
+ break;
+
+ case XVAL_CTIME:
+ ts = get_stat_ctime (stat_buf);
+ collected = true;
+ break;
+
+ case XVAL_MTIME:
+ ts = get_stat_mtime (stat_buf);
+ collected = true;
+ break;
+ }
+
+ assert (collected);
+ return compare_ts (ts, pred_ptr->args.reftime.ts) > 0;
+}
+
+bool
+pred_nogroup (const char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
+{
+ (void) pathname;
+ (void) pred_ptr;
+ return getgrgid (stat_buf->st_gid) == NULL;
+}
+
+bool
+pred_nouser (const char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
+{
+ (void) pathname;
+ (void) pred_ptr;
+ return getpwuid (stat_buf->st_uid) == NULL;
+}
+
+
+static bool
+is_ok (const char *program, const char *arg)
+{
+ fflush (stdout);
+ /* The draft open standard requires that, in the POSIX locale,
+ the last non-blank character of this prompt be '?'.
+ The exact format is not specified.
+ This standard does not have requirements for locales other than POSIX
+ */
+ /* XXX: printing UNTRUSTED data here. */
+ if (fprintf (stderr, _("< %s ... %s > ? "), program, arg) < 0)
+ {
+ error (EXIT_FAILURE, errno, _("Failed to write prompt for -ok"));
+ }
+ fflush (stderr);
+ return yesno ();
+}
+
+bool
+pred_ok (const char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
+{
+ if (is_ok (pred_ptr->args.exec_vec.replace_vec[0], pathname))
+ return impl_pred_exec (pathname, stat_buf, pred_ptr);
+ else
+ return false;
+}
+
+bool
+pred_okdir (const char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
+{
+ if (is_ok (pred_ptr->args.exec_vec.replace_vec[0], pathname))
+ return impl_pred_exec (state.rel_pathname, stat_buf, pred_ptr);
+ else
+ return false;
+}
+
+bool
+pred_openparen (const char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
+{
+ (void) pathname;
+ (void) stat_buf;
+ (void) pred_ptr;
+ return true;
+}
+
+bool
+pred_or (const char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
+{
+ if (pred_ptr->pred_left == NULL
+ || !apply_predicate (pathname, stat_buf, pred_ptr->pred_left))
+ {
+ return apply_predicate (pathname, stat_buf, pred_ptr->pred_right);
+ }
+ else
+ return true;
+}
+
+bool
+pred_path (const char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
+{
+ (void) stat_buf;
+ if (fnmatch (pred_ptr->args.str, pathname, 0) == 0)
+ return (true);
+ return (false);
+}
+
+bool
+pred_perm (const char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
+{
+ mode_t mode = stat_buf->st_mode;
+ mode_t perm_val = pred_ptr->args.perm.val[S_ISDIR (mode) != 0];
+ (void) pathname;
+ switch (pred_ptr->args.perm.kind)
+ {
+ case PERM_AT_LEAST:
+ return (mode & perm_val) == perm_val;
+ break;
+
+ case PERM_ANY:
+ /* True if any of the bits set in the mask are also set in the file's mode.
+ *
+ *
+ * Otherwise, if onum is prefixed by a hyphen, the primary shall
+ * evaluate as true if at least all of the bits specified in
+ * onum that are also set in the octal mask 07777 are set.
+ *
+ * Eric Blake's interpretation is that the mode argument is zero,
+
+ */
+ if (0 == perm_val)
+ return true; /* Savannah bug 14748; we used to return false */
+ else
+ return (mode & perm_val) != 0;
+ break;
+
+ case PERM_EXACT:
+ return (mode & MODE_ALL) == perm_val;
+ break;
+
+ default:
+ abort ();
+ break;
+ }
+}
+
+
+bool
+pred_executable (const char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
+{
+ (void) pathname;
+ (void) stat_buf;
+ (void) pred_ptr;
+
+ /* As for access, the check is performed with the real user id. */
+ return 0 == faccessat (state.cwd_dir_fd, state.rel_pathname, X_OK, 0);
+}
+
+bool
+pred_readable (const char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
+{
+ (void) pathname;
+ (void) stat_buf;
+ (void) pred_ptr;
+
+ /* As for access, the check is performed with the real user id. */
+ return 0 == faccessat (state.cwd_dir_fd, state.rel_pathname, R_OK, 0);
+}
+
+bool
+pred_writable (const char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
+{
+ (void) pathname;
+ (void) stat_buf;
+ (void) pred_ptr;
+
+ /* As for access, the check is performed with the real user id. */
+ return 0 == faccessat (state.cwd_dir_fd, state.rel_pathname, W_OK, 0);
+}
+
+bool
+pred_print (const char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
+{
+ (void) stat_buf;
+ (void) pred_ptr;
+
+ print_quoted (pred_ptr->args.printf_vec.stream,
+ pred_ptr->args.printf_vec.quote_opts,
+ pred_ptr->args.printf_vec.dest_is_tty,
+ "%s\n", pathname);
+ return true;
+}
+
+bool
+pred_print0 (const char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
+{
+ return pred_fprint0(pathname, stat_buf, pred_ptr);
+}
+
+bool
+pred_prune (const char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
+{
+ (void) pathname;
+ (void) pred_ptr;
+
+ if (options.do_dir_first == true) { /* no effect with -depth */
+ assert (state.have_stat);
+ if (stat_buf != NULL &&
+ S_ISDIR(stat_buf->st_mode))
+ state.stop_at_current_level = true;
+ }
+
+ /* findutils used to return options.do_dir_first here, so that -prune
+ * returns true only if -depth is not in effect. But POSIX requires
+ * that -prune always evaluate as true.
+ */
+ return true;
+}
+
+bool
+pred_quit (const char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
+{
+ (void) pathname;
+ (void) stat_buf;
+ (void) pred_ptr;
+
+ /* Run any cleanups. This includes executing any command lines
+ * we have partly built but not executed.
+ */
+ cleanup ();
+
+ /* Since -exec and friends don't leave child processes running in the
+ * background, there is no need to wait for them here.
+ */
+ exit (state.exit_status); /* 0 for success, etc. */
+}
+
+bool
+pred_regex (const char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
+{
+ int len = strlen (pathname);
+(void) stat_buf;
+ if (re_match (pred_ptr->args.regex, pathname, len, 0,
+ (struct re_registers *) NULL) == len)
+ return (true);
+ return (false);
+}
+
+bool
+pred_size (const char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
+{
+ uintmax_t f_val;
+
+ (void) pathname;
+ f_val = ((stat_buf->st_size / pred_ptr->args.size.blocksize)
+ + (stat_buf->st_size % pred_ptr->args.size.blocksize != 0));
+ switch (pred_ptr->args.size.kind)
+ {
+ case COMP_GT:
+ if (f_val > pred_ptr->args.size.size)
+ return (true);
+ break;
+ case COMP_LT:
+ if (f_val < pred_ptr->args.size.size)
+ return (true);
+ break;
+ case COMP_EQ:
+ if (f_val == pred_ptr->args.size.size)
+ return (true);
+ break;
+ }
+ return (false);
+}
+
+bool
+pred_samefile (const char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
+{
+ /* Potential optimisation: because of the loop protection, we always
+ * know the device of the current directory, hence the device number
+ * of the file we're currently considering. If -L is not in effect,
+ * and the device number of the file we're looking for is not the
+ * same as the device number of the current directory, this
+ * predicate cannot return true. Hence there would be no need to
+ * stat the file we're looking at.
+ *
+ * For the moment, we simply compare inode numbers, which should cut
+ * down greatly on the number of calls to stat. Some of the
+ * remainder will be unnecessary, but the additional complexity
+ * probably isn't worthwhile.
+ */
+ (void) pathname;
+
+ /* We will often still have an fd open on the file under consideration,
+ * but that's just to ensure inode number stability by maintaining
+ * a reference to it; we don't need the file for anything else.
+ */
+ if (stat_buf->st_ino)
+ {
+ if (stat_buf->st_ino != pred_ptr->args.samefileid.ino)
+ return false;
+ }
+ /* Now stat the file to check the device number. */
+ if (0 == get_statinfo (pathname, state.rel_pathname, stat_buf))
+ {
+ /* the repeated test here is necessary in case stat_buf.st_ino had been zero. */
+ return stat_buf->st_ino == pred_ptr->args.samefileid.ino
+ && stat_buf->st_dev == pred_ptr->args.samefileid.dev;
+ }
+ else
+ {
+ /* get_statinfo will already have emitted an error message. */
+ return false;
+ }
+}
+
+bool
+pred_true (const char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
+{
+ (void) pathname;
+ (void) stat_buf;
+ (void) pred_ptr;
+ return true;
+}
+
+bool
+pred_type (const char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
+{
+ mode_t mode;
+ mode_t type = pred_ptr->args.type;
+
+ assert (state.have_type);
+
+ if (0 == state.type)
+ {
+ /* This can sometimes happen with broken NFS servers.
+ * See Savannah bug #16378.
+ */
+ return false;
+ }
+
+ (void) pathname;
+
+ if (state.have_stat)
+ mode = stat_buf->st_mode;
+ else
+ mode = state.type;
+
+#ifndef S_IFMT
+ /* POSIX system; check `mode' the slow way. */
+ if ((S_ISBLK (mode) && type == S_IFBLK)
+ || (S_ISCHR (mode) && type == S_IFCHR)
+ || (S_ISDIR (mode) && type == S_IFDIR)
+ || (S_ISREG (mode) && type == S_IFREG)
+#ifdef S_IFLNK
+ || (S_ISLNK (mode) && type == S_IFLNK)
+#endif
+#ifdef S_IFIFO
+ || (S_ISFIFO (mode) && type == S_IFIFO)
+#endif
+#ifdef S_IFSOCK
+ || (S_ISSOCK (mode) && type == S_IFSOCK)
+#endif
+#ifdef S_IFDOOR
+ || (S_ISDOOR (mode) && type == S_IFDOOR)
+#endif
+ )
+#else /* S_IFMT */
+ /* Unix system; check `mode' the fast way. */
+ if ((mode & S_IFMT) == type)
+#endif /* S_IFMT */
+ return (true);
+ else
+ return (false);
+}
+
+bool
+pred_uid (const char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
+{
+ (void) pathname;
+ switch (pred_ptr->args.numinfo.kind)
+ {
+ case COMP_GT:
+ if (stat_buf->st_uid > pred_ptr->args.numinfo.l_val)
+ return (true);
+ break;
+ case COMP_LT:
+ if (stat_buf->st_uid < pred_ptr->args.numinfo.l_val)
+ return (true);
+ break;
+ case COMP_EQ:
+ if (stat_buf->st_uid == pred_ptr->args.numinfo.l_val)
+ return (true);
+ break;
+ }
+ return (false);
+}
+
+bool
+pred_used (const char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
+{
+ struct timespec delta, at, ct;
+
+ (void) pathname;
+
+ /* TODO: this needs to be retested carefully (manually, if necessary) */
+ at = get_stat_atime (stat_buf);
+ ct = get_stat_ctime (stat_buf);
+ delta.tv_sec = at.tv_sec - ct.tv_sec;
+ delta.tv_nsec = at.tv_nsec - ct.tv_nsec;
+ if (delta.tv_nsec < 0)
+ {
+ delta.tv_nsec += 1000000000;
+ delta.tv_sec -= 1;
+ }
+ return pred_timewindow (delta, pred_ptr, DAYSECS);
+}
+
+bool
+pred_user (const char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
+{
+ (void) pathname;
+ if (pred_ptr->args.uid == stat_buf->st_uid)
+ return (true);
+ else
+ return (false);
+}
+
+bool
+pred_xtype (const char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
+{
+ struct stat sbuf; /* local copy, not stat_buf because we're using a different stat method */
+ int (*ystat) (const char*, struct stat *p);
+
+ /* If we would normally stat the link itself, stat the target instead.
+ * If we would normally follow the link, stat the link itself instead.
+ */
+ if (following_links ())
+ ystat = optionp_stat;
+ else
+ ystat = optionl_stat;
+
+ set_stat_placeholders (&sbuf);
+ if ((*ystat) (state.rel_pathname, &sbuf) != 0)
+ {
+ if (following_links () && errno == ENOENT)
+ {
+ /* If we failed to follow the symlink,
+ * fall back on looking at the symlink itself.
+ */
+ /* Mimic behavior of ls -lL. */
+ return (pred_type (pathname, stat_buf, pred_ptr));
+ }
+ else
+ {
+ error (0, errno, "%s", safely_quote_err_filename (0, pathname));
+ state.exit_status = 1;
+ }
+ return false;
+ }
+ /* Now that we have our stat() information, query it in the same
+ * way that -type does.
+ */
+ return (pred_type (pathname, &sbuf, pred_ptr));
+}
+
+
+bool
+pred_context (const char *pathname, struct stat *stat_buf,
+ struct predicate *pred_ptr)
+{
+ security_context_t scontext;
+ int rv = (*options.x_getfilecon) (state.cwd_dir_fd, state.rel_pathname,
+ &scontext);
+ (void) stat_buf;
+
+ if (rv < 0)
+ {
+ error (0, errno, _("getfilecon failed: %s"),
+ safely_quote_err_filename (0, pathname));
+ return false;
+ }
+
+ rv = (fnmatch (pred_ptr->args.scontext, scontext, 0) == 0);
+ freecon (scontext);
+ return rv;
+}
+
+/* Copy STR into BUF and trim blanks from the end of BUF.
+ Return BUF. */
+
+static char *
+blank_rtrim (const char *str, char *buf)
+{
+ int i;
+
+ if (str == NULL)
+ return (NULL);
+ strcpy (buf, str);
+ i = strlen (buf) - 1;
+ while ((i >= 0) && ((buf[i] == ' ') || buf[i] == '\t'))
+ i--;
+ buf[++i] = '\0';
+ return buf;
+}
+
+/* Print out the predicate list starting at NODE. */
+void
+print_list (FILE *fp, struct predicate *node)
+{
+ struct predicate *cur;
+ char name[256];
+
+ cur = node;
+ while (cur != NULL)
+ {
+ fprintf (fp, "[%s] ", blank_rtrim (cur->p_name, name));
+ cur = cur->pred_next;
+ }
+ fprintf (fp, "\n");
+}
+
+/* Print out the predicate list starting at NODE. */
+static void
+print_parenthesised (FILE *fp, struct predicate *node)
+{
+ int parens = 0;
+
+ if (node)
+ {
+ if ((pred_is (node, pred_or) || pred_is (node, pred_and))
+ && node->pred_left == NULL)
+ {
+ /* We print "<nothing> or X" as just "X"
+ * We print "<nothing> and X" as just "X"
+ */
+ print_parenthesised(fp, node->pred_right);
+ }
+ else
+ {
+ if (node->pred_left || node->pred_right)
+ parens = 1;
+
+ if (parens)
+ fprintf (fp, "%s", " ( ");
+ print_optlist (fp, node);
+ if (parens)
+ fprintf (fp, "%s", " ) ");
+ }
+ }
+}
+
+void
+print_optlist (FILE *fp, const struct predicate *p)
+{
+ if (p)
+ {
+ print_parenthesised (fp, p->pred_left);
+ fprintf (fp,
+ "%s%s%s",
+ p->need_stat ? "[call stat] " : "",
+ p->need_type ? "[need type] " : "",
+ p->need_inum ? "[need inum] " : "");
+ print_predicate (fp, p);
+ fprintf (fp, " [%g] ", p->est_success_rate);
+ if (options.debug_options & DebugSuccessRates)
+ {
+ fprintf (fp, "[%ld/%ld", p->perf.successes, p->perf.visits);
+ if (p->perf.visits)
+ {
+ double real_rate = (double)p->perf.successes / (double)p->perf.visits;
+ fprintf (fp, "=%g] ", real_rate);
+ }
+ else
+ {
+ fprintf (fp, "=_] ");
+ }
+ }
+ print_parenthesised (fp, p->pred_right);
+ }
+}
+
+void show_success_rates (const struct predicate *p)
+{
+ if (options.debug_options & DebugSuccessRates)
+ {
+ fprintf (stderr, "Predicate success rates after completion:\n");
+ print_optlist (stderr, p);
+ fprintf (stderr, "\n");
+ }
+}
+
+
+
+
+#ifdef _NDEBUG
+/* If _NDEBUG is defined, the assertions will do nothing. Hence
+ * there is no point in having a function body for pred_sanity_check()
+ * if that preprocessor macro is defined.
+ */
+void
+pred_sanity_check (const struct predicate *predicates)
+{
+ /* Do nothing, since assert is a no-op with _NDEBUG set */
+ return;
+}
+#else
+void
+pred_sanity_check (const struct predicate *predicates)
+{
+ const struct predicate *p;
+
+ for (p=predicates; p != NULL; p=p->pred_next)
+ {
+ /* All predicates must do something. */
+ assert (p->pred_func != NULL);
+
+ /* All predicates must have a parser table entry. */
+ assert (p->parser_entry != NULL);
+
+ /* If the parser table tells us that just one predicate function is
+ * possible, verify that that is still the one that is in effect.
+ * If the parser has NULL for the predicate function, that means that
+ * the parse_xxx function fills it in, so we can't check it.
+ */
+ if (p->parser_entry->pred_func)
+ {
+ assert (p->parser_entry->pred_func == p->pred_func);
+ }
+
+ switch (p->parser_entry->type)
+ {
+ /* Options all take effect during parsing, so there should
+ * be no predicate entries corresponding to them. Hence we
+ * should not see any ARG_OPTION or ARG_POSITIONAL_OPTION
+ * items.
+ *
+ * This is a silly way of coding this test, but it prevents
+ * a compiler warning (i.e. otherwise it would think that
+ * there would be case statements missing).
+ */
+ case ARG_OPTION:
+ case ARG_POSITIONAL_OPTION:
+ assert (p->parser_entry->type != ARG_OPTION);
+ assert (p->parser_entry->type != ARG_POSITIONAL_OPTION);
+ break;
+
+ case ARG_ACTION:
+ assert (p->side_effects); /* actions have side effects. */
+ if (!pred_is (p, pred_prune) && !pred_is(p, pred_quit))
+ {
+ /* actions other than -prune and -quit should
+ * inhibit the default -print
+ */
+ assert (p->no_default_print);
+ }
+ break;
+
+ /* We happen to know that the only user of ARG_SPECIAL_PARSE
+ * is a test, so handle it like ARG_TEST.
+ */
+ case ARG_SPECIAL_PARSE:
+ case ARG_TEST:
+ case ARG_PUNCTUATION:
+ case ARG_NOOP:
+ /* Punctuation and tests should have no side
+ * effects and not inhibit default print.
+ */
+ assert (!p->no_default_print);
+ assert (!p->side_effects);
+ break;
+ }
+ }
+}
+#endif
diff --git a/find/print.c b/find/print.c
new file mode 100644
index 0000000..e4c28ad
--- /dev/null
+++ b/find/print.c
@@ -0,0 +1,1327 @@
+/* print.c -- print/printf-related code.
+ Copyright (C) 1990, 1991, 1992, 1993, 1994, 2000, 2001, 2003, 2004,
+ 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012 Free Software Foundation,
+ Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/* We always include config.h first. */
+#include <config.h>
+
+/* system headers go here. */
+#include <assert.h>
+#include <ctype.h>
+#include <errno.h>
+#include <grp.h>
+#include <locale.h>
+#include <math.h>
+#include <pwd.h>
+#include <stdarg.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+
+/* gnulib headers. */
+#include "areadlink.h"
+#include "dirname.h"
+#include "error.h"
+#include "filemode.h"
+#include "gettext.h"
+#include "human.h"
+#include "printquoted.h"
+#include "stat-size.h"
+#include "stat-time.h"
+#include "verify.h"
+#include "xalloc.h"
+
+/* find-specific headers. */
+#include "defs.h"
+#include "print.h"
+
+#if ENABLE_NLS
+# include <libintl.h>
+# define _(Text) gettext (Text)
+#else
+# define _(Text) Text
+#endif
+#ifdef gettext_noop
+# define N_(String) gettext_noop (String)
+#else
+/* See locate.c for explanation as to why not use (String) */
+# define N_(String) String
+#endif
+
+#if defined STDC_HEADERS
+# define ISDIGIT(c) isdigit ((unsigned char)c)
+#else
+# define ISDIGIT(c) (isascii ((unsigned char)c) && isdigit ((unsigned char)c))
+#endif
+#undef MAX
+#define MAX(a, b) ((a) > (b) ? (a) : (b))
+
+
+/* Create a new fprintf segment in *SEGMENT, with type KIND,
+ from the text in FORMAT, which has length LEN.
+ Return the address of the `next' pointer of the new segment. */
+struct segment **
+make_segment (struct segment **segment,
+ char *format,
+ int len,
+ int kind,
+ char format_char,
+ char aux_format_char,
+ struct predicate *pred)
+{
+ enum EvaluationCost mycost = NeedsNothing;
+ char *fmt;
+
+ assert (format_char != '{');
+ assert (format_char != '[');
+ assert (format_char != '(');
+
+ *segment = xmalloc (sizeof (struct segment));
+
+ (*segment)->segkind = kind;
+ (*segment)->format_char[0] = format_char;
+ (*segment)->format_char[1] = aux_format_char;
+ (*segment)->next = NULL;
+ (*segment)->text_len = len;
+
+ fmt = (*segment)->text = xmalloc (len + sizeof "d");
+ strncpy (fmt, format, len);
+ fmt += len;
+
+ if (kind == KIND_PLAIN /* Plain text string, no % conversion. */
+ || kind == KIND_STOP) /* Terminate argument, no newline. */
+ {
+ assert (0 == format_char);
+ assert (0 == aux_format_char);
+ *fmt = '\0';
+ if (mycost > pred->p_cost)
+ pred->p_cost = NeedsNothing;
+ return &(*segment)->next;
+ }
+
+ assert (kind == KIND_FORMAT);
+ switch (format_char)
+ {
+ case '%': /* literal % */
+ *fmt++ = '%';
+ break;
+
+ case 'l': /* object of symlink */
+ pred->need_stat = true;
+ mycost = NeedsLinkName;
+ *fmt++ = 's';
+ break;
+
+ case 'y': /* file type */
+ pred->need_type = true;
+ mycost = NeedsType;
+ *fmt++ = 's';
+ break;
+
+ case 'i': /* inode number */
+ pred->need_inum = true;
+ mycost = NeedsInodeNumber;
+ *fmt++ = 's';
+ break;
+
+ case 'a': /* atime in `ctime' format */
+ case 'A': /* atime in user-specified strftime format */
+ case 'B': /* birth time in user-specified strftime format */
+ case 'c': /* ctime in `ctime' format */
+ case 'C': /* ctime in user-specified strftime format */
+ case 'F': /* file system type */
+ case 'g': /* group name */
+ case 'M': /* mode in `ls -l' format (eg., "drwxr-xr-x") */
+ case 's': /* size in bytes */
+ case 't': /* mtime in `ctime' format */
+ case 'T': /* mtime in user-specified strftime format */
+ case 'u': /* user name */
+ pred->need_stat = true;
+ mycost = NeedsStatInfo;
+ *fmt++ = 's';
+ break;
+
+ case 'S': /* sparseness */
+ pred->need_stat = true;
+ mycost = NeedsStatInfo;
+ *fmt++ = 'g';
+ break;
+
+ case 'Y': /* symlink pointed file type */
+ pred->need_stat = true;
+ mycost = NeedsType; /* true for amortised effect */
+ *fmt++ = 's';
+ break;
+
+ case 'f': /* basename of path */
+ case 'h': /* leading directories part of path */
+ case 'p': /* pathname */
+ case 'P': /* pathname with ARGV element stripped */
+ *fmt++ = 's';
+ break;
+
+ case 'Z': /* SELinux security context */
+ mycost = NeedsAccessInfo;
+ *fmt++ = 's';
+ break;
+
+ case 'H': /* ARGV element file was found under */
+ *fmt++ = 's';
+ break;
+
+ /* Numeric items that one might expect to honour
+ * #, 0, + flags but which do not.
+ */
+ case 'G': /* GID number */
+ case 'U': /* UID number */
+ case 'b': /* size in 512-byte blocks (NOT birthtime in ctime fmt)*/
+ case 'D': /* Filesystem device on which the file exits */
+ case 'k': /* size in 1K blocks */
+ case 'n': /* number of links */
+ pred->need_stat = true;
+ mycost = NeedsStatInfo;
+ *fmt++ = 's';
+ break;
+
+ /* Numeric items that DO honour #, 0, + flags.
+ */
+ case 'd': /* depth in search tree (0 = ARGV element) */
+ *fmt++ = 'd';
+ break;
+
+ case 'm': /* mode as octal number (perms only) */
+ *fmt++ = 'o';
+ pred->need_stat = true;
+ mycost = NeedsStatInfo;
+ break;
+ }
+ *fmt = '\0';
+
+ if (mycost > pred->p_cost)
+ pred->p_cost = mycost;
+ return &(*segment)->next;
+}
+
+static bool
+is_octal_char (char ch)
+{
+ return ch >= '0' && ch <= '7';
+}
+
+static char
+parse_octal_escape(const char *p, size_t *consumed)
+{
+ register int n, i;
+ size_t pos = 0;
+
+ for (i = n = 0; i < 3 && is_octal_char(p[pos]); i++, pos++)
+ {
+ n = 8 * n + p[pos] - '0';
+ }
+ --pos;
+ *consumed = pos;
+ return n;
+}
+
+static int
+parse_escape_char(const char ch)
+{
+ char value = 0;
+ switch (ch)
+ {
+ case 'a':
+ value = '\a';
+ break;
+ case 'b':
+ value = '\b';
+ break;
+ case 'f':
+ value = '\f';
+ break;
+ case 'n':
+ value = '\n';
+ break;
+ case 'r':
+ value = '\r';
+ break;
+ case 't':
+ value = '\t';
+ break;
+ case 'v':
+ value = '\v';
+ break;
+ case '\\':
+ value = '\\';
+ break;
+ }
+ return value;
+}
+
+
+static size_t
+get_format_flags_length(const char *p)
+{
+ size_t n = 0;
+ /* Scan past flags, width and precision, to verify kind. */
+ for (; p[++n] && strchr ("-+ #", p[n]);)
+ {
+ /* Do nothing. */
+ }
+ while (ISDIGIT (p[n]))
+ n++;
+ if (p[n] == '.')
+ for (n++; ISDIGIT (p[n]); n++)
+ /* Do nothing. */ ;
+ return n;
+}
+
+static size_t
+get_format_specifer_length(char ch)
+{
+ if (strchr ("abcdDfFgGhHiklmMnpPsStuUyYZ%", ch))
+ {
+ return 1;
+ }
+ else if (strchr ("ABCT", ch))
+ {
+ return 2;
+ }
+ else
+ {
+ return 0;
+ }
+}
+
+
+bool
+insert_fprintf (struct format_val *vec,
+ const struct parser_table *entry,
+ char *format)
+{
+ char *segstart = format;
+ char *fmt_editpos; /* Current address in scanning `format'. */
+ struct segment **segmentp; /* Address of current segment. */
+ struct predicate *our_pred;
+
+ our_pred = insert_primary_withpred (entry, pred_fprintf, format);
+ our_pred->side_effects = our_pred->no_default_print = true;
+ our_pred->args.printf_vec = *vec;
+ our_pred->need_type = false;
+ our_pred->need_stat = false;
+ our_pred->p_cost = NeedsNothing;
+
+ segmentp = &our_pred->args.printf_vec.segment;
+ *segmentp = NULL;
+
+ for (fmt_editpos = segstart; *fmt_editpos; fmt_editpos++)
+ {
+ if (fmt_editpos[0] == '\\' && fmt_editpos[1] == 'c')
+ {
+ make_segment (segmentp, segstart, fmt_editpos - segstart,
+ KIND_STOP, 0, 0,
+ our_pred);
+ if (our_pred->need_stat && (our_pred->p_cost < NeedsStatInfo))
+ our_pred->p_cost = NeedsStatInfo;
+ return true;
+ }
+ else if (*fmt_editpos == '\\')
+ {
+ size_t readpos = 1;
+ if (!fmt_editpos[readpos])
+ {
+ error (0, 0, _("warning: escape `\\' followed by nothing at all"));
+ --readpos;
+ /* (*fmt_editpos) is already '\\' and that's a reasonable result. */
+ }
+ else if (is_octal_char(fmt_editpos[readpos]))
+ {
+ size_t consumed = 0;
+ *fmt_editpos = parse_octal_escape(fmt_editpos + readpos, &consumed);
+ readpos += consumed;
+ }
+ else
+ {
+ const char val = parse_escape_char(fmt_editpos[readpos]);
+ if (val)
+ {
+ fmt_editpos[0] = val;
+ }
+ else
+ {
+ error (0, 0, _("warning: unrecognized escape `\\%c'"),
+ fmt_editpos[readpos]);
+ fmt_editpos += readpos;
+ continue;
+ }
+ }
+ segmentp = make_segment (segmentp,
+ segstart, fmt_editpos - segstart + 1,
+ KIND_PLAIN, 0, 0,
+ our_pred);
+ segstart = fmt_editpos + readpos + 1; /* Move past the escape. */
+ fmt_editpos += readpos; /* Incremented immediately by `for'. */
+ }
+ else if (fmt_editpos[0] == '%')
+ {
+ size_t len;
+ if (fmt_editpos[1] == 0)
+ {
+ /* Trailing %. We don't like those. */
+ error (EXIT_FAILURE, 0,
+ _("error: %s at end of format string"), fmt_editpos);
+ }
+
+ if (fmt_editpos[1] == '%') /* %% produces just %. */
+ len = 1;
+ else
+ len = get_format_flags_length(fmt_editpos);
+ fmt_editpos += len;
+
+ len = get_format_specifer_length (fmt_editpos[0]);
+ if (len && (fmt_editpos[len-1]))
+ {
+ const char fmt2 = (len == 2) ? fmt_editpos[1] : 0;
+ segmentp = make_segment (segmentp, segstart,
+ fmt_editpos - segstart,
+ KIND_FORMAT, fmt_editpos[0], fmt2,
+ our_pred);
+ fmt_editpos += (len - 1);
+ }
+ else
+ {
+ if (strchr ("{[(", fmt_editpos[0]))
+ {
+ error (EXIT_FAILURE, 0,
+ _("error: the format directive `%%%c' is reserved for future use"),
+ (int)fmt_editpos[0]);
+ /*NOTREACHED*/
+ }
+
+ if (len == 2 && !fmt_editpos[1])
+ {
+ error (0, 0,
+ _("warning: format directive `%%%c' "
+ "should be followed by another character"),
+ fmt_editpos[0]);
+ }
+ else
+ {
+ /* An unrecognized % escape. Print the char after the %. */
+ error (0, 0,
+ _("warning: unrecognized format directive `%%%c'"),
+ fmt_editpos[0]);
+ }
+ segmentp = make_segment (segmentp,
+ segstart, fmt_editpos + 1 - segstart,
+ KIND_PLAIN, 0, 0,
+ our_pred);
+ }
+ segstart = fmt_editpos + 1;
+ }
+ }
+
+ if (fmt_editpos > segstart)
+ make_segment (segmentp, segstart, fmt_editpos - segstart, KIND_PLAIN, 0, 0,
+ our_pred);
+ return true;
+}
+
+static bool
+scan_for_digit_differences (const char *p, const char *q,
+ size_t *first, size_t *n)
+{
+ bool seen = false;
+ size_t i;
+
+ for (i=0; p[i] && q[i]; i++)
+ {
+ if (p[i] != q[i])
+ {
+ if (!isdigit ((unsigned char)q[i]) || !isdigit ((unsigned char)q[i]))
+ return false;
+
+ if (!seen)
+ {
+ *first = i;
+ *n = 1;
+ seen = 1;
+ }
+ else
+ {
+ if (i-*first == *n)
+ {
+ /* Still in the first sequence of differing digits. */
+ ++*n;
+ }
+ else
+ {
+ /* More than one differing contiguous character sequence. */
+ return false;
+ }
+ }
+ }
+ }
+ if (p[i] || q[i])
+ {
+ /* strings are different lengths. */
+ return false;
+ }
+ return true;
+}
+
+static char*
+do_time_format (const char *fmt, const struct tm *p, const char *ns, size_t ns_size)
+{
+ static char *buf = NULL;
+ static size_t buf_size;
+ char *timefmt = NULL;
+ struct tm altered_time;
+
+
+ /* If the format expands to nothing (%p in some locales, for
+ * example), strftime can return 0. We actually want to distinguish
+ * the error case where the buffer is too short, so we just prepend
+ * an otherwise uninteresting character to prevent the no-output
+ * case.
+ */
+ timefmt = xmalloc (strlen (fmt) + 2u);
+ timefmt[0] = '_';
+ memcpy (timefmt + 1, fmt, strlen (fmt) + 1);
+
+ /* altered_time is a similar time, but in which both
+ * digits of the seconds field are different.
+ */
+ altered_time = *p;
+ if (altered_time.tm_sec >= 11)
+ altered_time.tm_sec -= 11;
+ else
+ altered_time.tm_sec += 11;
+
+ /* If we call strftime() with buf_size=0, the program will coredump
+ * on Solaris, since it unconditionally writes the terminating null
+ * character.
+ */
+ if (buf == NULL)
+ {
+ buf_size = 1u;
+ buf = xmalloc (buf_size);
+ }
+ while (true)
+ {
+ /* I'm not sure that Solaris will return 0 when the buffer is too small.
+ * Therefore we do not check for (buf_used != 0) as the termination
+ * condition.
+ */
+ size_t buf_used = strftime (buf, buf_size, timefmt, p);
+ if (buf_used /* Conforming POSIX system */
+ && (buf_used < buf_size)) /* Solaris workaround */
+ {
+ char *altbuf;
+ size_t i = 0, n = 0;
+ size_t final_len = (buf_used
+ + 1u /* for \0 */
+ + ns_size);
+ buf = xrealloc (buf, final_len);
+ buf_size = final_len;
+ altbuf = xmalloc (final_len);
+ strftime (altbuf, buf_size, timefmt, &altered_time);
+
+ /* Find the seconds digits; they should be the only changed part.
+ * In theory the result of the two formatting operations could differ in
+ * more than just one sequence of decimal digits (for example %X might
+ * in theory return a spelled-out time like "thirty seconds past noon").
+ * When that happens, we just avoid inserting the nanoseconds field.
+ */
+ if (scan_for_digit_differences (buf, altbuf, &i, &n)
+ && (2==n) && !isdigit ((unsigned char)buf[i+n]))
+ {
+ const size_t end_of_seconds = i + n;
+ const size_t suffix_len = buf_used-(end_of_seconds)+1;
+
+ /* Move the tail (including the \0). Note that this
+ * is a move of an overlapping memory block, so we
+ * must use memmove instead of memcpy. Then insert
+ * the nanoseconds (but not its trailing \0).
+ */
+ assert (end_of_seconds + ns_size + suffix_len == final_len);
+ memmove (buf+end_of_seconds+ns_size,
+ buf+end_of_seconds,
+ suffix_len);
+ memcpy (buf+i+n, ns, ns_size);
+ }
+ else
+ {
+ /* No seconds digits. No need to insert anything. */
+ }
+ /* The first character of buf is the underscore, which we actually
+ * don't want.
+ */
+ free (timefmt);
+ free (altbuf);
+ return buf+1;
+ }
+ else
+ {
+ buf = x2nrealloc (buf, &buf_size, sizeof *buf);
+ }
+ }
+}
+
+/* Return a static string formatting the time WHEN according to the
+ * strftime format character KIND.
+ *
+ * This function contains a number of assertions. These look like
+ * runtime checks of the results of computations, which would be a
+ * problem since external events should not be tested for with
+ * "assert" (instead you should use "if"). However, they are not
+ * really runtime checks. The assertions actually exist to verify
+ * that the various buffers are correctly sized.
+ */
+static char *
+format_date (struct timespec ts, int kind)
+{
+ /* In theory, we use an extra 10 characters for 9 digits of
+ * nanoseconds and 1 for the decimal point. However, the real
+ * world is more complex than that.
+ *
+ * For example, some systems return junk in the tv_nsec part of
+ * st_birthtime. An example of this is the NetBSD-4.0-RELENG kernel
+ * (at Sat Mar 24 18:46:46 2007) running a NetBSD-3.1-RELEASE
+ * runtime and examining files on an msdos filesytem. So for that
+ * reason we set NS_BUF_LEN to 32, which is simply "long enough" as
+ * opposed to "exactly the right size". Note that the behaviour of
+ * NetBSD appears to be a result of the use of uninitialized data,
+ * as it's not 100% reproducible (more like 25%).
+ */
+ enum {
+ NS_BUF_LEN = 32,
+ DATE_LEN_PERCENT_APLUS=21 /* length of result of %A+ (it's longer than %c)*/
+ };
+ static char buf[128u+10u + MAX(DATE_LEN_PERCENT_APLUS,
+ MAX (LONGEST_HUMAN_READABLE + 2, NS_BUF_LEN+64+200))];
+ char ns_buf[NS_BUF_LEN]; /* -.9999999990 (- sign can happen!)*/
+ int charsprinted, need_ns_suffix;
+ struct tm *tm;
+ char fmt[6];
+
+ /* human_readable() assumes we pass a buffer which is at least as
+ * long as LONGEST_HUMAN_READABLE. We use an assertion here to
+ * ensure that no nasty unsigned overflow happened in our calculation
+ * of the size of buf. Do the assertion here rather than in the
+ * code for %@ so that we find the problem quickly if it exists. If
+ * you want to submit a patch to move this into the if statement, go
+ * ahead, I'll apply it. But include performance timings
+ * demonstrating that the performance difference is actually
+ * measurable.
+ */
+ verify (sizeof (buf) >= LONGEST_HUMAN_READABLE);
+
+ charsprinted = 0;
+ need_ns_suffix = 0;
+
+ /* Format the main part of the time. */
+ if (kind == '+')
+ {
+ strcpy (fmt, "%F+%T");
+ need_ns_suffix = 1;
+ }
+ else
+ {
+ fmt[0] = '%';
+ fmt[1] = kind;
+ fmt[2] = '\0';
+
+ /* %a, %c, and %t are handled in ctime_format() */
+ switch (kind)
+ {
+ case 'S':
+ case 'T':
+ case 'X':
+ case '@':
+ need_ns_suffix = 1;
+ break;
+ default:
+ need_ns_suffix = 0;
+ break;
+ }
+ }
+
+ if (need_ns_suffix)
+ {
+ /* Format the nanoseconds part. Leave a trailing zero to
+ * discourage people from writing scripts which extract the
+ * fractional part of the timestamp by using column offsets.
+ * The reason for discouraging this is that in the future, the
+ * granularity may not be nanoseconds.
+ */
+ charsprinted = snprintf (ns_buf, NS_BUF_LEN, ".%09ld0", (long int)ts.tv_nsec);
+ assert (charsprinted < NS_BUF_LEN);
+ }
+ else
+ {
+ charsprinted = 0;
+ ns_buf[0] = 0;
+ }
+
+ if (kind != '@')
+ {
+ tm = localtime (&ts.tv_sec);
+ if (tm)
+ {
+ char *s = do_time_format (fmt, tm, ns_buf, charsprinted);
+ if (s)
+ return s;
+ }
+ }
+
+ /* If we get to here, either the format was %@, or we have fallen back to it
+ * because strftime failed.
+ */
+ if (1)
+ {
+ uintmax_t w = ts.tv_sec;
+ size_t used, len, remaining;
+
+ /* XXX: note that we are negating an unsigned type which is the
+ * widest possible unsigned type.
+ */
+ char *p = human_readable (ts.tv_sec < 0 ? -w : w, buf + 1,
+ human_ceiling, 1, 1);
+ assert (p > buf);
+ assert (p < (buf + (sizeof buf)));
+ if (ts.tv_sec < 0)
+ *--p = '-'; /* XXX: Ugh, relying on internal details of human_readable(). */
+
+ /* Add the nanoseconds part. Because we cannot enforce a
+ * particlar implementation of human_readable, we cannot assume
+ * any particular value for (p-buf). So we need to be careful
+ * that there is enough space remaining in the buffer.
+ */
+ if (need_ns_suffix)
+ {
+ len = strlen (p);
+ used = (p-buf) + len; /* Offset into buf of current end */
+ assert (sizeof buf > used); /* Ensure we can perform subtraction safely. */
+ remaining = sizeof buf - used - 1u; /* allow space for NUL */
+
+ if (strlen (ns_buf) >= remaining)
+ {
+ error (0, 0,
+ "charsprinted=%ld but remaining=%lu: ns_buf=%s",
+ (long)charsprinted, (unsigned long)remaining, ns_buf);
+ }
+ assert (strlen (ns_buf) < remaining);
+ strcat (p, ns_buf);
+ }
+ return p;
+ }
+}
+
+static const char *weekdays[] =
+ {
+ "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"
+ };
+static const char * months[] =
+ {
+ "Jan", "Feb", "Mar", "Apr", "May", "Jun",
+ "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
+ };
+
+
+static char *
+ctime_format (struct timespec ts)
+{
+ const struct tm * ptm;
+#define TIME_BUF_LEN 1024
+ static char resultbuf[TIME_BUF_LEN];
+ int nout;
+
+ ptm = localtime (&ts.tv_sec);
+ if (ptm)
+ {
+ assert (ptm->tm_wday >= 0);
+ assert (ptm->tm_wday < 7);
+ assert (ptm->tm_mon >= 0);
+ assert (ptm->tm_mon < 12);
+ assert (ptm->tm_hour >= 0);
+ assert (ptm->tm_hour < 24);
+ assert (ptm->tm_min < 60);
+ assert (ptm->tm_sec <= 61); /* allows 2 leap seconds. */
+
+ /* wkday mon mday hh:mm:ss.nnnnnnnnn yyyy */
+ nout = snprintf (resultbuf, TIME_BUF_LEN,
+ "%3s %3s %2d %02d:%02d:%02d.%09ld0 %04d",
+ weekdays[ptm->tm_wday],
+ months[ptm->tm_mon],
+ ptm->tm_mday,
+ ptm->tm_hour,
+ ptm->tm_min,
+ ptm->tm_sec,
+ (long int)ts.tv_nsec,
+ 1900 + ptm->tm_year);
+
+ assert (nout < TIME_BUF_LEN);
+ return resultbuf;
+ }
+ else
+ {
+ /* The time cannot be represented as a struct tm.
+ Output it as an integer. */
+ return format_date (ts, '@');
+ }
+}
+
+static double
+file_sparseness (const struct stat *p)
+{
+ if (0 == p->st_size)
+ {
+ if (0 == ST_NBLOCKS(*p))
+ return 1.0;
+ else
+ return ST_NBLOCKS(*p) < 0 ? -HUGE_VAL : HUGE_VAL;
+ }
+ else
+ {
+ double blklen = ST_NBLOCKSIZE * (double)ST_NBLOCKS(*p);
+ return blklen / p->st_size;
+ }
+}
+
+static void
+checked_fprintf (struct format_val *dest, const char *fmt, ...)
+{
+ int rv;
+ va_list ap;
+
+ va_start (ap, fmt);
+ rv = vfprintf (dest->stream, fmt, ap);
+ if (rv < 0)
+ nonfatal_nontarget_file_error (errno, dest->filename);
+}
+
+static void
+checked_print_quoted (struct format_val *dest,
+ const char *format, const char *s)
+{
+ int rv = print_quoted (dest->stream, dest->quote_opts, dest->dest_is_tty,
+ format, s);
+ if (rv < 0)
+ nonfatal_nontarget_file_error (errno, dest->filename);
+}
+
+
+static void
+checked_fwrite (void *p, size_t siz, size_t nmemb, struct format_val *dest)
+{
+ const size_t items_written = fwrite (p, siz, nmemb, dest->stream);
+ if (items_written < nmemb)
+ nonfatal_nontarget_file_error (errno, dest->filename);
+}
+
+static void
+checked_fflush (struct format_val *dest)
+{
+ if (0 != fflush (dest->stream))
+ {
+ nonfatal_nontarget_file_error (errno, dest->filename);
+ }
+}
+
+static const char*
+mode_to_filetype (mode_t m)
+{
+#define HANDLE_TYPE(t,letter) if (m==t) { return letter; }
+#ifdef S_IFREG
+ HANDLE_TYPE(S_IFREG, "f"); /* regular file */
+#endif
+#ifdef S_IFDIR
+ HANDLE_TYPE(S_IFDIR, "d"); /* directory */
+#endif
+#ifdef S_IFLNK
+ HANDLE_TYPE(S_IFLNK, "l"); /* symbolic link */
+#endif
+#ifdef S_IFSOCK
+ HANDLE_TYPE(S_IFSOCK, "s"); /* Unix domain socket */
+#endif
+#ifdef S_IFBLK
+ HANDLE_TYPE(S_IFBLK, "b"); /* block device */
+#endif
+#ifdef S_IFCHR
+ HANDLE_TYPE(S_IFCHR, "c"); /* character device */
+#endif
+#ifdef S_IFIFO
+ HANDLE_TYPE(S_IFIFO, "p"); /* FIFO */
+#endif
+#ifdef S_IFDOOR
+ HANDLE_TYPE(S_IFDOOR, "D"); /* Door (e.g. on Solaris) */
+#endif
+ return "U"; /* Unknown */
+}
+
+
+
+static void
+do_fprintf (struct format_val *dest,
+ struct segment *segment,
+ const char *pathname,
+ const struct stat *stat_buf)
+{
+ char hbuf[LONGEST_HUMAN_READABLE + 1];
+ const char *cp;
+
+ switch (segment->segkind)
+ {
+ case KIND_PLAIN: /* Plain text string (no % conversion). */
+ /* trusted */
+ checked_fwrite(segment->text, 1, segment->text_len, dest);
+ break;
+
+ case KIND_STOP: /* Terminate argument and flush output. */
+ /* trusted */
+ checked_fwrite (segment->text, 1, segment->text_len, dest);
+ checked_fflush (dest);
+ break;
+
+ case KIND_FORMAT:
+ switch (segment->format_char[0])
+ {
+ case 'a': /* atime in `ctime' format. */
+ /* UNTRUSTED, probably unexploitable */
+ checked_fprintf (dest, segment->text, ctime_format (get_stat_atime (stat_buf)));
+ break;
+ case 'b': /* size in 512-byte blocks */
+ /* UNTRUSTED, probably unexploitable */
+ checked_fprintf (dest, segment->text,
+ human_readable ((uintmax_t) ST_NBLOCKS (*stat_buf),
+ hbuf, human_ceiling,
+ ST_NBLOCKSIZE, 512));
+ break;
+ case 'c': /* ctime in `ctime' format */
+ /* UNTRUSTED, probably unexploitable */
+ checked_fprintf (dest, segment->text, ctime_format (get_stat_ctime (stat_buf)));
+ break;
+ case 'd': /* depth in search tree */
+ /* UNTRUSTED, probably unexploitable */
+ checked_fprintf (dest, segment->text, state.curdepth);
+ break;
+ case 'D': /* Device on which file exists (stat.st_dev) */
+ /* trusted */
+ checked_fprintf (dest, segment->text,
+ human_readable ((uintmax_t) stat_buf->st_dev, hbuf,
+ human_ceiling, 1, 1));
+ break;
+ case 'f': /* base name of path */
+ /* sanitised */
+ {
+ char *base = base_name (pathname);
+ checked_print_quoted (dest, segment->text, base);
+ free (base);
+ }
+ break;
+ case 'F': /* file system type */
+ /* trusted */
+ checked_print_quoted (dest, segment->text, filesystem_type (stat_buf, pathname));
+ break;
+ case 'g': /* group name */
+ /* trusted */
+ /* (well, the actual group is selected by the user but
+ * its name was selected by the system administrator)
+ */
+ {
+ struct group *g;
+
+ g = getgrgid (stat_buf->st_gid);
+ if (g)
+ {
+ segment->text[segment->text_len] = 's';
+ checked_fprintf (dest, segment->text, g->gr_name);
+ break;
+ }
+ else
+ {
+ /* Do nothing. */
+ /*FALLTHROUGH*/
+ }
+ }
+ /*FALLTHROUGH*/ /*...sometimes, so 'G' case.*/
+
+ case 'G': /* GID number */
+ /* UNTRUSTED, probably unexploitable */
+ checked_fprintf (dest, segment->text,
+ human_readable ((uintmax_t) stat_buf->st_gid, hbuf,
+ human_ceiling, 1, 1));
+ break;
+ case 'h': /* leading directories part of path */
+ /* sanitised */
+ {
+ cp = strrchr (pathname, '/');
+ if (cp == NULL) /* No leading directories. */
+ {
+ /* If there is no slash in the pathname, we still
+ * print the string because it contains characters
+ * other than just '%s'. The %h expands to ".".
+ */
+ checked_print_quoted (dest, segment->text, ".");
+ }
+ else
+ {
+ char *s = strdup (pathname);
+ s[cp - pathname] = 0;
+ checked_print_quoted (dest, segment->text, s);
+ free (s);
+ }
+ }
+ break;
+
+ case 'H': /* ARGV element file was found under */
+ /* trusted */
+ {
+ char *s = xmalloc (state.starting_path_length+1);
+ memcpy (s, pathname, state.starting_path_length);
+ s[state.starting_path_length] = 0;
+ checked_fprintf (dest, segment->text, s);
+ free (s);
+ }
+ break;
+
+ case 'i': /* inode number */
+ /* UNTRUSTED, but not exploitable I think */
+ /* POSIX does not guarantee that ino_t is unsigned or even
+ * integral (except as an XSI extension), but we'll work on
+ * fixing that if we ever get a report of a system where
+ * ino_t is indeed a signed integral type or a non-integral
+ * arithmetic type. */
+ checked_fprintf (dest, segment->text,
+ human_readable ((uintmax_t) stat_buf->st_ino, hbuf,
+ human_ceiling,
+ 1, 1));
+ break;
+ case 'k': /* size in 1K blocks */
+ /* UNTRUSTED, but not exploitable I think */
+ checked_fprintf (dest, segment->text,
+ human_readable ((uintmax_t) ST_NBLOCKS (*stat_buf),
+ hbuf, human_ceiling,
+ ST_NBLOCKSIZE, 1024));
+ break;
+ case 'l': /* object of symlink */
+ /* sanitised */
+#ifdef S_ISLNK
+ {
+ char *linkname = 0;
+
+ if (S_ISLNK (stat_buf->st_mode))
+ {
+ linkname = areadlinkat (state.cwd_dir_fd, state.rel_pathname);
+ if (linkname == NULL)
+ {
+ nonfatal_target_file_error (errno, pathname);
+ state.exit_status = 1;
+ }
+ }
+ if (linkname)
+ {
+ checked_print_quoted (dest, segment->text, linkname);
+ }
+ else
+ {
+ /* We still need to honour the field width etc., so this is
+ * not a no-op.
+ */
+ checked_print_quoted (dest, segment->text, "");
+ }
+ free (linkname);
+ }
+#endif /* S_ISLNK */
+ break;
+
+ case 'M': /* mode as 10 chars (eg., "-rwxr-x--x" */
+ /* UNTRUSTED, probably unexploitable */
+ {
+ char modestring[16] ;
+ filemodestring (stat_buf, modestring);
+ modestring[10] = '\0';
+ checked_fprintf (dest, segment->text, modestring);
+ }
+ break;
+
+ case 'm': /* mode as octal number (perms only) */
+ /* UNTRUSTED, probably unexploitable */
+ {
+ /* Output the mode portably using the traditional numbers,
+ even if the host unwisely uses some other numbering
+ scheme. But help the compiler in the common case where
+ the host uses the traditional numbering scheme. */
+ mode_t m = stat_buf->st_mode;
+ bool traditional_numbering_scheme =
+ (S_ISUID == 04000 && S_ISGID == 02000 && S_ISVTX == 01000
+ && S_IRUSR == 00400 && S_IWUSR == 00200 && S_IXUSR == 00100
+ && S_IRGRP == 00040 && S_IWGRP == 00020 && S_IXGRP == 00010
+ && S_IROTH == 00004 && S_IWOTH == 00002 && S_IXOTH == 00001);
+ checked_fprintf (dest, segment->text,
+ (traditional_numbering_scheme
+ ? m & MODE_ALL
+ : ((m & S_ISUID ? 04000 : 0)
+ | (m & S_ISGID ? 02000 : 0)
+ | (m & S_ISVTX ? 01000 : 0)
+ | (m & S_IRUSR ? 00400 : 0)
+ | (m & S_IWUSR ? 00200 : 0)
+ | (m & S_IXUSR ? 00100 : 0)
+ | (m & S_IRGRP ? 00040 : 0)
+ | (m & S_IWGRP ? 00020 : 0)
+ | (m & S_IXGRP ? 00010 : 0)
+ | (m & S_IROTH ? 00004 : 0)
+ | (m & S_IWOTH ? 00002 : 0)
+ | (m & S_IXOTH ? 00001 : 0))));
+ }
+ break;
+
+ case 'n': /* number of links */
+ /* UNTRUSTED, probably unexploitable */
+ checked_fprintf (dest, segment->text,
+ human_readable ((uintmax_t) stat_buf->st_nlink,
+ hbuf,
+ human_ceiling,
+ 1, 1));
+ break;
+
+ case 'p': /* pathname */
+ /* sanitised */
+ checked_print_quoted (dest, segment->text, pathname);
+ break;
+
+ case 'P': /* pathname with ARGV element stripped */
+ /* sanitised */
+ if (state.curdepth > 0)
+ {
+ cp = pathname + state.starting_path_length;
+ if (*cp == '/')
+ /* Move past the slash between the ARGV element
+ and the rest of the pathname. But if the ARGV element
+ ends in a slash, we didn't add another, so we've
+ already skipped past it. */
+ cp++;
+ }
+ else
+ {
+ cp = "";
+ }
+ checked_print_quoted (dest, segment->text, cp);
+ break;
+
+ case 's': /* size in bytes */
+ /* UNTRUSTED, probably unexploitable */
+ checked_fprintf (dest, segment->text,
+ human_readable ((uintmax_t) stat_buf->st_size,
+ hbuf, human_ceiling, 1, 1));
+ break;
+
+ case 'S': /* sparseness */
+ /* UNTRUSTED, probably unexploitable */
+ checked_fprintf (dest, segment->text, file_sparseness (stat_buf));
+ break;
+
+ case 't': /* mtime in `ctime' format */
+ /* UNTRUSTED, probably unexploitable */
+ checked_fprintf (dest, segment->text,
+ ctime_format (get_stat_mtime (stat_buf)));
+ break;
+
+ case 'u': /* user name */
+ /* trusted */
+ /* (well, the actual user is selected by the user on systems
+ * where chown is not restricted, but the user name was
+ * selected by the system administrator)
+ */
+ {
+ struct passwd *p;
+
+ p = getpwuid (stat_buf->st_uid);
+ if (p)
+ {
+ segment->text[segment->text_len] = 's';
+ checked_fprintf (dest, segment->text, p->pw_name);
+ break;
+ }
+ /* else fallthru */
+ }
+ /* FALLTHROUGH*/ /* .. to case U */
+
+ case 'U': /* UID number */
+ /* UNTRUSTED, probably unexploitable */
+ checked_fprintf (dest, segment->text,
+ human_readable ((uintmax_t) stat_buf->st_uid, hbuf,
+ human_ceiling, 1, 1));
+ break;
+
+ /* %Y: type of file system entry like `ls -l`:
+ * (d,-,l,s,p,b,c,n) n=nonexistent (symlink)
+ */
+ case 'Y': /* in case of symlink */
+ /* trusted */
+ {
+#ifdef S_ISLNK
+ if (S_ISLNK (stat_buf->st_mode))
+ {
+ struct stat sbuf;
+ /* If we would normally follow links, do not do so.
+ * If we would normally not follow links, do so.
+ */
+ if ((following_links () ? optionp_stat : optionl_stat)
+ (state.rel_pathname, &sbuf) != 0)
+ {
+ if ( errno == ENOENT )
+ {
+ checked_fprintf (dest, segment->text, "N");
+ break;
+ }
+ else if ( errno == ELOOP )
+ {
+ checked_fprintf (dest, segment->text, "L");
+ break;
+ }
+ else
+ {
+ checked_fprintf (dest, segment->text, "?");
+ error (0, errno, "%s",
+ safely_quote_err_filename (0, pathname));
+ /* exit_status = 1;
+ return ; */
+ break;
+ }
+ }
+ checked_fprintf (dest, segment->text,
+ mode_to_filetype (sbuf.st_mode & S_IFMT));
+ }
+#endif /* S_ISLNK */
+ else
+ {
+ checked_fprintf (dest, segment->text,
+ mode_to_filetype (stat_buf->st_mode & S_IFMT));
+ }
+ }
+ break;
+
+ case 'y':
+ /* trusted */
+ {
+ checked_fprintf (dest, segment->text,
+ mode_to_filetype (stat_buf->st_mode & S_IFMT));
+ }
+ break;
+
+ case 'Z': /* SELinux security context */
+ {
+ security_context_t scontext;
+ int rv = (*options.x_getfilecon) (state.cwd_dir_fd, state.rel_pathname,
+ &scontext);
+ if (rv < 0)
+ {
+ /* If getfilecon fails, there will in the general case
+ still be some text to print. We just make %Z expand
+ to an empty string. */
+ checked_fprintf (dest, segment->text, "");
+
+ error (0, errno, _("getfilecon failed: %s"),
+ safely_quote_err_filename (0, pathname));
+ state.exit_status = 1;
+ }
+ else
+ {
+ checked_fprintf (dest, segment->text, scontext);
+ freecon (scontext);
+ }
+ }
+ break;
+
+ case 0:
+ case '%':
+ checked_fprintf (dest, segment->text);
+ break;
+ }
+ /* end of KIND_FORMAT case */
+ break;
+ }
+}
+
+bool
+pred_fprintf (const char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
+{
+ struct format_val *dest = &pred_ptr->args.printf_vec;
+ struct segment *segment;
+
+ for (segment = dest->segment; segment; segment = segment->next)
+ {
+ if ( (KIND_FORMAT == segment->segkind) && segment->format_char[1]) /* Component of date. */
+ {
+ struct timespec ts;
+ int valid = 0;
+
+ switch (segment->format_char[0])
+ {
+ case 'A':
+ ts = get_stat_atime (stat_buf);
+ valid = 1;
+ break;
+ case 'B':
+ ts = get_stat_birthtime (stat_buf);
+ if ('@' == segment->format_char[1])
+ valid = 1;
+ else
+ valid = (ts.tv_nsec >= 0);
+ break;
+ case 'C':
+ ts = get_stat_ctime (stat_buf);
+ valid = 1;
+ break;
+ case 'T':
+ ts = get_stat_mtime (stat_buf);
+ valid = 1;
+ break;
+ default:
+ assert (0);
+ abort ();
+ }
+ /* We trust the output of format_date not to contain
+ * nasty characters, though the value of the date
+ * is itself untrusted data.
+ */
+ if (valid)
+ {
+ /* trusted */
+ checked_fprintf (dest, segment->text,
+ format_date (ts, segment->format_char[1]));
+ }
+ else
+ {
+ /* The specified timestamp is not available, output
+ * nothing for the timestamp, but use the rest (so that
+ * for example find foo -printf '[%Bs] %p\n' can print
+ * "[] foo").
+ */
+ /* trusted */
+ checked_fprintf (dest, segment->text, "");
+ }
+ }
+ else
+ {
+ /* Print a segment which is not a date. */
+ do_fprintf (dest, segment, pathname, stat_buf);
+ }
+ }
+ return true;
+}
diff --git a/find/print.h b/find/print.h
new file mode 100644
index 0000000..2168859
--- /dev/null
+++ b/find/print.h
@@ -0,0 +1,32 @@
+/* print.h -- declarations for symbols in print.c.
+ Copyright (C) 2011-2015 Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+#include "defs.h"
+
+struct format_val;
+struct parser_table;
+struct predicate;
+struct segment;
+
+struct segment **make_segment (struct segment **segment,
+ char *format, int len,
+ int kind, char format_char,
+ char aux_format_char,
+ struct predicate *pred);
+bool
+insert_fprintf (struct format_val *vec,
+ const struct parser_table *entry,
+ char *format);
diff --git a/find/sharefile.c b/find/sharefile.c
new file mode 100644
index 0000000..8120dff
--- /dev/null
+++ b/find/sharefile.c
@@ -0,0 +1,203 @@
+/* sharefile.c -- open files just once.
+ Copyright (C) 2008, 2009, 2010, 2011 Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/* config.h always comes first. */
+#include <config.h>
+
+/* system headers. */
+#include <assert.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+
+/* gnulib headers. */
+#include "cloexec.h"
+#include "hash.h"
+#include "stdio-safer.h"
+
+/* find headers. */
+#include "sharefile.h"
+#include "defs.h"
+
+
+enum
+ {
+ DefaultHashTableSize = 11
+ };
+
+struct sharefile
+{
+ char *mode;
+ Hash_table *table;
+};
+
+
+/*
+ * We cannot use the name to determine that two strings represent the
+ * same file, since that test would be fooled by symbolic links.
+ * Instead we use the device and inode number.
+ *
+ * However, we remember the name of each file that we opened. This
+ * allows us to issue a fatal error message when (flushing and)
+ * closing a file fails.
+ */
+struct SharefileEntry
+{
+ dev_t device;
+ ino_t inode;
+ char *name; /* not the only name for this file; error messages only */
+ FILE *fp;
+};
+
+
+static bool
+entry_comparator (const void *av, const void *bv)
+{
+ const struct SharefileEntry *a=av, *b=bv;
+ return (a->inode == b->inode) && (a->device == b->device);
+}
+
+static void
+entry_free (void *pv)
+{
+ struct SharefileEntry *p = pv;
+ if (p->fp)
+ {
+ if (0 != fclose (p->fp))
+ fatal_nontarget_file_error (errno, p->name);
+ }
+ free (p->name);
+ free (p);
+}
+
+static size_t
+entry_hashfunc (const void *pv, size_t buckets)
+{
+ const struct SharefileEntry *p = pv;
+ return (p->device ^ p->inode) % buckets;
+}
+
+
+
+sharefile_handle
+sharefile_init (const char *mode)
+{
+ struct Hash_tuning;
+
+ struct sharefile *p = malloc (sizeof (struct sharefile));
+ if (p)
+ {
+ p->mode = strdup (mode);
+ if (p->mode)
+ {
+ p->table = hash_initialize (DefaultHashTableSize, NULL,
+ entry_hashfunc,
+ entry_comparator,
+ entry_free);
+ if (p->table)
+ {
+ return p;
+ }
+ else
+ {
+ free (p->mode);
+ free (p);
+ }
+ }
+ else
+ {
+ free (p);
+ }
+ }
+ return NULL;
+}
+
+void
+sharefile_destroy (sharefile_handle pv)
+{
+ struct sharefile *p = pv;
+ free (p->mode);
+ hash_free (p->table);
+}
+
+
+FILE *
+sharefile_fopen (sharefile_handle h, const char *filename)
+{
+ struct sharefile *p = h;
+ struct SharefileEntry *new_entry;
+
+ new_entry = malloc (sizeof (struct SharefileEntry));
+ if (!new_entry)
+ return NULL;
+
+ new_entry->name = strdup (filename);
+ if (NULL == new_entry->name)
+ {
+ free (new_entry);
+ return NULL;
+ }
+
+ if (NULL == (new_entry->fp = fopen_safer (filename, p->mode)))
+ {
+ free (new_entry);
+ return NULL;
+ }
+ else
+ {
+ struct stat st;
+ const int fd = fileno (new_entry->fp);
+ assert (fd >= 0);
+
+ set_cloexec_flag (fd, true);
+ if (fstat (fd, &st) < 0)
+ {
+ entry_free (new_entry);
+ return NULL;
+ }
+ else
+ {
+ void *existing;
+
+ new_entry->device = st.st_dev;
+ new_entry->inode = st.st_ino;
+
+ existing = hash_lookup (p->table, new_entry);
+ if (existing) /* We have previously opened that file. */
+ {
+ entry_free (new_entry); /* don't need new_entry. */
+ return ((const struct SharefileEntry*)existing)->fp;
+ }
+ else /* We didn't open it already */
+ {
+ if (hash_insert (p->table, new_entry))
+ {
+ return new_entry->fp;
+ }
+ else /* failed to insert in hashtable. */
+ {
+ const int save_errno = errno;
+ entry_free (new_entry);
+ errno = save_errno;
+ return NULL;
+ }
+ }
+ }
+ }
+}
diff --git a/find/sharefile.h b/find/sharefile.h
new file mode 100644
index 0000000..786cca0
--- /dev/null
+++ b/find/sharefile.h
@@ -0,0 +1,31 @@
+/* sharefile.h -- open files just once.
+ Copyright (C) 2008, 2009, 2010, 2011 Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+
+#ifndef INC_SHAREFILE_H
+#define INC_SHAREFILE_H 1
+
+#include <stdlib.h>
+#include <stdio.h>
+
+typedef void * sharefile_handle;
+
+sharefile_handle sharefile_init(const char *mode);
+FILE *sharefile_fopen(sharefile_handle, const char *filename);
+void sharefile_destroy(sharefile_handle);
+
+#endif
diff --git a/find/testsuite/Makefile.am b/find/testsuite/Makefile.am
new file mode 100644
index 0000000..c1369c3
--- /dev/null
+++ b/find/testsuite/Makefile.am
@@ -0,0 +1,283 @@
+# Copyright (C) 2001,2003-2015 Free Software Foundation, Inc.
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+# The 2001 copyright line above was added in 2015 based on James
+# Youngman's best estimate of the original publication date of this
+# file (it appeared in findutils release 4.1.7 but may have appeared
+# in earlier releases which I don't have copies of).
+
+AUTOMAKE_OPTIONS = dejagnu parallel-tests
+FIND = ../find
+FINDFLAGS =
+
+DEJATOOL = find
+
+EXTRA_DIST_XO = \
+find.gnu/access.xo \
+find.gnu/comma.xo \
+find.gnu/delete.xo \
+find.gnu/deletedir.xo \
+find.gnu/deletefile.xo \
+find.gnu/depth.xo \
+find.gnu/depth-d.xo \
+find.gnu/empty.xo \
+find.gnu/execdir-hier.xo \
+find.gnu/execdir-multiple.xo \
+find.gnu/execdir-one.xo \
+find.gnu/execdir-root-only.xo \
+find.gnu/exec-many-rtn-failure.xo \
+find.gnu/exec-many-rtn-success.xo \
+find.gnu/exec-one-rtn-fail.xo \
+find.gnu/exec-one-rtn-success.xo \
+find.gnu/false.xo \
+find.gnu/follow-arg-parent-symlink.xo \
+find.gnu/follow-basic.xo \
+find.gnu/fprint0_stdout.xo \
+find.gnu/gnuand.xo \
+find.gnu/gnunot.xo \
+find.gnu/gnu-or.xo \
+find.gnu/ilname.xo \
+find.gnu/iname.xo \
+find.gnu/inum.xo \
+find.gnu/ipath.xo \
+find.gnu/iregex1.xo \
+find.gnu/iwholename.xo \
+find.gnu/lname.xo \
+find.gnu/mindepth-arg.xo \
+find.gnu/name-opt.xo \
+find.gnu/name-period.xo \
+find.gnu/name-slash.xo \
+find.gnu/no-fdleak-test.xo \
+find.gnu/path.xo \
+find.gnu/print_stdout.xo \
+find.gnu/perm.xo \
+find.gnu/perm000.xo \
+find.gnu/perm-slash.xo \
+find.gnu/posix-dflt.xo \
+find.gnu/posix-h.xo \
+find.gnu/posix-l.xo \
+find.gnu/printfHdfl.xo \
+find.gnu/printf-nonlocal-symlink.xo \
+find.gnu/printf-slash.xo \
+find.gnu/printf-symlink.xo \
+find.gnu/printf-h.xo \
+find.gnu/printf.xo \
+find.gnu/print0.xo \
+find.gnu/prune-default-print.xo \
+find.gnu/regex1.xo \
+find.gnu/regex2.xo \
+find.gnu/samefile-copy.xo \
+find.gnu/samefile-link.xo \
+find.gnu/samefile-p-brokenlink.xo \
+find.gnu/samefile-same.xo \
+find.gnu/samefile-symlink.xo \
+find.gnu/sv-bug-17782.xo \
+find.gnu/sv-bug-18222.xo \
+find.gnu/sv-bug-27563-execdir.xo \
+find.gnu/true.xo \
+find.gnu/wholename.xo \
+find.gnu/xtype-symlink.xo \
+find.gnu/quit.xo \
+find.gnu/xtype.xo \
+find.posix/and.xo \
+find.posix/depth1.xo \
+find.posix/dotdotfiles.xo \
+find.posix/exec-nogaps.xo \
+find.posix/exec-one.xo \
+find.posix/files-not-expressions1.xo \
+find.posix/files-not-expressions2.xo \
+find.posix/files-not-expressions3.xo \
+find.posix/grouping.xo \
+find.posix/links.xo \
+find.posix/sv-bug-11175.xo \
+find.posix/sv-bug-12181.xo \
+find.posix/sv-bug-25359.xo \
+find.posix/sv-bug-27563-exec.xo \
+find.posix/mtime0.xo \
+find.posix/sizes.xo \
+find.posix/name.xo \
+find.posix/nameslash.xo \
+find.posix/parent.xo \
+find.posix/perm-X.xo \
+find.posix/perm-vanilla.xo \
+find.posix/posixnot.xo \
+find.posix/prune.xo \
+find.posix/prune-result.xo \
+find.posix/prune-stat.xo \
+find.posix/sizetype.xo \
+find.posix/sv-bug-15235.xo \
+find.posix/sv-bug-19613.xo \
+find.posix/typesize.xo
+
+
+EXTRA_DIST_EXP = \
+config/unix.exp \
+find.gnu/access.exp \
+find.gnu/comma.exp \
+find.gnu/delete.exp \
+find.gnu/deletedir.exp \
+find.gnu/deletefile.exp \
+find.gnu/depth.exp \
+find.gnu/depth-d.exp \
+find.gnu/empty.exp \
+find.gnu/execdir-hier.exp \
+find.gnu/execdir-in-unreadable.exp \
+find.gnu/execdir-multiple.exp \
+find.gnu/execdir-one.exp \
+find.gnu/execdir-pwd.exp \
+find.gnu/execdir-pwd1.exp \
+find.gnu/execdir-root-only.exp \
+find.gnu/exec-many-rtn-failure.exp \
+find.gnu/exec-many-rtn-success.exp \
+find.gnu/exec-one-rtn-fail.exp \
+find.gnu/exec-one-rtn-success.exp \
+find.gnu/false.exp \
+find.gnu/follow-arg-parent-symlink.exp \
+find.gnu/follow-basic.exp \
+find.gnu/fprint0_stdout.exp \
+find.gnu/fprintf-samefile.exp \
+find.gnu/fprint-unwritable.exp \
+find.gnu/gnuand.exp \
+find.gnu/gnunot.exp \
+find.gnu/gnu-or.exp \
+find.gnu/ilname.exp \
+find.gnu/iname.exp \
+find.gnu/inum.exp \
+find.gnu/ipath.exp \
+find.gnu/iregex1.exp \
+find.gnu/iwholename.exp \
+find.gnu/lname.exp \
+find.gnu/mindepth-arg.exp \
+find.gnu/mindepth-badarg.exp \
+find.gnu/name-opt.exp \
+find.gnu/name-period.exp \
+find.gnu/name-slash.exp \
+find.gnu/no-fdleak-test.exp \
+find.posix/parent.exp \
+find.gnu/path.exp \
+find.gnu/print_stdout.exp \
+find.gnu/print0.exp \
+find.gnu/perm.exp \
+find.gnu/perm000.exp \
+find.gnu/perm-slash.exp \
+find.gnu/posix-dflt.exp \
+find.gnu/posix-h.exp \
+find.gnu/posix-l.exp \
+find.gnu/posix-perminvalid.exp \
+find.gnu/printfHdfl.exp \
+find.gnu/printf.exp \
+find.gnu/printf-nonlocal-symlink.exp \
+find.gnu/printf-slash.exp \
+find.gnu/printf-symlink.exp \
+find.gnu/printf-h.exp \
+find.gnu/printf-reserved.exp \
+find.gnu/prune-default-print.exp \
+find.gnu/regex1.exp \
+find.gnu/regex2.exp \
+find.gnu/samefile-copy.exp \
+find.gnu/samefile-link.exp \
+find.gnu/samefile-missing.exp \
+find.gnu/samefile-p-brokenlink.exp \
+find.gnu/samefile-same.exp \
+find.gnu/samefile-symlink.exp \
+find.gnu/true.exp \
+find.gnu/wholename.exp \
+find.gnu/xtype-symlink.exp \
+find.gnu/sv-bug-12230.exp \
+find.gnu/sv-bug-17477.exp \
+find.gnu/sv-bug-17490.exp \
+find.gnu/sv-bug-17782.exp \
+find.gnu/sv-bug-18222.exp \
+find.gnu/sv-bug-24169.exp \
+find.gnu/sv-bug-27563-execdir.exp \
+find.gnu/quit.exp \
+find.gnu/used-invarg.exp \
+find.gnu/used-missing.exp \
+find.gnu/user-invalid.exp \
+find.gnu/xtype.exp \
+find.posix/and.exp \
+find.posix/bracket-depth.exp \
+find.posix/depth1.exp \
+find.posix/dotdotfiles.exp \
+find.posix/empty-parens.exp \
+find.posix/exec-nogaps.exp \
+find.posix/exec-one.exp \
+find.posix/files-not-expressions1.exp \
+find.posix/files-not-expressions2.exp \
+find.posix/files-not-expressions3.exp \
+find.posix/grouping.exp \
+find.posix/group-empty.exp \
+find.posix/group-missing.exp \
+find.posix/links.exp \
+find.posix/mtime0.exp \
+find.posix/sv-bug-11175.exp \
+find.posix/sv-bug-12181.exp \
+find.posix/sv-bug-25359.exp \
+find.posix/sv-bug-27563-exec.exp \
+find.posix/sv-bug-30777.exp \
+find.posix/sizes.exp \
+find.posix/name.exp \
+find.posix/nameslash.exp \
+find.posix/name-missing.exp \
+find.posix/perm-X.exp \
+find.posix/perm-vanilla.exp \
+find.posix/posixnot.exp \
+find.posix/prune.exp \
+find.posix/prune-result.exp \
+find.posix/prune-stat.exp \
+find.posix/size-invalid.exp \
+find.posix/size-missing.exp \
+find.posix/sizetype.exp \
+find.posix/typearg.exp \
+find.posix/sv-bug-15235.exp \
+find.posix/sv-bug-19605.exp \
+find.posix/sv-bug-19613.exp \
+find.posix/sv-bug-19617.exp \
+find.posix/typesize.exp \
+find.posix/user-empty.exp \
+find.posix/user-missing.exp
+
+EXTRA_DIST_GOLDEN = \
+ test_escapechars.golden
+
+test_shell_progs = \
+sv-bug-32043.sh \
+test_escapechars.sh \
+test_escape_c.sh \
+test_inode.sh \
+sv-34079.sh \
+sv-34976-execdir-fd-leak.sh
+
+EXTRA_DIST = $(EXTRA_DIST_EXP) $(EXTRA_DIST_XO) $(EXTRA_DIST_GOLDEN) \
+ $(test_shell_progs) binary_locations.sh checklists.py
+
+CLEANFILES = *.log *.sum site.exp site.bak configured-testfiles.txt
+
+#DIST_SUBDIRS = config
+
+
+TESTS = $(test_shell_progs)
+TEST_EXTENSIONS = .sh .py
+
+check-local: checklists
+
+configured-testfiles.txt: Makefile
+ @echo Generating $@
+ @( cd $(srcdir) && ls $(EXTRA_DIST_XO) && ls $(EXTRA_DIST_EXP) ) >| $@
+
+.PHONY: checklists
+
+checklists: configured-testfiles.txt Makefile
+ $(PYTHON) $(srcdir)/checklists.py configured-testfiles.txt $(srcdir) config find.gnu find.posix
diff --git a/find/testsuite/Makefile.in b/find/testsuite/Makefile.in
new file mode 100644
index 0000000..1b4ab64
--- /dev/null
+++ b/find/testsuite/Makefile.in
@@ -0,0 +1,2433 @@
+# Makefile.in generated by automake 1.14.1 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2013 Free Software Foundation, Inc.
+
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+# Copyright (C) 2001,2003-2015 Free Software Foundation, Inc.
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+# The 2001 copyright line above was added in 2015 based on James
+# Youngman's best estimate of the original publication date of this
+# file (it appeared in findutils release 4.1.7 but may have appeared
+# in earlier releases which I don't have copies of).
+VPATH = @srcdir@
+am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
+am__make_running_with_option = \
+ case $${target_option-} in \
+ ?) ;; \
+ *) echo "am__make_running_with_option: internal error: invalid" \
+ "target option '$${target_option-}' specified" >&2; \
+ exit 1;; \
+ esac; \
+ has_opt=no; \
+ sane_makeflags=$$MAKEFLAGS; \
+ if $(am__is_gnu_make); then \
+ sane_makeflags=$$MFLAGS; \
+ else \
+ case $$MAKEFLAGS in \
+ *\\[\ \ ]*) \
+ bs=\\; \
+ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \
+ esac; \
+ fi; \
+ skip_next=no; \
+ strip_trailopt () \
+ { \
+ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+ }; \
+ for flg in $$sane_makeflags; do \
+ test $$skip_next = yes && { skip_next=no; continue; }; \
+ case $$flg in \
+ *=*|--*) continue;; \
+ -*I) strip_trailopt 'I'; skip_next=yes;; \
+ -*I?*) strip_trailopt 'I';; \
+ -*O) strip_trailopt 'O'; skip_next=yes;; \
+ -*O?*) strip_trailopt 'O';; \
+ -*l) strip_trailopt 'l'; skip_next=yes;; \
+ -*l?*) strip_trailopt 'l';; \
+ -[dEDm]) skip_next=yes;; \
+ -[JT]) skip_next=yes;; \
+ esac; \
+ case $$flg in \
+ *$$target_option*) has_opt=yes; break;; \
+ esac; \
+ done; \
+ test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+subdir = find/testsuite
+DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
+ $(top_srcdir)/build-aux/mkinstalldirs \
+ $(top_srcdir)/build-aux/test-driver
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/findlib.m4 \
+ $(top_srcdir)/m4/mkinstalldirs.m4 $(top_srcdir)/m4/noreturn.m4 \
+ $(top_srcdir)/m4/nullsort.m4 $(top_srcdir)/m4/withfts.m4 \
+ $(top_srcdir)/gl/m4/00gnulib.m4 \
+ $(top_srcdir)/gl/m4/absolute-header.m4 \
+ $(top_srcdir)/gl/m4/alloca.m4 \
+ $(top_srcdir)/gl/m4/arpa_inet_h.m4 \
+ $(top_srcdir)/gl/m4/assert.m4 $(top_srcdir)/gl/m4/bison.m4 \
+ $(top_srcdir)/gl/m4/btowc.m4 $(top_srcdir)/gl/m4/byteswap.m4 \
+ $(top_srcdir)/gl/m4/canonicalize.m4 \
+ $(top_srcdir)/gl/m4/chdir-long.m4 \
+ $(top_srcdir)/gl/m4/check-math-lib.m4 \
+ $(top_srcdir)/gl/m4/clock_time.m4 \
+ $(top_srcdir)/gl/m4/close-stream.m4 \
+ $(top_srcdir)/gl/m4/close.m4 $(top_srcdir)/gl/m4/closedir.m4 \
+ $(top_srcdir)/gl/m4/closein.m4 $(top_srcdir)/gl/m4/closeout.m4 \
+ $(top_srcdir)/gl/m4/codeset.m4 \
+ $(top_srcdir)/gl/m4/configmake.m4 $(top_srcdir)/gl/m4/ctype.m4 \
+ $(top_srcdir)/gl/m4/cycle-check.m4 \
+ $(top_srcdir)/gl/m4/d-ino.m4 $(top_srcdir)/gl/m4/d-type.m4 \
+ $(top_srcdir)/gl/m4/dirent-safer.m4 \
+ $(top_srcdir)/gl/m4/dirent_h.m4 $(top_srcdir)/gl/m4/dirfd.m4 \
+ $(top_srcdir)/gl/m4/dirname.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/euidaccess.m4 \
+ $(top_srcdir)/gl/m4/exponentd.m4 \
+ $(top_srcdir)/gl/m4/exponentf.m4 \
+ $(top_srcdir)/gl/m4/exponentl.m4 \
+ $(top_srcdir)/gl/m4/extensions.m4 \
+ $(top_srcdir)/gl/m4/extern-inline.m4 \
+ $(top_srcdir)/gl/m4/faccessat.m4 $(top_srcdir)/gl/m4/fchdir.m4 \
+ $(top_srcdir)/gl/m4/fcntl-o.m4 \
+ $(top_srcdir)/gl/m4/fcntl-safer.m4 \
+ $(top_srcdir)/gl/m4/fcntl.m4 $(top_srcdir)/gl/m4/fcntl_h.m4 \
+ $(top_srcdir)/gl/m4/fdopen.m4 $(top_srcdir)/gl/m4/fdopendir.m4 \
+ $(top_srcdir)/gl/m4/fflush.m4 \
+ $(top_srcdir)/gl/m4/fileblocks.m4 \
+ $(top_srcdir)/gl/m4/filemode.m4 \
+ $(top_srcdir)/gl/m4/filenamecat.m4 \
+ $(top_srcdir)/gl/m4/flexmember.m4 \
+ $(top_srcdir)/gl/m4/float_h.m4 $(top_srcdir)/gl/m4/fnmatch.m4 \
+ $(top_srcdir)/gl/m4/fopen.m4 $(top_srcdir)/gl/m4/fpending.m4 \
+ $(top_srcdir)/gl/m4/fpieee.m4 $(top_srcdir)/gl/m4/fpurge.m4 \
+ $(top_srcdir)/gl/m4/freadahead.m4 \
+ $(top_srcdir)/gl/m4/freading.m4 $(top_srcdir)/gl/m4/fseek.m4 \
+ $(top_srcdir)/gl/m4/fseeko.m4 $(top_srcdir)/gl/m4/fstat.m4 \
+ $(top_srcdir)/gl/m4/fstatat.m4 \
+ $(top_srcdir)/gl/m4/fstypename.m4 $(top_srcdir)/gl/m4/ftell.m4 \
+ $(top_srcdir)/gl/m4/ftello.m4 $(top_srcdir)/gl/m4/ftruncate.m4 \
+ $(top_srcdir)/gl/m4/fts.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/getgroups.m4 \
+ $(top_srcdir)/gl/m4/gethostname.m4 \
+ $(top_srcdir)/gl/m4/getline.m4 $(top_srcdir)/gl/m4/getopt.m4 \
+ $(top_srcdir)/gl/m4/getpagesize.m4 \
+ $(top_srcdir)/gl/m4/gettext.m4 $(top_srcdir)/gl/m4/gettime.m4 \
+ $(top_srcdir)/gl/m4/gettimeofday.m4 \
+ $(top_srcdir)/gl/m4/glibc21.m4 \
+ $(top_srcdir)/gl/m4/gnulib-common.m4 \
+ $(top_srcdir)/gl/m4/gnulib-comp.m4 \
+ $(top_srcdir)/gl/m4/group-member.m4 \
+ $(top_srcdir)/gl/m4/human.m4 $(top_srcdir)/gl/m4/i-ring.m4 \
+ $(top_srcdir)/gl/m4/iconv.m4 $(top_srcdir)/gl/m4/idcache.m4 \
+ $(top_srcdir)/gl/m4/include_next.m4 \
+ $(top_srcdir)/gl/m4/inet_pton.m4 $(top_srcdir)/gl/m4/inline.m4 \
+ $(top_srcdir)/gl/m4/intlmacosx.m4 \
+ $(top_srcdir)/gl/m4/intmax_t.m4 \
+ $(top_srcdir)/gl/m4/inttostr.m4 \
+ $(top_srcdir)/gl/m4/inttypes-pri.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/isfinite.m4 \
+ $(top_srcdir)/gl/m4/isinf.m4 $(top_srcdir)/gl/m4/isnand.m4 \
+ $(top_srcdir)/gl/m4/isnanf.m4 $(top_srcdir)/gl/m4/isnanl.m4 \
+ $(top_srcdir)/gl/m4/iswblank.m4 \
+ $(top_srcdir)/gl/m4/langinfo_h.m4 \
+ $(top_srcdir)/gl/m4/largefile.m4 \
+ $(top_srcdir)/gl/m4/lcmessage.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/libunistring-base.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-tr.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/localename.m4 $(top_srcdir)/gl/m4/lock.m4 \
+ $(top_srcdir)/gl/m4/longlong.m4 \
+ $(top_srcdir)/gl/m4/ls-mntd-fs.m4 $(top_srcdir)/gl/m4/lseek.m4 \
+ $(top_srcdir)/gl/m4/lstat.m4 $(top_srcdir)/gl/m4/malloc.m4 \
+ $(top_srcdir)/gl/m4/malloca.m4 \
+ $(top_srcdir)/gl/m4/manywarnings.m4 \
+ $(top_srcdir)/gl/m4/math_h.m4 $(top_srcdir)/gl/m4/mathfunc.m4 \
+ $(top_srcdir)/gl/m4/mbchar.m4 $(top_srcdir)/gl/m4/mbiter.m4 \
+ $(top_srcdir)/gl/m4/mbrtowc.m4 $(top_srcdir)/gl/m4/mbsinit.m4 \
+ $(top_srcdir)/gl/m4/mbslen.m4 $(top_srcdir)/gl/m4/mbsrtowcs.m4 \
+ $(top_srcdir)/gl/m4/mbstate_t.m4 \
+ $(top_srcdir)/gl/m4/mbswidth.m4 $(top_srcdir)/gl/m4/mbtowc.m4 \
+ $(top_srcdir)/gl/m4/memchr.m4 $(top_srcdir)/gl/m4/mempcpy.m4 \
+ $(top_srcdir)/gl/m4/memrchr.m4 $(top_srcdir)/gl/m4/mktime.m4 \
+ $(top_srcdir)/gl/m4/mmap-anon.m4 $(top_srcdir)/gl/m4/mode_t.m4 \
+ $(top_srcdir)/gl/m4/modechange.m4 $(top_srcdir)/gl/m4/modf.m4 \
+ $(top_srcdir)/gl/m4/mountlist.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/nanosleep.m4 \
+ $(top_srcdir)/gl/m4/netinet_in_h.m4 \
+ $(top_srcdir)/gl/m4/nl_langinfo.m4 $(top_srcdir)/gl/m4/nls.m4 \
+ $(top_srcdir)/gl/m4/nocrash.m4 $(top_srcdir)/gl/m4/off_t.m4 \
+ $(top_srcdir)/gl/m4/onceonly.m4 $(top_srcdir)/gl/m4/open.m4 \
+ $(top_srcdir)/gl/m4/openat.m4 $(top_srcdir)/gl/m4/opendir.m4 \
+ $(top_srcdir)/gl/m4/parse-datetime.m4 \
+ $(top_srcdir)/gl/m4/pathmax.m4 $(top_srcdir)/gl/m4/perror.m4 \
+ $(top_srcdir)/gl/m4/pipe.m4 $(top_srcdir)/gl/m4/po.m4 \
+ $(top_srcdir)/gl/m4/printf.m4 $(top_srcdir)/gl/m4/priv-set.m4 \
+ $(top_srcdir)/gl/m4/progtest.m4 $(top_srcdir)/gl/m4/putenv.m4 \
+ $(top_srcdir)/gl/m4/quote.m4 $(top_srcdir)/gl/m4/quotearg.m4 \
+ $(top_srcdir)/gl/m4/raise.m4 $(top_srcdir)/gl/m4/read.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/regex.m4 \
+ $(top_srcdir)/gl/m4/rewinddir.m4 $(top_srcdir)/gl/m4/rmdir.m4 \
+ $(top_srcdir)/gl/m4/rpmatch.m4 \
+ $(top_srcdir)/gl/m4/safe-read.m4 $(top_srcdir)/gl/m4/same.m4 \
+ $(top_srcdir)/gl/m4/save-cwd.m4 $(top_srcdir)/gl/m4/savedir.m4 \
+ $(top_srcdir)/gl/m4/select.m4 \
+ $(top_srcdir)/gl/m4/selinux-context-h.m4 \
+ $(top_srcdir)/gl/m4/selinux-selinux-h.m4 \
+ $(top_srcdir)/gl/m4/setenv.m4 $(top_srcdir)/gl/m4/setlocale.m4 \
+ $(top_srcdir)/gl/m4/sigaction.m4 \
+ $(top_srcdir)/gl/m4/signal_h.m4 \
+ $(top_srcdir)/gl/m4/signalblocking.m4 \
+ $(top_srcdir)/gl/m4/size_max.m4 $(top_srcdir)/gl/m4/sleep.m4 \
+ $(top_srcdir)/gl/m4/snprintf.m4 \
+ $(top_srcdir)/gl/m4/socketlib.m4 \
+ $(top_srcdir)/gl/m4/sockets.m4 $(top_srcdir)/gl/m4/socklen.m4 \
+ $(top_srcdir)/gl/m4/sockpfaf.m4 $(top_srcdir)/gl/m4/ssize_t.m4 \
+ $(top_srcdir)/gl/m4/st_dm_mode.m4 \
+ $(top_srcdir)/gl/m4/stat-size.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/stdbool.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/strdup.m4 $(top_srcdir)/gl/m4/strerror.m4 \
+ $(top_srcdir)/gl/m4/strerror_r.m4 \
+ $(top_srcdir)/gl/m4/strftime.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/strstr.m4 $(top_srcdir)/gl/m4/strtoull.m4 \
+ $(top_srcdir)/gl/m4/strtoumax.m4 \
+ $(top_srcdir)/gl/m4/symlink.m4 \
+ $(top_srcdir)/gl/m4/symlinkat.m4 \
+ $(top_srcdir)/gl/m4/sys_ioctl_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/sys_utsname_h.m4 \
+ $(top_srcdir)/gl/m4/sys_wait_h.m4 \
+ $(top_srcdir)/gl/m4/thread.m4 $(top_srcdir)/gl/m4/threadlib.m4 \
+ $(top_srcdir)/gl/m4/time_h.m4 $(top_srcdir)/gl/m4/time_r.m4 \
+ $(top_srcdir)/gl/m4/time_rz.m4 $(top_srcdir)/gl/m4/timegm.m4 \
+ $(top_srcdir)/gl/m4/timespec.m4 \
+ $(top_srcdir)/gl/m4/tm_gmtoff.m4 $(top_srcdir)/gl/m4/trunc.m4 \
+ $(top_srcdir)/gl/m4/uname.m4 $(top_srcdir)/gl/m4/ungetc.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/unlinkdir.m4 \
+ $(top_srcdir)/gl/m4/vasnprintf.m4 \
+ $(top_srcdir)/gl/m4/version-etc.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/wctob.m4 $(top_srcdir)/gl/m4/wctomb.m4 \
+ $(top_srcdir)/gl/m4/wctype_h.m4 $(top_srcdir)/gl/m4/wcwidth.m4 \
+ $(top_srcdir)/gl/m4/wint_t.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/xstrtod.m4 \
+ $(top_srcdir)/gl/m4/xstrtol.m4 $(top_srcdir)/gl/m4/yesno.m4 \
+ $(top_srcdir)/gl/m4/yield.m4 $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+mkinstalldirs = $(SHELL) $(top_srcdir)/build-aux/mkinstalldirs
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+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 =
+SOURCES =
+DIST_SOURCES =
+am__can_run_installinfo = \
+ case $$AM_UPDATE_INFO_DIR in \
+ n|no|NO) false;; \
+ *) (install-info --version) >/dev/null 2>&1;; \
+ esac
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
+RUNTESTDEFAULTFLAGS = --tool $$tool --srcdir $$srcdir
+EXPECT = expect
+RUNTEST = runtest
+am__tty_colors_dummy = \
+ mgn= red= grn= lgn= blu= brg= std=; \
+ am__color_tests=no
+am__tty_colors = { \
+ $(am__tty_colors_dummy); \
+ if test "X$(AM_COLOR_TESTS)" = Xno; then \
+ am__color_tests=no; \
+ elif test "X$(AM_COLOR_TESTS)" = Xalways; then \
+ am__color_tests=yes; \
+ elif test "X$$TERM" != Xdumb && { test -t 1; } 2>/dev/null; then \
+ am__color_tests=yes; \
+ fi; \
+ if test $$am__color_tests = yes; then \
+ red=''; \
+ grn=''; \
+ lgn=''; \
+ blu=''; \
+ mgn=''; \
+ brg=''; \
+ std=''; \
+ fi; \
+}
+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__recheck_rx = ^[ ]*:recheck:[ ]*
+am__global_test_result_rx = ^[ ]*:global-test-result:[ ]*
+am__copy_in_global_log_rx = ^[ ]*:copy-in-global-log:[ ]*
+# A command that, given a newline-separated list of test names on the
+# standard input, print the name of the tests that are to be re-run
+# upon "make recheck".
+am__list_recheck_tests = $(AWK) '{ \
+ recheck = 1; \
+ while ((rc = (getline line < ($$0 ".trs"))) != 0) \
+ { \
+ if (rc < 0) \
+ { \
+ if ((getline line2 < ($$0 ".log")) < 0) \
+ recheck = 0; \
+ break; \
+ } \
+ else if (line ~ /$(am__recheck_rx)[nN][Oo]/) \
+ { \
+ recheck = 0; \
+ break; \
+ } \
+ else if (line ~ /$(am__recheck_rx)[yY][eE][sS]/) \
+ { \
+ break; \
+ } \
+ }; \
+ if (recheck) \
+ print $$0; \
+ close ($$0 ".trs"); \
+ close ($$0 ".log"); \
+}'
+# A command that, given a newline-separated list of test names on the
+# standard input, create the global log from their .trs and .log files.
+am__create_global_log = $(AWK) ' \
+function fatal(msg) \
+{ \
+ print "fatal: making $@: " msg | "cat >&2"; \
+ exit 1; \
+} \
+function rst_section(header) \
+{ \
+ print header; \
+ len = length(header); \
+ for (i = 1; i <= len; i = i + 1) \
+ printf "="; \
+ printf "\n\n"; \
+} \
+{ \
+ copy_in_global_log = 1; \
+ global_test_result = "RUN"; \
+ while ((rc = (getline line < ($$0 ".trs"))) != 0) \
+ { \
+ if (rc < 0) \
+ fatal("failed to read from " $$0 ".trs"); \
+ if (line ~ /$(am__global_test_result_rx)/) \
+ { \
+ sub("$(am__global_test_result_rx)", "", line); \
+ sub("[ ]*$$", "", line); \
+ global_test_result = line; \
+ } \
+ else if (line ~ /$(am__copy_in_global_log_rx)[nN][oO]/) \
+ copy_in_global_log = 0; \
+ }; \
+ if (copy_in_global_log) \
+ { \
+ rst_section(global_test_result ": " $$0); \
+ while ((rc = (getline line < ($$0 ".log"))) != 0) \
+ { \
+ if (rc < 0) \
+ fatal("failed to read from " $$0 ".log"); \
+ print line; \
+ }; \
+ printf "\n"; \
+ }; \
+ close ($$0 ".trs"); \
+ close ($$0 ".log"); \
+}'
+# Restructured Text title.
+am__rst_title = { sed 's/.*/ & /;h;s/./=/g;p;x;s/ *$$//;p;g' && echo; }
+# Solaris 10 'make', and several other traditional 'make' implementations,
+# pass "-e" to $(SHELL), and POSIX 2008 even requires this. Work around it
+# by disabling -e (using the XSI extension "set +e") if it's set.
+am__sh_e_setup = case $$- in *e*) set +e;; esac
+# Default flags passed to test drivers.
+am__common_driver_flags = \
+ --color-tests "$$am__color_tests" \
+ --enable-hard-errors "$$am__enable_hard_errors" \
+ --expect-failure "$$am__expect_failure"
+# To be inserted before the command running the test. Creates the
+# directory for the log if needed. Stores in $dir the directory
+# containing $f, in $tst the test, in $log the log. Executes the
+# developer- defined test setup AM_TESTS_ENVIRONMENT (if any), and
+# passes TESTS_ENVIRONMENT. Set up options for the wrapper that
+# will run the test scripts (or their associated LOG_COMPILER, if
+# thy have one).
+am__check_pre = \
+$(am__sh_e_setup); \
+$(am__vpath_adj_setup) $(am__vpath_adj) \
+$(am__tty_colors); \
+srcdir=$(srcdir); export srcdir; \
+case "$@" in \
+ */*) am__odir=`echo "./$@" | sed 's|/[^/]*$$||'`;; \
+ *) am__odir=.;; \
+esac; \
+test "x$$am__odir" = x"." || test -d "$$am__odir" \
+ || $(MKDIR_P) "$$am__odir" || exit $$?; \
+if test -f "./$$f"; then dir=./; \
+elif test -f "$$f"; then dir=; \
+else dir="$(srcdir)/"; fi; \
+tst=$$dir$$f; log='$@'; \
+if test -n '$(DISABLE_HARD_ERRORS)'; then \
+ am__enable_hard_errors=no; \
+else \
+ am__enable_hard_errors=yes; \
+fi; \
+case " $(XFAIL_TESTS) " in \
+ *[\ \ ]$$f[\ \ ]* | *[\ \ ]$$dir$$f[\ \ ]*) \
+ am__expect_failure=yes;; \
+ *) \
+ am__expect_failure=no;; \
+esac; \
+$(AM_TESTS_ENVIRONMENT) $(TESTS_ENVIRONMENT)
+# A shell command to get the names of the tests scripts with any registered
+# extension removed (i.e., equivalently, the names of the test logs, with
+# the '.log' extension removed). The result is saved in the shell variable
+# '$bases'. This honors runtime overriding of TESTS and TEST_LOGS. Sadly,
+# we cannot use something simpler, involving e.g., "$(TEST_LOGS:.log=)",
+# since that might cause problem with VPATH rewrites for suffix-less tests.
+# See also 'test-harness-vpath-rewrite.sh' and 'test-trs-basic.sh'.
+am__set_TESTS_bases = \
+ bases='$(TEST_LOGS)'; \
+ bases=`for i in $$bases; do echo $$i; done | sed 's/\.log$$//'`; \
+ bases=`echo $$bases`
+RECHECK_LOGS = $(TEST_LOGS)
+AM_RECURSIVE_TARGETS = check recheck
+TEST_SUITE_LOG = test-suite.log
+am__test_logs1 = $(TESTS:=.log)
+am__test_logs2 = $(am__test_logs1:@EXEEXT@.log=.log)
+am__test_logs3 = $(am__test_logs2:.sh.log=.log)
+SH_LOG_DRIVER = $(SHELL) $(top_srcdir)/build-aux/test-driver
+SH_LOG_COMPILE = $(SH_LOG_COMPILER) $(AM_SH_LOG_FLAGS) $(SH_LOG_FLAGS)
+am__set_b = \
+ case '$@' in \
+ */*) \
+ case '$*' in \
+ */*) b='$*';; \
+ *) b=`echo '$@' | sed 's/\.log$$//'`; \
+ esac;; \
+ *) \
+ b='$*';; \
+ esac
+TEST_LOGS = $(am__test_logs3:.py.log=.log)
+PY_LOG_DRIVER = $(SHELL) $(top_srcdir)/build-aux/test-driver
+PY_LOG_COMPILE = $(PY_LOG_COMPILER) $(AM_PY_LOG_FLAGS) $(PY_LOG_FLAGS)
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+pkglibexecdir = @pkglibexecdir@
+ACLOCAL = @ACLOCAL@
+ALLOCA = @ALLOCA@
+ALLOCA_H = @ALLOCA_H@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+APPLE_UNIVERSAL_BUILD = @APPLE_UNIVERSAL_BUILD@
+AR = @AR@
+ARFLAGS = @ARFLAGS@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AUXDIR = @AUXDIR@
+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@
+BYTESWAP_H = @BYTESWAP_H@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CONFIG_INCLUDE = @CONFIG_INCLUDE@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFAULT_ARG_SIZE = @DEFAULT_ARG_SIZE@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EMULTIHOP_HIDDEN = @EMULTIHOP_HIDDEN@
+EMULTIHOP_VALUE = @EMULTIHOP_VALUE@
+ENOLINK_HIDDEN = @ENOLINK_HIDDEN@
+ENOLINK_VALUE = @ENOLINK_VALUE@
+EOVERFLOW_HIDDEN = @EOVERFLOW_HIDDEN@
+EOVERFLOW_VALUE = @EOVERFLOW_VALUE@
+ERRNO_H = @ERRNO_H@
+EXEEXT = @EXEEXT@
+FAKETIME = @FAKETIME@
+FINDLIBOBJS = @FINDLIBOBJS@
+FINDLIBS = @FINDLIBS@
+FLOAT_H = @FLOAT_H@
+FNMATCH_H = @FNMATCH_H@
+GETHOSTNAME_LIB = @GETHOSTNAME_LIB@
+GETOPT_H = @GETOPT_H@
+GETTEXT_MACRO_VERSION = @GETTEXT_MACRO_VERSION@
+GLIBC21 = @GLIBC21@
+GMSGFMT = @GMSGFMT@
+GMSGFMT_015 = @GMSGFMT_015@
+GNULIB_ACCEPT = @GNULIB_ACCEPT@
+GNULIB_ACCEPT4 = @GNULIB_ACCEPT4@
+GNULIB_ACOSF = @GNULIB_ACOSF@
+GNULIB_ACOSL = @GNULIB_ACOSL@
+GNULIB_ALPHASORT = @GNULIB_ALPHASORT@
+GNULIB_ASINF = @GNULIB_ASINF@
+GNULIB_ASINL = @GNULIB_ASINL@
+GNULIB_ATAN2F = @GNULIB_ATAN2F@
+GNULIB_ATANF = @GNULIB_ATANF@
+GNULIB_ATANL = @GNULIB_ATANL@
+GNULIB_ATOLL = @GNULIB_ATOLL@
+GNULIB_BIND = @GNULIB_BIND@
+GNULIB_BTOWC = @GNULIB_BTOWC@
+GNULIB_CALLOC_POSIX = @GNULIB_CALLOC_POSIX@
+GNULIB_CANONICALIZE_FILE_NAME = @GNULIB_CANONICALIZE_FILE_NAME@
+GNULIB_CBRT = @GNULIB_CBRT@
+GNULIB_CBRTF = @GNULIB_CBRTF@
+GNULIB_CBRTL = @GNULIB_CBRTL@
+GNULIB_CEIL = @GNULIB_CEIL@
+GNULIB_CEILF = @GNULIB_CEILF@
+GNULIB_CEILL = @GNULIB_CEILL@
+GNULIB_CHDIR = @GNULIB_CHDIR@
+GNULIB_CHOWN = @GNULIB_CHOWN@
+GNULIB_CLOSE = @GNULIB_CLOSE@
+GNULIB_CLOSEDIR = @GNULIB_CLOSEDIR@
+GNULIB_CONNECT = @GNULIB_CONNECT@
+GNULIB_COPYSIGN = @GNULIB_COPYSIGN@
+GNULIB_COPYSIGNF = @GNULIB_COPYSIGNF@
+GNULIB_COPYSIGNL = @GNULIB_COPYSIGNL@
+GNULIB_COSF = @GNULIB_COSF@
+GNULIB_COSHF = @GNULIB_COSHF@
+GNULIB_COSL = @GNULIB_COSL@
+GNULIB_DIRFD = @GNULIB_DIRFD@
+GNULIB_DPRINTF = @GNULIB_DPRINTF@
+GNULIB_DUP = @GNULIB_DUP@
+GNULIB_DUP2 = @GNULIB_DUP2@
+GNULIB_DUP3 = @GNULIB_DUP3@
+GNULIB_DUPLOCALE = @GNULIB_DUPLOCALE@
+GNULIB_ENVIRON = @GNULIB_ENVIRON@
+GNULIB_EUIDACCESS = @GNULIB_EUIDACCESS@
+GNULIB_EXP2 = @GNULIB_EXP2@
+GNULIB_EXP2F = @GNULIB_EXP2F@
+GNULIB_EXP2L = @GNULIB_EXP2L@
+GNULIB_EXPF = @GNULIB_EXPF@
+GNULIB_EXPL = @GNULIB_EXPL@
+GNULIB_EXPM1 = @GNULIB_EXPM1@
+GNULIB_EXPM1F = @GNULIB_EXPM1F@
+GNULIB_EXPM1L = @GNULIB_EXPM1L@
+GNULIB_FABSF = @GNULIB_FABSF@
+GNULIB_FABSL = @GNULIB_FABSL@
+GNULIB_FACCESSAT = @GNULIB_FACCESSAT@
+GNULIB_FCHDIR = @GNULIB_FCHDIR@
+GNULIB_FCHMODAT = @GNULIB_FCHMODAT@
+GNULIB_FCHOWNAT = @GNULIB_FCHOWNAT@
+GNULIB_FCLOSE = @GNULIB_FCLOSE@
+GNULIB_FCNTL = @GNULIB_FCNTL@
+GNULIB_FDATASYNC = @GNULIB_FDATASYNC@
+GNULIB_FDOPEN = @GNULIB_FDOPEN@
+GNULIB_FDOPENDIR = @GNULIB_FDOPENDIR@
+GNULIB_FFLUSH = @GNULIB_FFLUSH@
+GNULIB_FFS = @GNULIB_FFS@
+GNULIB_FFSL = @GNULIB_FFSL@
+GNULIB_FFSLL = @GNULIB_FFSLL@
+GNULIB_FGETC = @GNULIB_FGETC@
+GNULIB_FGETS = @GNULIB_FGETS@
+GNULIB_FLOOR = @GNULIB_FLOOR@
+GNULIB_FLOORF = @GNULIB_FLOORF@
+GNULIB_FLOORL = @GNULIB_FLOORL@
+GNULIB_FMA = @GNULIB_FMA@
+GNULIB_FMAF = @GNULIB_FMAF@
+GNULIB_FMAL = @GNULIB_FMAL@
+GNULIB_FMOD = @GNULIB_FMOD@
+GNULIB_FMODF = @GNULIB_FMODF@
+GNULIB_FMODL = @GNULIB_FMODL@
+GNULIB_FOPEN = @GNULIB_FOPEN@
+GNULIB_FPRINTF = @GNULIB_FPRINTF@
+GNULIB_FPRINTF_POSIX = @GNULIB_FPRINTF_POSIX@
+GNULIB_FPURGE = @GNULIB_FPURGE@
+GNULIB_FPUTC = @GNULIB_FPUTC@
+GNULIB_FPUTS = @GNULIB_FPUTS@
+GNULIB_FREAD = @GNULIB_FREAD@
+GNULIB_FREOPEN = @GNULIB_FREOPEN@
+GNULIB_FREXP = @GNULIB_FREXP@
+GNULIB_FREXPF = @GNULIB_FREXPF@
+GNULIB_FREXPL = @GNULIB_FREXPL@
+GNULIB_FSCANF = @GNULIB_FSCANF@
+GNULIB_FSEEK = @GNULIB_FSEEK@
+GNULIB_FSEEKO = @GNULIB_FSEEKO@
+GNULIB_FSTAT = @GNULIB_FSTAT@
+GNULIB_FSTATAT = @GNULIB_FSTATAT@
+GNULIB_FSYNC = @GNULIB_FSYNC@
+GNULIB_FTELL = @GNULIB_FTELL@
+GNULIB_FTELLO = @GNULIB_FTELLO@
+GNULIB_FTRUNCATE = @GNULIB_FTRUNCATE@
+GNULIB_FUTIMENS = @GNULIB_FUTIMENS@
+GNULIB_FWRITE = @GNULIB_FWRITE@
+GNULIB_GETC = @GNULIB_GETC@
+GNULIB_GETCHAR = @GNULIB_GETCHAR@
+GNULIB_GETCWD = @GNULIB_GETCWD@
+GNULIB_GETDELIM = @GNULIB_GETDELIM@
+GNULIB_GETDOMAINNAME = @GNULIB_GETDOMAINNAME@
+GNULIB_GETDTABLESIZE = @GNULIB_GETDTABLESIZE@
+GNULIB_GETGROUPS = @GNULIB_GETGROUPS@
+GNULIB_GETHOSTNAME = @GNULIB_GETHOSTNAME@
+GNULIB_GETLINE = @GNULIB_GETLINE@
+GNULIB_GETLOADAVG = @GNULIB_GETLOADAVG@
+GNULIB_GETLOGIN = @GNULIB_GETLOGIN@
+GNULIB_GETLOGIN_R = @GNULIB_GETLOGIN_R@
+GNULIB_GETPAGESIZE = @GNULIB_GETPAGESIZE@
+GNULIB_GETPEERNAME = @GNULIB_GETPEERNAME@
+GNULIB_GETSOCKNAME = @GNULIB_GETSOCKNAME@
+GNULIB_GETSOCKOPT = @GNULIB_GETSOCKOPT@
+GNULIB_GETSUBOPT = @GNULIB_GETSUBOPT@
+GNULIB_GETTIMEOFDAY = @GNULIB_GETTIMEOFDAY@
+GNULIB_GETUSERSHELL = @GNULIB_GETUSERSHELL@
+GNULIB_GL_UNISTD_H_GETOPT = @GNULIB_GL_UNISTD_H_GETOPT@
+GNULIB_GRANTPT = @GNULIB_GRANTPT@
+GNULIB_GROUP_MEMBER = @GNULIB_GROUP_MEMBER@
+GNULIB_HYPOT = @GNULIB_HYPOT@
+GNULIB_HYPOTF = @GNULIB_HYPOTF@
+GNULIB_HYPOTL = @GNULIB_HYPOTL@
+GNULIB_ILOGB = @GNULIB_ILOGB@
+GNULIB_ILOGBF = @GNULIB_ILOGBF@
+GNULIB_ILOGBL = @GNULIB_ILOGBL@
+GNULIB_IMAXABS = @GNULIB_IMAXABS@
+GNULIB_IMAXDIV = @GNULIB_IMAXDIV@
+GNULIB_INET_NTOP = @GNULIB_INET_NTOP@
+GNULIB_INET_PTON = @GNULIB_INET_PTON@
+GNULIB_IOCTL = @GNULIB_IOCTL@
+GNULIB_ISATTY = @GNULIB_ISATTY@
+GNULIB_ISBLANK = @GNULIB_ISBLANK@
+GNULIB_ISFINITE = @GNULIB_ISFINITE@
+GNULIB_ISINF = @GNULIB_ISINF@
+GNULIB_ISNAN = @GNULIB_ISNAN@
+GNULIB_ISNAND = @GNULIB_ISNAND@
+GNULIB_ISNANF = @GNULIB_ISNANF@
+GNULIB_ISNANL = @GNULIB_ISNANL@
+GNULIB_ISWBLANK = @GNULIB_ISWBLANK@
+GNULIB_ISWCTYPE = @GNULIB_ISWCTYPE@
+GNULIB_LCHMOD = @GNULIB_LCHMOD@
+GNULIB_LCHOWN = @GNULIB_LCHOWN@
+GNULIB_LDEXPF = @GNULIB_LDEXPF@
+GNULIB_LDEXPL = @GNULIB_LDEXPL@
+GNULIB_LINK = @GNULIB_LINK@
+GNULIB_LINKAT = @GNULIB_LINKAT@
+GNULIB_LISTEN = @GNULIB_LISTEN@
+GNULIB_LOCALECONV = @GNULIB_LOCALECONV@
+GNULIB_LOG = @GNULIB_LOG@
+GNULIB_LOG10 = @GNULIB_LOG10@
+GNULIB_LOG10F = @GNULIB_LOG10F@
+GNULIB_LOG10L = @GNULIB_LOG10L@
+GNULIB_LOG1P = @GNULIB_LOG1P@
+GNULIB_LOG1PF = @GNULIB_LOG1PF@
+GNULIB_LOG1PL = @GNULIB_LOG1PL@
+GNULIB_LOG2 = @GNULIB_LOG2@
+GNULIB_LOG2F = @GNULIB_LOG2F@
+GNULIB_LOG2L = @GNULIB_LOG2L@
+GNULIB_LOGB = @GNULIB_LOGB@
+GNULIB_LOGBF = @GNULIB_LOGBF@
+GNULIB_LOGBL = @GNULIB_LOGBL@
+GNULIB_LOGF = @GNULIB_LOGF@
+GNULIB_LOGL = @GNULIB_LOGL@
+GNULIB_LSEEK = @GNULIB_LSEEK@
+GNULIB_LSTAT = @GNULIB_LSTAT@
+GNULIB_MALLOC_POSIX = @GNULIB_MALLOC_POSIX@
+GNULIB_MBRLEN = @GNULIB_MBRLEN@
+GNULIB_MBRTOWC = @GNULIB_MBRTOWC@
+GNULIB_MBSCASECMP = @GNULIB_MBSCASECMP@
+GNULIB_MBSCASESTR = @GNULIB_MBSCASESTR@
+GNULIB_MBSCHR = @GNULIB_MBSCHR@
+GNULIB_MBSCSPN = @GNULIB_MBSCSPN@
+GNULIB_MBSINIT = @GNULIB_MBSINIT@
+GNULIB_MBSLEN = @GNULIB_MBSLEN@
+GNULIB_MBSNCASECMP = @GNULIB_MBSNCASECMP@
+GNULIB_MBSNLEN = @GNULIB_MBSNLEN@
+GNULIB_MBSNRTOWCS = @GNULIB_MBSNRTOWCS@
+GNULIB_MBSPBRK = @GNULIB_MBSPBRK@
+GNULIB_MBSPCASECMP = @GNULIB_MBSPCASECMP@
+GNULIB_MBSRCHR = @GNULIB_MBSRCHR@
+GNULIB_MBSRTOWCS = @GNULIB_MBSRTOWCS@
+GNULIB_MBSSEP = @GNULIB_MBSSEP@
+GNULIB_MBSSPN = @GNULIB_MBSSPN@
+GNULIB_MBSSTR = @GNULIB_MBSSTR@
+GNULIB_MBSTOK_R = @GNULIB_MBSTOK_R@
+GNULIB_MBTOWC = @GNULIB_MBTOWC@
+GNULIB_MEMCHR = @GNULIB_MEMCHR@
+GNULIB_MEMMEM = @GNULIB_MEMMEM@
+GNULIB_MEMPCPY = @GNULIB_MEMPCPY@
+GNULIB_MEMRCHR = @GNULIB_MEMRCHR@
+GNULIB_MKDIRAT = @GNULIB_MKDIRAT@
+GNULIB_MKDTEMP = @GNULIB_MKDTEMP@
+GNULIB_MKFIFO = @GNULIB_MKFIFO@
+GNULIB_MKFIFOAT = @GNULIB_MKFIFOAT@
+GNULIB_MKNOD = @GNULIB_MKNOD@
+GNULIB_MKNODAT = @GNULIB_MKNODAT@
+GNULIB_MKOSTEMP = @GNULIB_MKOSTEMP@
+GNULIB_MKOSTEMPS = @GNULIB_MKOSTEMPS@
+GNULIB_MKSTEMP = @GNULIB_MKSTEMP@
+GNULIB_MKSTEMPS = @GNULIB_MKSTEMPS@
+GNULIB_MKTIME = @GNULIB_MKTIME@
+GNULIB_MODF = @GNULIB_MODF@
+GNULIB_MODFF = @GNULIB_MODFF@
+GNULIB_MODFL = @GNULIB_MODFL@
+GNULIB_NANOSLEEP = @GNULIB_NANOSLEEP@
+GNULIB_NL_LANGINFO = @GNULIB_NL_LANGINFO@
+GNULIB_NONBLOCKING = @GNULIB_NONBLOCKING@
+GNULIB_OBSTACK_PRINTF = @GNULIB_OBSTACK_PRINTF@
+GNULIB_OBSTACK_PRINTF_POSIX = @GNULIB_OBSTACK_PRINTF_POSIX@
+GNULIB_OPEN = @GNULIB_OPEN@
+GNULIB_OPENAT = @GNULIB_OPENAT@
+GNULIB_OPENDIR = @GNULIB_OPENDIR@
+GNULIB_PCLOSE = @GNULIB_PCLOSE@
+GNULIB_PERROR = @GNULIB_PERROR@
+GNULIB_PIPE = @GNULIB_PIPE@
+GNULIB_PIPE2 = @GNULIB_PIPE2@
+GNULIB_POPEN = @GNULIB_POPEN@
+GNULIB_POSIX_OPENPT = @GNULIB_POSIX_OPENPT@
+GNULIB_POWF = @GNULIB_POWF@
+GNULIB_PREAD = @GNULIB_PREAD@
+GNULIB_PRINTF = @GNULIB_PRINTF@
+GNULIB_PRINTF_POSIX = @GNULIB_PRINTF_POSIX@
+GNULIB_PSELECT = @GNULIB_PSELECT@
+GNULIB_PTHREAD_SIGMASK = @GNULIB_PTHREAD_SIGMASK@
+GNULIB_PTSNAME = @GNULIB_PTSNAME@
+GNULIB_PTSNAME_R = @GNULIB_PTSNAME_R@
+GNULIB_PUTC = @GNULIB_PUTC@
+GNULIB_PUTCHAR = @GNULIB_PUTCHAR@
+GNULIB_PUTENV = @GNULIB_PUTENV@
+GNULIB_PUTS = @GNULIB_PUTS@
+GNULIB_PWRITE = @GNULIB_PWRITE@
+GNULIB_QSORT_R = @GNULIB_QSORT_R@
+GNULIB_RAISE = @GNULIB_RAISE@
+GNULIB_RANDOM = @GNULIB_RANDOM@
+GNULIB_RANDOM_R = @GNULIB_RANDOM_R@
+GNULIB_RAWMEMCHR = @GNULIB_RAWMEMCHR@
+GNULIB_READ = @GNULIB_READ@
+GNULIB_READDIR = @GNULIB_READDIR@
+GNULIB_READLINK = @GNULIB_READLINK@
+GNULIB_READLINKAT = @GNULIB_READLINKAT@
+GNULIB_REALLOC_POSIX = @GNULIB_REALLOC_POSIX@
+GNULIB_REALPATH = @GNULIB_REALPATH@
+GNULIB_RECV = @GNULIB_RECV@
+GNULIB_RECVFROM = @GNULIB_RECVFROM@
+GNULIB_REMAINDER = @GNULIB_REMAINDER@
+GNULIB_REMAINDERF = @GNULIB_REMAINDERF@
+GNULIB_REMAINDERL = @GNULIB_REMAINDERL@
+GNULIB_REMOVE = @GNULIB_REMOVE@
+GNULIB_RENAME = @GNULIB_RENAME@
+GNULIB_RENAMEAT = @GNULIB_RENAMEAT@
+GNULIB_REWINDDIR = @GNULIB_REWINDDIR@
+GNULIB_RINT = @GNULIB_RINT@
+GNULIB_RINTF = @GNULIB_RINTF@
+GNULIB_RINTL = @GNULIB_RINTL@
+GNULIB_RMDIR = @GNULIB_RMDIR@
+GNULIB_ROUND = @GNULIB_ROUND@
+GNULIB_ROUNDF = @GNULIB_ROUNDF@
+GNULIB_ROUNDL = @GNULIB_ROUNDL@
+GNULIB_RPMATCH = @GNULIB_RPMATCH@
+GNULIB_SCANDIR = @GNULIB_SCANDIR@
+GNULIB_SCANF = @GNULIB_SCANF@
+GNULIB_SECURE_GETENV = @GNULIB_SECURE_GETENV@
+GNULIB_SELECT = @GNULIB_SELECT@
+GNULIB_SEND = @GNULIB_SEND@
+GNULIB_SENDTO = @GNULIB_SENDTO@
+GNULIB_SETENV = @GNULIB_SETENV@
+GNULIB_SETHOSTNAME = @GNULIB_SETHOSTNAME@
+GNULIB_SETLOCALE = @GNULIB_SETLOCALE@
+GNULIB_SETSOCKOPT = @GNULIB_SETSOCKOPT@
+GNULIB_SHUTDOWN = @GNULIB_SHUTDOWN@
+GNULIB_SIGACTION = @GNULIB_SIGACTION@
+GNULIB_SIGNAL_H_SIGPIPE = @GNULIB_SIGNAL_H_SIGPIPE@
+GNULIB_SIGNBIT = @GNULIB_SIGNBIT@
+GNULIB_SIGPROCMASK = @GNULIB_SIGPROCMASK@
+GNULIB_SINF = @GNULIB_SINF@
+GNULIB_SINHF = @GNULIB_SINHF@
+GNULIB_SINL = @GNULIB_SINL@
+GNULIB_SLEEP = @GNULIB_SLEEP@
+GNULIB_SNPRINTF = @GNULIB_SNPRINTF@
+GNULIB_SOCKET = @GNULIB_SOCKET@
+GNULIB_SPRINTF_POSIX = @GNULIB_SPRINTF_POSIX@
+GNULIB_SQRTF = @GNULIB_SQRTF@
+GNULIB_SQRTL = @GNULIB_SQRTL@
+GNULIB_STAT = @GNULIB_STAT@
+GNULIB_STDIO_H_NONBLOCKING = @GNULIB_STDIO_H_NONBLOCKING@
+GNULIB_STDIO_H_SIGPIPE = @GNULIB_STDIO_H_SIGPIPE@
+GNULIB_STPCPY = @GNULIB_STPCPY@
+GNULIB_STPNCPY = @GNULIB_STPNCPY@
+GNULIB_STRCASESTR = @GNULIB_STRCASESTR@
+GNULIB_STRCHRNUL = @GNULIB_STRCHRNUL@
+GNULIB_STRDUP = @GNULIB_STRDUP@
+GNULIB_STRERROR = @GNULIB_STRERROR@
+GNULIB_STRERROR_R = @GNULIB_STRERROR_R@
+GNULIB_STRNCAT = @GNULIB_STRNCAT@
+GNULIB_STRNDUP = @GNULIB_STRNDUP@
+GNULIB_STRNLEN = @GNULIB_STRNLEN@
+GNULIB_STRPBRK = @GNULIB_STRPBRK@
+GNULIB_STRPTIME = @GNULIB_STRPTIME@
+GNULIB_STRSEP = @GNULIB_STRSEP@
+GNULIB_STRSIGNAL = @GNULIB_STRSIGNAL@
+GNULIB_STRSTR = @GNULIB_STRSTR@
+GNULIB_STRTOD = @GNULIB_STRTOD@
+GNULIB_STRTOIMAX = @GNULIB_STRTOIMAX@
+GNULIB_STRTOK_R = @GNULIB_STRTOK_R@
+GNULIB_STRTOLL = @GNULIB_STRTOLL@
+GNULIB_STRTOULL = @GNULIB_STRTOULL@
+GNULIB_STRTOUMAX = @GNULIB_STRTOUMAX@
+GNULIB_STRVERSCMP = @GNULIB_STRVERSCMP@
+GNULIB_SYMLINK = @GNULIB_SYMLINK@
+GNULIB_SYMLINKAT = @GNULIB_SYMLINKAT@
+GNULIB_SYSTEM_POSIX = @GNULIB_SYSTEM_POSIX@
+GNULIB_TANF = @GNULIB_TANF@
+GNULIB_TANHF = @GNULIB_TANHF@
+GNULIB_TANL = @GNULIB_TANL@
+GNULIB_TIMEGM = @GNULIB_TIMEGM@
+GNULIB_TIME_R = @GNULIB_TIME_R@
+GNULIB_TIME_RZ = @GNULIB_TIME_RZ@
+GNULIB_TMPFILE = @GNULIB_TMPFILE@
+GNULIB_TOWCTRANS = @GNULIB_TOWCTRANS@
+GNULIB_TRUNC = @GNULIB_TRUNC@
+GNULIB_TRUNCF = @GNULIB_TRUNCF@
+GNULIB_TRUNCL = @GNULIB_TRUNCL@
+GNULIB_TTYNAME_R = @GNULIB_TTYNAME_R@
+GNULIB_UNAME = @GNULIB_UNAME@
+GNULIB_UNISTD_H_NONBLOCKING = @GNULIB_UNISTD_H_NONBLOCKING@
+GNULIB_UNISTD_H_SIGPIPE = @GNULIB_UNISTD_H_SIGPIPE@
+GNULIB_UNLINK = @GNULIB_UNLINK@
+GNULIB_UNLINKAT = @GNULIB_UNLINKAT@
+GNULIB_UNLOCKPT = @GNULIB_UNLOCKPT@
+GNULIB_UNSETENV = @GNULIB_UNSETENV@
+GNULIB_USLEEP = @GNULIB_USLEEP@
+GNULIB_UTIMENSAT = @GNULIB_UTIMENSAT@
+GNULIB_VASPRINTF = @GNULIB_VASPRINTF@
+GNULIB_VDPRINTF = @GNULIB_VDPRINTF@
+GNULIB_VFPRINTF = @GNULIB_VFPRINTF@
+GNULIB_VFPRINTF_POSIX = @GNULIB_VFPRINTF_POSIX@
+GNULIB_VFSCANF = @GNULIB_VFSCANF@
+GNULIB_VPRINTF = @GNULIB_VPRINTF@
+GNULIB_VPRINTF_POSIX = @GNULIB_VPRINTF_POSIX@
+GNULIB_VSCANF = @GNULIB_VSCANF@
+GNULIB_VSNPRINTF = @GNULIB_VSNPRINTF@
+GNULIB_VSPRINTF_POSIX = @GNULIB_VSPRINTF_POSIX@
+GNULIB_WAITPID = @GNULIB_WAITPID@
+GNULIB_WCPCPY = @GNULIB_WCPCPY@
+GNULIB_WCPNCPY = @GNULIB_WCPNCPY@
+GNULIB_WCRTOMB = @GNULIB_WCRTOMB@
+GNULIB_WCSCASECMP = @GNULIB_WCSCASECMP@
+GNULIB_WCSCAT = @GNULIB_WCSCAT@
+GNULIB_WCSCHR = @GNULIB_WCSCHR@
+GNULIB_WCSCMP = @GNULIB_WCSCMP@
+GNULIB_WCSCOLL = @GNULIB_WCSCOLL@
+GNULIB_WCSCPY = @GNULIB_WCSCPY@
+GNULIB_WCSCSPN = @GNULIB_WCSCSPN@
+GNULIB_WCSDUP = @GNULIB_WCSDUP@
+GNULIB_WCSLEN = @GNULIB_WCSLEN@
+GNULIB_WCSNCASECMP = @GNULIB_WCSNCASECMP@
+GNULIB_WCSNCAT = @GNULIB_WCSNCAT@
+GNULIB_WCSNCMP = @GNULIB_WCSNCMP@
+GNULIB_WCSNCPY = @GNULIB_WCSNCPY@
+GNULIB_WCSNLEN = @GNULIB_WCSNLEN@
+GNULIB_WCSNRTOMBS = @GNULIB_WCSNRTOMBS@
+GNULIB_WCSPBRK = @GNULIB_WCSPBRK@
+GNULIB_WCSRCHR = @GNULIB_WCSRCHR@
+GNULIB_WCSRTOMBS = @GNULIB_WCSRTOMBS@
+GNULIB_WCSSPN = @GNULIB_WCSSPN@
+GNULIB_WCSSTR = @GNULIB_WCSSTR@
+GNULIB_WCSTOK = @GNULIB_WCSTOK@
+GNULIB_WCSWIDTH = @GNULIB_WCSWIDTH@
+GNULIB_WCSXFRM = @GNULIB_WCSXFRM@
+GNULIB_WCTOB = @GNULIB_WCTOB@
+GNULIB_WCTOMB = @GNULIB_WCTOMB@
+GNULIB_WCTRANS = @GNULIB_WCTRANS@
+GNULIB_WCTYPE = @GNULIB_WCTYPE@
+GNULIB_WCWIDTH = @GNULIB_WCWIDTH@
+GNULIB_WMEMCHR = @GNULIB_WMEMCHR@
+GNULIB_WMEMCMP = @GNULIB_WMEMCMP@
+GNULIB_WMEMCPY = @GNULIB_WMEMCPY@
+GNULIB_WMEMMOVE = @GNULIB_WMEMMOVE@
+GNULIB_WMEMSET = @GNULIB_WMEMSET@
+GNULIB_WRITE = @GNULIB_WRITE@
+GNULIB__EXIT = @GNULIB__EXIT@
+GREP = @GREP@
+HAVE_ACCEPT4 = @HAVE_ACCEPT4@
+HAVE_ACOSF = @HAVE_ACOSF@
+HAVE_ACOSL = @HAVE_ACOSL@
+HAVE_ALPHASORT = @HAVE_ALPHASORT@
+HAVE_ARPA_INET_H = @HAVE_ARPA_INET_H@
+HAVE_ASINF = @HAVE_ASINF@
+HAVE_ASINL = @HAVE_ASINL@
+HAVE_ATAN2F = @HAVE_ATAN2F@
+HAVE_ATANF = @HAVE_ATANF@
+HAVE_ATANL = @HAVE_ATANL@
+HAVE_ATOLL = @HAVE_ATOLL@
+HAVE_ATTRIBUTE_NORETURN = @HAVE_ATTRIBUTE_NORETURN@
+HAVE_BTOWC = @HAVE_BTOWC@
+HAVE_CANONICALIZE_FILE_NAME = @HAVE_CANONICALIZE_FILE_NAME@
+HAVE_CBRT = @HAVE_CBRT@
+HAVE_CBRTF = @HAVE_CBRTF@
+HAVE_CBRTL = @HAVE_CBRTL@
+HAVE_CHOWN = @HAVE_CHOWN@
+HAVE_CLOSEDIR = @HAVE_CLOSEDIR@
+HAVE_COPYSIGN = @HAVE_COPYSIGN@
+HAVE_COPYSIGNL = @HAVE_COPYSIGNL@
+HAVE_COSF = @HAVE_COSF@
+HAVE_COSHF = @HAVE_COSHF@
+HAVE_COSL = @HAVE_COSL@
+HAVE_DECL_ACOSL = @HAVE_DECL_ACOSL@
+HAVE_DECL_ASINL = @HAVE_DECL_ASINL@
+HAVE_DECL_ATANL = @HAVE_DECL_ATANL@
+HAVE_DECL_CBRTF = @HAVE_DECL_CBRTF@
+HAVE_DECL_CBRTL = @HAVE_DECL_CBRTL@
+HAVE_DECL_CEILF = @HAVE_DECL_CEILF@
+HAVE_DECL_CEILL = @HAVE_DECL_CEILL@
+HAVE_DECL_COPYSIGNF = @HAVE_DECL_COPYSIGNF@
+HAVE_DECL_COSL = @HAVE_DECL_COSL@
+HAVE_DECL_DIRFD = @HAVE_DECL_DIRFD@
+HAVE_DECL_ENVIRON = @HAVE_DECL_ENVIRON@
+HAVE_DECL_EXP2 = @HAVE_DECL_EXP2@
+HAVE_DECL_EXP2F = @HAVE_DECL_EXP2F@
+HAVE_DECL_EXP2L = @HAVE_DECL_EXP2L@
+HAVE_DECL_EXPL = @HAVE_DECL_EXPL@
+HAVE_DECL_EXPM1L = @HAVE_DECL_EXPM1L@
+HAVE_DECL_FCHDIR = @HAVE_DECL_FCHDIR@
+HAVE_DECL_FDATASYNC = @HAVE_DECL_FDATASYNC@
+HAVE_DECL_FDOPENDIR = @HAVE_DECL_FDOPENDIR@
+HAVE_DECL_FLOORF = @HAVE_DECL_FLOORF@
+HAVE_DECL_FLOORL = @HAVE_DECL_FLOORL@
+HAVE_DECL_FPURGE = @HAVE_DECL_FPURGE@
+HAVE_DECL_FREXPL = @HAVE_DECL_FREXPL@
+HAVE_DECL_FSEEKO = @HAVE_DECL_FSEEKO@
+HAVE_DECL_FTELLO = @HAVE_DECL_FTELLO@
+HAVE_DECL_GETDELIM = @HAVE_DECL_GETDELIM@
+HAVE_DECL_GETDOMAINNAME = @HAVE_DECL_GETDOMAINNAME@
+HAVE_DECL_GETLINE = @HAVE_DECL_GETLINE@
+HAVE_DECL_GETLOADAVG = @HAVE_DECL_GETLOADAVG@
+HAVE_DECL_GETLOGIN_R = @HAVE_DECL_GETLOGIN_R@
+HAVE_DECL_GETPAGESIZE = @HAVE_DECL_GETPAGESIZE@
+HAVE_DECL_GETUSERSHELL = @HAVE_DECL_GETUSERSHELL@
+HAVE_DECL_IMAXABS = @HAVE_DECL_IMAXABS@
+HAVE_DECL_IMAXDIV = @HAVE_DECL_IMAXDIV@
+HAVE_DECL_INET_NTOP = @HAVE_DECL_INET_NTOP@
+HAVE_DECL_INET_PTON = @HAVE_DECL_INET_PTON@
+HAVE_DECL_LDEXPL = @HAVE_DECL_LDEXPL@
+HAVE_DECL_LOCALTIME_R = @HAVE_DECL_LOCALTIME_R@
+HAVE_DECL_LOG10L = @HAVE_DECL_LOG10L@
+HAVE_DECL_LOG2 = @HAVE_DECL_LOG2@
+HAVE_DECL_LOG2F = @HAVE_DECL_LOG2F@
+HAVE_DECL_LOG2L = @HAVE_DECL_LOG2L@
+HAVE_DECL_LOGB = @HAVE_DECL_LOGB@
+HAVE_DECL_LOGL = @HAVE_DECL_LOGL@
+HAVE_DECL_MEMMEM = @HAVE_DECL_MEMMEM@
+HAVE_DECL_MEMRCHR = @HAVE_DECL_MEMRCHR@
+HAVE_DECL_OBSTACK_PRINTF = @HAVE_DECL_OBSTACK_PRINTF@
+HAVE_DECL_REMAINDER = @HAVE_DECL_REMAINDER@
+HAVE_DECL_REMAINDERL = @HAVE_DECL_REMAINDERL@
+HAVE_DECL_RINTF = @HAVE_DECL_RINTF@
+HAVE_DECL_ROUND = @HAVE_DECL_ROUND@
+HAVE_DECL_ROUNDF = @HAVE_DECL_ROUNDF@
+HAVE_DECL_ROUNDL = @HAVE_DECL_ROUNDL@
+HAVE_DECL_SETENV = @HAVE_DECL_SETENV@
+HAVE_DECL_SETHOSTNAME = @HAVE_DECL_SETHOSTNAME@
+HAVE_DECL_SINL = @HAVE_DECL_SINL@
+HAVE_DECL_SNPRINTF = @HAVE_DECL_SNPRINTF@
+HAVE_DECL_SQRTL = @HAVE_DECL_SQRTL@
+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_TANL = @HAVE_DECL_TANL@
+HAVE_DECL_TRUNC = @HAVE_DECL_TRUNC@
+HAVE_DECL_TRUNCF = @HAVE_DECL_TRUNCF@
+HAVE_DECL_TRUNCL = @HAVE_DECL_TRUNCL@
+HAVE_DECL_TTYNAME_R = @HAVE_DECL_TTYNAME_R@
+HAVE_DECL_UNSETENV = @HAVE_DECL_UNSETENV@
+HAVE_DECL_VSNPRINTF = @HAVE_DECL_VSNPRINTF@
+HAVE_DECL_WCTOB = @HAVE_DECL_WCTOB@
+HAVE_DECL_WCWIDTH = @HAVE_DECL_WCWIDTH@
+HAVE_DIRENT_H = @HAVE_DIRENT_H@
+HAVE_DPRINTF = @HAVE_DPRINTF@
+HAVE_DUP2 = @HAVE_DUP2@
+HAVE_DUP3 = @HAVE_DUP3@
+HAVE_DUPLOCALE = @HAVE_DUPLOCALE@
+HAVE_EUIDACCESS = @HAVE_EUIDACCESS@
+HAVE_EXPF = @HAVE_EXPF@
+HAVE_EXPL = @HAVE_EXPL@
+HAVE_EXPM1 = @HAVE_EXPM1@
+HAVE_EXPM1F = @HAVE_EXPM1F@
+HAVE_FABSF = @HAVE_FABSF@
+HAVE_FABSL = @HAVE_FABSL@
+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_FMA = @HAVE_FMA@
+HAVE_FMAF = @HAVE_FMAF@
+HAVE_FMAL = @HAVE_FMAL@
+HAVE_FMODF = @HAVE_FMODF@
+HAVE_FMODL = @HAVE_FMODL@
+HAVE_FREXPF = @HAVE_FREXPF@
+HAVE_FSEEKO = @HAVE_FSEEKO@
+HAVE_FSTATAT = @HAVE_FSTATAT@
+HAVE_FSYNC = @HAVE_FSYNC@
+HAVE_FTELLO = @HAVE_FTELLO@
+HAVE_FTRUNCATE = @HAVE_FTRUNCATE@
+HAVE_FUTIMENS = @HAVE_FUTIMENS@
+HAVE_GETDTABLESIZE = @HAVE_GETDTABLESIZE@
+HAVE_GETGROUPS = @HAVE_GETGROUPS@
+HAVE_GETHOSTNAME = @HAVE_GETHOSTNAME@
+HAVE_GETLOGIN = @HAVE_GETLOGIN@
+HAVE_GETOPT_H = @HAVE_GETOPT_H@
+HAVE_GETPAGESIZE = @HAVE_GETPAGESIZE@
+HAVE_GETSUBOPT = @HAVE_GETSUBOPT@
+HAVE_GETTIMEOFDAY = @HAVE_GETTIMEOFDAY@
+HAVE_GRANTPT = @HAVE_GRANTPT@
+HAVE_GROUP_MEMBER = @HAVE_GROUP_MEMBER@
+HAVE_HYPOTF = @HAVE_HYPOTF@
+HAVE_HYPOTL = @HAVE_HYPOTL@
+HAVE_ILOGB = @HAVE_ILOGB@
+HAVE_ILOGBF = @HAVE_ILOGBF@
+HAVE_ILOGBL = @HAVE_ILOGBL@
+HAVE_INTTYPES_H = @HAVE_INTTYPES_H@
+HAVE_ISBLANK = @HAVE_ISBLANK@
+HAVE_ISNAND = @HAVE_ISNAND@
+HAVE_ISNANF = @HAVE_ISNANF@
+HAVE_ISNANL = @HAVE_ISNANL@
+HAVE_ISWBLANK = @HAVE_ISWBLANK@
+HAVE_ISWCNTRL = @HAVE_ISWCNTRL@
+HAVE_LANGINFO_CODESET = @HAVE_LANGINFO_CODESET@
+HAVE_LANGINFO_ERA = @HAVE_LANGINFO_ERA@
+HAVE_LANGINFO_H = @HAVE_LANGINFO_H@
+HAVE_LANGINFO_T_FMT_AMPM = @HAVE_LANGINFO_T_FMT_AMPM@
+HAVE_LANGINFO_YESEXPR = @HAVE_LANGINFO_YESEXPR@
+HAVE_LCHMOD = @HAVE_LCHMOD@
+HAVE_LCHOWN = @HAVE_LCHOWN@
+HAVE_LDEXPF = @HAVE_LDEXPF@
+HAVE_LINK = @HAVE_LINK@
+HAVE_LINKAT = @HAVE_LINKAT@
+HAVE_LOG10F = @HAVE_LOG10F@
+HAVE_LOG10L = @HAVE_LOG10L@
+HAVE_LOG1P = @HAVE_LOG1P@
+HAVE_LOG1PF = @HAVE_LOG1PF@
+HAVE_LOG1PL = @HAVE_LOG1PL@
+HAVE_LOGBF = @HAVE_LOGBF@
+HAVE_LOGBL = @HAVE_LOGBL@
+HAVE_LOGF = @HAVE_LOGF@
+HAVE_LOGL = @HAVE_LOGL@
+HAVE_LONG_LONG_INT = @HAVE_LONG_LONG_INT@
+HAVE_LSTAT = @HAVE_LSTAT@
+HAVE_MAX_ALIGN_T = @HAVE_MAX_ALIGN_T@
+HAVE_MBRLEN = @HAVE_MBRLEN@
+HAVE_MBRTOWC = @HAVE_MBRTOWC@
+HAVE_MBSINIT = @HAVE_MBSINIT@
+HAVE_MBSLEN = @HAVE_MBSLEN@
+HAVE_MBSNRTOWCS = @HAVE_MBSNRTOWCS@
+HAVE_MBSRTOWCS = @HAVE_MBSRTOWCS@
+HAVE_MEMCHR = @HAVE_MEMCHR@
+HAVE_MEMPCPY = @HAVE_MEMPCPY@
+HAVE_MKDIRAT = @HAVE_MKDIRAT@
+HAVE_MKDTEMP = @HAVE_MKDTEMP@
+HAVE_MKFIFO = @HAVE_MKFIFO@
+HAVE_MKFIFOAT = @HAVE_MKFIFOAT@
+HAVE_MKNOD = @HAVE_MKNOD@
+HAVE_MKNODAT = @HAVE_MKNODAT@
+HAVE_MKOSTEMP = @HAVE_MKOSTEMP@
+HAVE_MKOSTEMPS = @HAVE_MKOSTEMPS@
+HAVE_MKSTEMP = @HAVE_MKSTEMP@
+HAVE_MKSTEMPS = @HAVE_MKSTEMPS@
+HAVE_MODFF = @HAVE_MODFF@
+HAVE_MODFL = @HAVE_MODFL@
+HAVE_MSVC_INVALID_PARAMETER_HANDLER = @HAVE_MSVC_INVALID_PARAMETER_HANDLER@
+HAVE_NANOSLEEP = @HAVE_NANOSLEEP@
+HAVE_NETINET_IN_H = @HAVE_NETINET_IN_H@
+HAVE_NL_LANGINFO = @HAVE_NL_LANGINFO@
+HAVE_OPENAT = @HAVE_OPENAT@
+HAVE_OPENDIR = @HAVE_OPENDIR@
+HAVE_OS_H = @HAVE_OS_H@
+HAVE_PCLOSE = @HAVE_PCLOSE@
+HAVE_PIPE = @HAVE_PIPE@
+HAVE_PIPE2 = @HAVE_PIPE2@
+HAVE_POPEN = @HAVE_POPEN@
+HAVE_POSIX_OPENPT = @HAVE_POSIX_OPENPT@
+HAVE_POSIX_SIGNALBLOCKING = @HAVE_POSIX_SIGNALBLOCKING@
+HAVE_POWF = @HAVE_POWF@
+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_RAISE = @HAVE_RAISE@
+HAVE_RANDOM = @HAVE_RANDOM@
+HAVE_RANDOM_H = @HAVE_RANDOM_H@
+HAVE_RANDOM_R = @HAVE_RANDOM_R@
+HAVE_RAWMEMCHR = @HAVE_RAWMEMCHR@
+HAVE_READDIR = @HAVE_READDIR@
+HAVE_READLINK = @HAVE_READLINK@
+HAVE_READLINKAT = @HAVE_READLINKAT@
+HAVE_REALPATH = @HAVE_REALPATH@
+HAVE_REMAINDER = @HAVE_REMAINDER@
+HAVE_REMAINDERF = @HAVE_REMAINDERF@
+HAVE_RENAMEAT = @HAVE_RENAMEAT@
+HAVE_REWINDDIR = @HAVE_REWINDDIR@
+HAVE_RINT = @HAVE_RINT@
+HAVE_RINTL = @HAVE_RINTL@
+HAVE_RPMATCH = @HAVE_RPMATCH@
+HAVE_SAME_LONG_DOUBLE_AS_DOUBLE = @HAVE_SAME_LONG_DOUBLE_AS_DOUBLE@
+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_SIGACTION = @HAVE_SIGACTION@
+HAVE_SIGHANDLER_T = @HAVE_SIGHANDLER_T@
+HAVE_SIGINFO_T = @HAVE_SIGINFO_T@
+HAVE_SIGNED_SIG_ATOMIC_T = @HAVE_SIGNED_SIG_ATOMIC_T@
+HAVE_SIGNED_WCHAR_T = @HAVE_SIGNED_WCHAR_T@
+HAVE_SIGNED_WINT_T = @HAVE_SIGNED_WINT_T@
+HAVE_SIGSET_T = @HAVE_SIGSET_T@
+HAVE_SINF = @HAVE_SINF@
+HAVE_SINHF = @HAVE_SINHF@
+HAVE_SINL = @HAVE_SINL@
+HAVE_SLEEP = @HAVE_SLEEP@
+HAVE_SQRTF = @HAVE_SQRTF@
+HAVE_SQRTL = @HAVE_SQRTL@
+HAVE_STDINT_H = @HAVE_STDINT_H@
+HAVE_STPCPY = @HAVE_STPCPY@
+HAVE_STPNCPY = @HAVE_STPNCPY@
+HAVE_STRCASECMP = @HAVE_STRCASECMP@
+HAVE_STRCASESTR = @HAVE_STRCASESTR@
+HAVE_STRCHRNUL = @HAVE_STRCHRNUL@
+HAVE_STRINGS_H = @HAVE_STRINGS_H@
+HAVE_STRPBRK = @HAVE_STRPBRK@
+HAVE_STRPTIME = @HAVE_STRPTIME@
+HAVE_STRSEP = @HAVE_STRSEP@
+HAVE_STRTOD = @HAVE_STRTOD@
+HAVE_STRTOLL = @HAVE_STRTOLL@
+HAVE_STRTOULL = @HAVE_STRTOULL@
+HAVE_STRUCT_RANDOM_DATA = @HAVE_STRUCT_RANDOM_DATA@
+HAVE_STRUCT_SIGACTION_SA_SIGACTION = @HAVE_STRUCT_SIGACTION_SA_SIGACTION@
+HAVE_STRUCT_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_STRUCT_UTSNAME = @HAVE_STRUCT_UTSNAME@
+HAVE_STRVERSCMP = @HAVE_STRVERSCMP@
+HAVE_SYMLINK = @HAVE_SYMLINK@
+HAVE_SYMLINKAT = @HAVE_SYMLINKAT@
+HAVE_SYS_BITYPES_H = @HAVE_SYS_BITYPES_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_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_SYS_UTSNAME_H = @HAVE_SYS_UTSNAME_H@
+HAVE_TANF = @HAVE_TANF@
+HAVE_TANHF = @HAVE_TANHF@
+HAVE_TANL = @HAVE_TANL@
+HAVE_TIMEGM = @HAVE_TIMEGM@
+HAVE_TIMEZONE_T = @HAVE_TIMEZONE_T@
+HAVE_TYPE_VOLATILE_SIG_ATOMIC_T = @HAVE_TYPE_VOLATILE_SIG_ATOMIC_T@
+HAVE_UNAME = @HAVE_UNAME@
+HAVE_UNISTD_H = @HAVE_UNISTD_H@
+HAVE_UNLINKAT = @HAVE_UNLINKAT@
+HAVE_UNLOCKPT = @HAVE_UNLOCKPT@
+HAVE_UNSIGNED_LONG_LONG_INT = @HAVE_UNSIGNED_LONG_LONG_INT@
+HAVE_USLEEP = @HAVE_USLEEP@
+HAVE_UTIMENSAT = @HAVE_UTIMENSAT@
+HAVE_VASPRINTF = @HAVE_VASPRINTF@
+HAVE_VDPRINTF = @HAVE_VDPRINTF@
+HAVE_WCHAR_H = @HAVE_WCHAR_H@
+HAVE_WCHAR_T = @HAVE_WCHAR_T@
+HAVE_WCPCPY = @HAVE_WCPCPY@
+HAVE_WCPNCPY = @HAVE_WCPNCPY@
+HAVE_WCRTOMB = @HAVE_WCRTOMB@
+HAVE_WCSCASECMP = @HAVE_WCSCASECMP@
+HAVE_WCSCAT = @HAVE_WCSCAT@
+HAVE_WCSCHR = @HAVE_WCSCHR@
+HAVE_WCSCMP = @HAVE_WCSCMP@
+HAVE_WCSCOLL = @HAVE_WCSCOLL@
+HAVE_WCSCPY = @HAVE_WCSCPY@
+HAVE_WCSCSPN = @HAVE_WCSCSPN@
+HAVE_WCSDUP = @HAVE_WCSDUP@
+HAVE_WCSLEN = @HAVE_WCSLEN@
+HAVE_WCSNCASECMP = @HAVE_WCSNCASECMP@
+HAVE_WCSNCAT = @HAVE_WCSNCAT@
+HAVE_WCSNCMP = @HAVE_WCSNCMP@
+HAVE_WCSNCPY = @HAVE_WCSNCPY@
+HAVE_WCSNLEN = @HAVE_WCSNLEN@
+HAVE_WCSNRTOMBS = @HAVE_WCSNRTOMBS@
+HAVE_WCSPBRK = @HAVE_WCSPBRK@
+HAVE_WCSRCHR = @HAVE_WCSRCHR@
+HAVE_WCSRTOMBS = @HAVE_WCSRTOMBS@
+HAVE_WCSSPN = @HAVE_WCSSPN@
+HAVE_WCSSTR = @HAVE_WCSSTR@
+HAVE_WCSTOK = @HAVE_WCSTOK@
+HAVE_WCSWIDTH = @HAVE_WCSWIDTH@
+HAVE_WCSXFRM = @HAVE_WCSXFRM@
+HAVE_WCTRANS_T = @HAVE_WCTRANS_T@
+HAVE_WCTYPE_H = @HAVE_WCTYPE_H@
+HAVE_WCTYPE_T = @HAVE_WCTYPE_T@
+HAVE_WINSOCK2_H = @HAVE_WINSOCK2_H@
+HAVE_WINT_T = @HAVE_WINT_T@
+HAVE_WMEMCHR = @HAVE_WMEMCHR@
+HAVE_WMEMCMP = @HAVE_WMEMCMP@
+HAVE_WMEMCPY = @HAVE_WMEMCPY@
+HAVE_WMEMMOVE = @HAVE_WMEMMOVE@
+HAVE_WMEMSET = @HAVE_WMEMSET@
+HAVE_WS2TCPIP_H = @HAVE_WS2TCPIP_H@
+HAVE_XLOCALE_H = @HAVE_XLOCALE_H@
+HAVE__BOOL = @HAVE__BOOL@
+HAVE__EXIT = @HAVE__EXIT@
+INCLUDE_NEXT = @INCLUDE_NEXT@
+INCLUDE_NEXT_AS_FIRST_DIRECTIVE = @INCLUDE_NEXT_AS_FIRST_DIRECTIVE@
+INET_PTON_LIB = @INET_PTON_LIB@
+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@
+ISFINITE_LIBM = @ISFINITE_LIBM@
+ISINF_LIBM = @ISINF_LIBM@
+LDFLAGS = @LDFLAGS@
+LIBGNULIB_LIBDEPS = @LIBGNULIB_LIBDEPS@
+LIBGNULIB_LTLIBDEPS = @LIBGNULIB_LTLIBDEPS@
+LIBICONV = @LIBICONV@
+LIBINTL = @LIBINTL@
+LIBMULTITHREAD = @LIBMULTITHREAD@
+LIBOBJS = @LIBOBJS@
+LIBPTH = @LIBPTH@
+LIBPTH_PREFIX = @LIBPTH_PREFIX@
+LIBS = @LIBS@
+LIBSOCKET = @LIBSOCKET@
+LIBTESTS_LIBDEPS = @LIBTESTS_LIBDEPS@
+LIBTHREAD = @LIBTHREAD@
+LIBUNISTRING_UNITYPES_H = @LIBUNISTRING_UNITYPES_H@
+LIBUNISTRING_UNIWIDTH_H = @LIBUNISTRING_UNIWIDTH_H@
+LIB_CLOCK_GETTIME = @LIB_CLOCK_GETTIME@
+LIB_EACCESS = @LIB_EACCESS@
+LIB_NANOSLEEP = @LIB_NANOSLEEP@
+LIB_SELECT = @LIB_SELECT@
+LIB_SELINUX = @LIB_SELINUX@
+LN_S = @LN_S@
+LOCALCHARSET_TESTS_ENVIRONMENT = @LOCALCHARSET_TESTS_ENVIRONMENT@
+LOCALE_FR = @LOCALE_FR@
+LOCALE_FR_UTF8 = @LOCALE_FR_UTF8@
+LOCALE_JA = @LOCALE_JA@
+LOCALE_TR_UTF8 = @LOCALE_TR_UTF8@
+LOCALE_ZH_CN = @LOCALE_ZH_CN@
+LTLIBICONV = @LTLIBICONV@
+LTLIBINTL = @LTLIBINTL@
+LTLIBMULTITHREAD = @LTLIBMULTITHREAD@
+LTLIBOBJS = @LTLIBOBJS@
+LTLIBPTH = @LTLIBPTH@
+LTLIBTHREAD = @LTLIBTHREAD@
+MAKEINFO = @MAKEINFO@
+MKDIR_P = @MKDIR_P@
+MKINSTALLDIRS = @MKINSTALLDIRS@
+MODF_LIBM = @MODF_LIBM@
+MSGFMT = @MSGFMT@
+MSGFMT_015 = @MSGFMT_015@
+MSGMERGE = @MSGMERGE@
+NETINET_IN_H = @NETINET_IN_H@
+NEXT_ARPA_INET_H = @NEXT_ARPA_INET_H@
+NEXT_AS_FIRST_DIRECTIVE_ARPA_INET_H = @NEXT_AS_FIRST_DIRECTIVE_ARPA_INET_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_FCNTL_H = @NEXT_AS_FIRST_DIRECTIVE_FCNTL_H@
+NEXT_AS_FIRST_DIRECTIVE_FLOAT_H = @NEXT_AS_FIRST_DIRECTIVE_FLOAT_H@
+NEXT_AS_FIRST_DIRECTIVE_GETOPT_H = @NEXT_AS_FIRST_DIRECTIVE_GETOPT_H@
+NEXT_AS_FIRST_DIRECTIVE_INTTYPES_H = @NEXT_AS_FIRST_DIRECTIVE_INTTYPES_H@
+NEXT_AS_FIRST_DIRECTIVE_LANGINFO_H = @NEXT_AS_FIRST_DIRECTIVE_LANGINFO_H@
+NEXT_AS_FIRST_DIRECTIVE_LOCALE_H = @NEXT_AS_FIRST_DIRECTIVE_LOCALE_H@
+NEXT_AS_FIRST_DIRECTIVE_MATH_H = @NEXT_AS_FIRST_DIRECTIVE_MATH_H@
+NEXT_AS_FIRST_DIRECTIVE_NETINET_IN_H = @NEXT_AS_FIRST_DIRECTIVE_NETINET_IN_H@
+NEXT_AS_FIRST_DIRECTIVE_SELINUX_SELINUX_H = @NEXT_AS_FIRST_DIRECTIVE_SELINUX_SELINUX_H@
+NEXT_AS_FIRST_DIRECTIVE_SIGNAL_H = @NEXT_AS_FIRST_DIRECTIVE_SIGNAL_H@
+NEXT_AS_FIRST_DIRECTIVE_STDARG_H = @NEXT_AS_FIRST_DIRECTIVE_STDARG_H@
+NEXT_AS_FIRST_DIRECTIVE_STDDEF_H = @NEXT_AS_FIRST_DIRECTIVE_STDDEF_H@
+NEXT_AS_FIRST_DIRECTIVE_STDINT_H = @NEXT_AS_FIRST_DIRECTIVE_STDINT_H@
+NEXT_AS_FIRST_DIRECTIVE_STDIO_H = @NEXT_AS_FIRST_DIRECTIVE_STDIO_H@
+NEXT_AS_FIRST_DIRECTIVE_STDLIB_H = @NEXT_AS_FIRST_DIRECTIVE_STDLIB_H@
+NEXT_AS_FIRST_DIRECTIVE_STRINGS_H = @NEXT_AS_FIRST_DIRECTIVE_STRINGS_H@
+NEXT_AS_FIRST_DIRECTIVE_STRING_H = @NEXT_AS_FIRST_DIRECTIVE_STRING_H@
+NEXT_AS_FIRST_DIRECTIVE_SYS_IOCTL_H = @NEXT_AS_FIRST_DIRECTIVE_SYS_IOCTL_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_SYS_UTSNAME_H = @NEXT_AS_FIRST_DIRECTIVE_SYS_UTSNAME_H@
+NEXT_AS_FIRST_DIRECTIVE_SYS_WAIT_H = @NEXT_AS_FIRST_DIRECTIVE_SYS_WAIT_H@
+NEXT_AS_FIRST_DIRECTIVE_TIME_H = @NEXT_AS_FIRST_DIRECTIVE_TIME_H@
+NEXT_AS_FIRST_DIRECTIVE_UNISTD_H = @NEXT_AS_FIRST_DIRECTIVE_UNISTD_H@
+NEXT_AS_FIRST_DIRECTIVE_WCHAR_H = @NEXT_AS_FIRST_DIRECTIVE_WCHAR_H@
+NEXT_AS_FIRST_DIRECTIVE_WCTYPE_H = @NEXT_AS_FIRST_DIRECTIVE_WCTYPE_H@
+NEXT_CTYPE_H = @NEXT_CTYPE_H@
+NEXT_DIRENT_H = @NEXT_DIRENT_H@
+NEXT_ERRNO_H = @NEXT_ERRNO_H@
+NEXT_FCNTL_H = @NEXT_FCNTL_H@
+NEXT_FLOAT_H = @NEXT_FLOAT_H@
+NEXT_GETOPT_H = @NEXT_GETOPT_H@
+NEXT_INTTYPES_H = @NEXT_INTTYPES_H@
+NEXT_LANGINFO_H = @NEXT_LANGINFO_H@
+NEXT_LOCALE_H = @NEXT_LOCALE_H@
+NEXT_MATH_H = @NEXT_MATH_H@
+NEXT_NETINET_IN_H = @NEXT_NETINET_IN_H@
+NEXT_SELINUX_SELINUX_H = @NEXT_SELINUX_SELINUX_H@
+NEXT_SIGNAL_H = @NEXT_SIGNAL_H@
+NEXT_STDARG_H = @NEXT_STDARG_H@
+NEXT_STDDEF_H = @NEXT_STDDEF_H@
+NEXT_STDINT_H = @NEXT_STDINT_H@
+NEXT_STDIO_H = @NEXT_STDIO_H@
+NEXT_STDLIB_H = @NEXT_STDLIB_H@
+NEXT_STRINGS_H = @NEXT_STRINGS_H@
+NEXT_STRING_H = @NEXT_STRING_H@
+NEXT_SYS_IOCTL_H = @NEXT_SYS_IOCTL_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_SYS_UTSNAME_H = @NEXT_SYS_UTSNAME_H@
+NEXT_SYS_WAIT_H = @NEXT_SYS_WAIT_H@
+NEXT_TIME_H = @NEXT_TIME_H@
+NEXT_UNISTD_H = @NEXT_UNISTD_H@
+NEXT_WCHAR_H = @NEXT_WCHAR_H@
+NEXT_WCTYPE_H = @NEXT_WCTYPE_H@
+OBJEXT = @OBJEXT@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+POSUB = @POSUB@
+PRAGMA_COLUMNS = @PRAGMA_COLUMNS@
+PRAGMA_SYSTEM_HEADER = @PRAGMA_SYSTEM_HEADER@
+PRIPTR_PREFIX = @PRIPTR_PREFIX@
+PRI_MACROS_BROKEN = @PRI_MACROS_BROKEN@
+PTHREAD_H_DEFINES_STRUCT_TIMESPEC = @PTHREAD_H_DEFINES_STRUCT_TIMESPEC@
+PTRDIFF_T_SUFFIX = @PTRDIFF_T_SUFFIX@
+PYTHON = @PYTHON@
+PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
+PYTHON_PLATFORM = @PYTHON_PLATFORM@
+PYTHON_PREFIX = @PYTHON_PREFIX@
+PYTHON_VERSION = @PYTHON_VERSION@
+RANLIB = @RANLIB@
+REPLACE_BTOWC = @REPLACE_BTOWC@
+REPLACE_CALLOC = @REPLACE_CALLOC@
+REPLACE_CANONICALIZE_FILE_NAME = @REPLACE_CANONICALIZE_FILE_NAME@
+REPLACE_CBRTF = @REPLACE_CBRTF@
+REPLACE_CBRTL = @REPLACE_CBRTL@
+REPLACE_CEIL = @REPLACE_CEIL@
+REPLACE_CEILF = @REPLACE_CEILF@
+REPLACE_CEILL = @REPLACE_CEILL@
+REPLACE_CHOWN = @REPLACE_CHOWN@
+REPLACE_CLOSE = @REPLACE_CLOSE@
+REPLACE_CLOSEDIR = @REPLACE_CLOSEDIR@
+REPLACE_DIRFD = @REPLACE_DIRFD@
+REPLACE_DPRINTF = @REPLACE_DPRINTF@
+REPLACE_DUP = @REPLACE_DUP@
+REPLACE_DUP2 = @REPLACE_DUP2@
+REPLACE_DUPLOCALE = @REPLACE_DUPLOCALE@
+REPLACE_EXP2 = @REPLACE_EXP2@
+REPLACE_EXP2L = @REPLACE_EXP2L@
+REPLACE_EXPM1 = @REPLACE_EXPM1@
+REPLACE_EXPM1F = @REPLACE_EXPM1F@
+REPLACE_FABSL = @REPLACE_FABSL@
+REPLACE_FCHOWNAT = @REPLACE_FCHOWNAT@
+REPLACE_FCLOSE = @REPLACE_FCLOSE@
+REPLACE_FCNTL = @REPLACE_FCNTL@
+REPLACE_FDOPEN = @REPLACE_FDOPEN@
+REPLACE_FDOPENDIR = @REPLACE_FDOPENDIR@
+REPLACE_FFLUSH = @REPLACE_FFLUSH@
+REPLACE_FLOOR = @REPLACE_FLOOR@
+REPLACE_FLOORF = @REPLACE_FLOORF@
+REPLACE_FLOORL = @REPLACE_FLOORL@
+REPLACE_FMA = @REPLACE_FMA@
+REPLACE_FMAF = @REPLACE_FMAF@
+REPLACE_FMAL = @REPLACE_FMAL@
+REPLACE_FMOD = @REPLACE_FMOD@
+REPLACE_FMODF = @REPLACE_FMODF@
+REPLACE_FMODL = @REPLACE_FMODL@
+REPLACE_FOPEN = @REPLACE_FOPEN@
+REPLACE_FPRINTF = @REPLACE_FPRINTF@
+REPLACE_FPURGE = @REPLACE_FPURGE@
+REPLACE_FREOPEN = @REPLACE_FREOPEN@
+REPLACE_FREXP = @REPLACE_FREXP@
+REPLACE_FREXPF = @REPLACE_FREXPF@
+REPLACE_FREXPL = @REPLACE_FREXPL@
+REPLACE_FSEEK = @REPLACE_FSEEK@
+REPLACE_FSEEKO = @REPLACE_FSEEKO@
+REPLACE_FSTAT = @REPLACE_FSTAT@
+REPLACE_FSTATAT = @REPLACE_FSTATAT@
+REPLACE_FTELL = @REPLACE_FTELL@
+REPLACE_FTELLO = @REPLACE_FTELLO@
+REPLACE_FTRUNCATE = @REPLACE_FTRUNCATE@
+REPLACE_FUTIMENS = @REPLACE_FUTIMENS@
+REPLACE_GETCWD = @REPLACE_GETCWD@
+REPLACE_GETDELIM = @REPLACE_GETDELIM@
+REPLACE_GETDOMAINNAME = @REPLACE_GETDOMAINNAME@
+REPLACE_GETDTABLESIZE = @REPLACE_GETDTABLESIZE@
+REPLACE_GETGROUPS = @REPLACE_GETGROUPS@
+REPLACE_GETLINE = @REPLACE_GETLINE@
+REPLACE_GETLOGIN_R = @REPLACE_GETLOGIN_R@
+REPLACE_GETPAGESIZE = @REPLACE_GETPAGESIZE@
+REPLACE_GETTIMEOFDAY = @REPLACE_GETTIMEOFDAY@
+REPLACE_GMTIME = @REPLACE_GMTIME@
+REPLACE_HUGE_VAL = @REPLACE_HUGE_VAL@
+REPLACE_HYPOT = @REPLACE_HYPOT@
+REPLACE_HYPOTF = @REPLACE_HYPOTF@
+REPLACE_HYPOTL = @REPLACE_HYPOTL@
+REPLACE_ILOGB = @REPLACE_ILOGB@
+REPLACE_ILOGBF = @REPLACE_ILOGBF@
+REPLACE_INET_NTOP = @REPLACE_INET_NTOP@
+REPLACE_INET_PTON = @REPLACE_INET_PTON@
+REPLACE_IOCTL = @REPLACE_IOCTL@
+REPLACE_ISATTY = @REPLACE_ISATTY@
+REPLACE_ISFINITE = @REPLACE_ISFINITE@
+REPLACE_ISINF = @REPLACE_ISINF@
+REPLACE_ISNAN = @REPLACE_ISNAN@
+REPLACE_ISWBLANK = @REPLACE_ISWBLANK@
+REPLACE_ISWCNTRL = @REPLACE_ISWCNTRL@
+REPLACE_ITOLD = @REPLACE_ITOLD@
+REPLACE_LCHOWN = @REPLACE_LCHOWN@
+REPLACE_LDEXPL = @REPLACE_LDEXPL@
+REPLACE_LINK = @REPLACE_LINK@
+REPLACE_LINKAT = @REPLACE_LINKAT@
+REPLACE_LOCALECONV = @REPLACE_LOCALECONV@
+REPLACE_LOCALTIME = @REPLACE_LOCALTIME@
+REPLACE_LOCALTIME_R = @REPLACE_LOCALTIME_R@
+REPLACE_LOG = @REPLACE_LOG@
+REPLACE_LOG10 = @REPLACE_LOG10@
+REPLACE_LOG10F = @REPLACE_LOG10F@
+REPLACE_LOG10L = @REPLACE_LOG10L@
+REPLACE_LOG1P = @REPLACE_LOG1P@
+REPLACE_LOG1PF = @REPLACE_LOG1PF@
+REPLACE_LOG1PL = @REPLACE_LOG1PL@
+REPLACE_LOG2 = @REPLACE_LOG2@
+REPLACE_LOG2F = @REPLACE_LOG2F@
+REPLACE_LOG2L = @REPLACE_LOG2L@
+REPLACE_LOGB = @REPLACE_LOGB@
+REPLACE_LOGBF = @REPLACE_LOGBF@
+REPLACE_LOGBL = @REPLACE_LOGBL@
+REPLACE_LOGF = @REPLACE_LOGF@
+REPLACE_LOGL = @REPLACE_LOGL@
+REPLACE_LSEEK = @REPLACE_LSEEK@
+REPLACE_LSTAT = @REPLACE_LSTAT@
+REPLACE_MALLOC = @REPLACE_MALLOC@
+REPLACE_MBRLEN = @REPLACE_MBRLEN@
+REPLACE_MBRTOWC = @REPLACE_MBRTOWC@
+REPLACE_MBSINIT = @REPLACE_MBSINIT@
+REPLACE_MBSNRTOWCS = @REPLACE_MBSNRTOWCS@
+REPLACE_MBSRTOWCS = @REPLACE_MBSRTOWCS@
+REPLACE_MBSTATE_T = @REPLACE_MBSTATE_T@
+REPLACE_MBTOWC = @REPLACE_MBTOWC@
+REPLACE_MEMCHR = @REPLACE_MEMCHR@
+REPLACE_MEMMEM = @REPLACE_MEMMEM@
+REPLACE_MKDIR = @REPLACE_MKDIR@
+REPLACE_MKFIFO = @REPLACE_MKFIFO@
+REPLACE_MKNOD = @REPLACE_MKNOD@
+REPLACE_MKSTEMP = @REPLACE_MKSTEMP@
+REPLACE_MKTIME = @REPLACE_MKTIME@
+REPLACE_MODF = @REPLACE_MODF@
+REPLACE_MODFF = @REPLACE_MODFF@
+REPLACE_MODFL = @REPLACE_MODFL@
+REPLACE_NAN = @REPLACE_NAN@
+REPLACE_NANOSLEEP = @REPLACE_NANOSLEEP@
+REPLACE_NL_LANGINFO = @REPLACE_NL_LANGINFO@
+REPLACE_NULL = @REPLACE_NULL@
+REPLACE_OBSTACK_PRINTF = @REPLACE_OBSTACK_PRINTF@
+REPLACE_OPEN = @REPLACE_OPEN@
+REPLACE_OPENAT = @REPLACE_OPENAT@
+REPLACE_OPENDIR = @REPLACE_OPENDIR@
+REPLACE_PERROR = @REPLACE_PERROR@
+REPLACE_POPEN = @REPLACE_POPEN@
+REPLACE_PREAD = @REPLACE_PREAD@
+REPLACE_PRINTF = @REPLACE_PRINTF@
+REPLACE_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_R = @REPLACE_RANDOM_R@
+REPLACE_READ = @REPLACE_READ@
+REPLACE_READLINK = @REPLACE_READLINK@
+REPLACE_READLINKAT = @REPLACE_READLINKAT@
+REPLACE_REALLOC = @REPLACE_REALLOC@
+REPLACE_REALPATH = @REPLACE_REALPATH@
+REPLACE_REMAINDER = @REPLACE_REMAINDER@
+REPLACE_REMAINDERF = @REPLACE_REMAINDERF@
+REPLACE_REMAINDERL = @REPLACE_REMAINDERL@
+REPLACE_REMOVE = @REPLACE_REMOVE@
+REPLACE_RENAME = @REPLACE_RENAME@
+REPLACE_RENAMEAT = @REPLACE_RENAMEAT@
+REPLACE_RMDIR = @REPLACE_RMDIR@
+REPLACE_ROUND = @REPLACE_ROUND@
+REPLACE_ROUNDF = @REPLACE_ROUNDF@
+REPLACE_ROUNDL = @REPLACE_ROUNDL@
+REPLACE_SELECT = @REPLACE_SELECT@
+REPLACE_SETENV = @REPLACE_SETENV@
+REPLACE_SETLOCALE = @REPLACE_SETLOCALE@
+REPLACE_SIGNBIT = @REPLACE_SIGNBIT@
+REPLACE_SIGNBIT_USING_GCC = @REPLACE_SIGNBIT_USING_GCC@
+REPLACE_SLEEP = @REPLACE_SLEEP@
+REPLACE_SNPRINTF = @REPLACE_SNPRINTF@
+REPLACE_SPRINTF = @REPLACE_SPRINTF@
+REPLACE_SQRTL = @REPLACE_SQRTL@
+REPLACE_STAT = @REPLACE_STAT@
+REPLACE_STDIO_READ_FUNCS = @REPLACE_STDIO_READ_FUNCS@
+REPLACE_STDIO_WRITE_FUNCS = @REPLACE_STDIO_WRITE_FUNCS@
+REPLACE_STPNCPY = @REPLACE_STPNCPY@
+REPLACE_STRCASESTR = @REPLACE_STRCASESTR@
+REPLACE_STRCHRNUL = @REPLACE_STRCHRNUL@
+REPLACE_STRDUP = @REPLACE_STRDUP@
+REPLACE_STRERROR = @REPLACE_STRERROR@
+REPLACE_STRERROR_R = @REPLACE_STRERROR_R@
+REPLACE_STRNCAT = @REPLACE_STRNCAT@
+REPLACE_STRNDUP = @REPLACE_STRNDUP@
+REPLACE_STRNLEN = @REPLACE_STRNLEN@
+REPLACE_STRSIGNAL = @REPLACE_STRSIGNAL@
+REPLACE_STRSTR = @REPLACE_STRSTR@
+REPLACE_STRTOD = @REPLACE_STRTOD@
+REPLACE_STRTOIMAX = @REPLACE_STRTOIMAX@
+REPLACE_STRTOK_R = @REPLACE_STRTOK_R@
+REPLACE_STRTOUMAX = @REPLACE_STRTOUMAX@
+REPLACE_STRUCT_LCONV = @REPLACE_STRUCT_LCONV@
+REPLACE_STRUCT_TIMEVAL = @REPLACE_STRUCT_TIMEVAL@
+REPLACE_SYMLINK = @REPLACE_SYMLINK@
+REPLACE_SYMLINKAT = @REPLACE_SYMLINKAT@
+REPLACE_TIMEGM = @REPLACE_TIMEGM@
+REPLACE_TMPFILE = @REPLACE_TMPFILE@
+REPLACE_TOWLOWER = @REPLACE_TOWLOWER@
+REPLACE_TRUNC = @REPLACE_TRUNC@
+REPLACE_TRUNCF = @REPLACE_TRUNCF@
+REPLACE_TRUNCL = @REPLACE_TRUNCL@
+REPLACE_TTYNAME_R = @REPLACE_TTYNAME_R@
+REPLACE_UNLINK = @REPLACE_UNLINK@
+REPLACE_UNLINKAT = @REPLACE_UNLINKAT@
+REPLACE_UNSETENV = @REPLACE_UNSETENV@
+REPLACE_USLEEP = @REPLACE_USLEEP@
+REPLACE_UTIMENSAT = @REPLACE_UTIMENSAT@
+REPLACE_VASPRINTF = @REPLACE_VASPRINTF@
+REPLACE_VDPRINTF = @REPLACE_VDPRINTF@
+REPLACE_VFPRINTF = @REPLACE_VFPRINTF@
+REPLACE_VPRINTF = @REPLACE_VPRINTF@
+REPLACE_VSNPRINTF = @REPLACE_VSNPRINTF@
+REPLACE_VSPRINTF = @REPLACE_VSPRINTF@
+REPLACE_WCRTOMB = @REPLACE_WCRTOMB@
+REPLACE_WCSNRTOMBS = @REPLACE_WCSNRTOMBS@
+REPLACE_WCSRTOMBS = @REPLACE_WCSRTOMBS@
+REPLACE_WCSWIDTH = @REPLACE_WCSWIDTH@
+REPLACE_WCTOB = @REPLACE_WCTOB@
+REPLACE_WCTOMB = @REPLACE_WCTOMB@
+REPLACE_WCWIDTH = @REPLACE_WCWIDTH@
+REPLACE_WRITE = @REPLACE_WRITE@
+SED = @SED@
+SELINUX_CONTEXT_H = @SELINUX_CONTEXT_H@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+SIG_ATOMIC_T_SUFFIX = @SIG_ATOMIC_T_SUFFIX@
+SIZE_T_SUFFIX = @SIZE_T_SUFFIX@
+SORT = @SORT@
+SORT_SUPPORTS_Z = @SORT_SUPPORTS_Z@
+STDALIGN_H = @STDALIGN_H@
+STDARG_H = @STDARG_H@
+STDBOOL_H = @STDBOOL_H@
+STDDEF_H = @STDDEF_H@
+STDINT_H = @STDINT_H@
+STRIP = @STRIP@
+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@
+TIME_H_DEFINES_STRUCT_TIMESPEC = @TIME_H_DEFINES_STRUCT_TIMESPEC@
+TRUNC_LIBM = @TRUNC_LIBM@
+UINT32_MAX_LT_UINTMAX_MAX = @UINT32_MAX_LT_UINTMAX_MAX@
+UINT64_MAX_EQ_ULONG_MAX = @UINT64_MAX_EQ_ULONG_MAX@
+UNDEFINE_STRTOK_R = @UNDEFINE_STRTOK_R@
+UNISTD_H_DEFINES_STRUCT_TIMESPEC = @UNISTD_H_DEFINES_STRUCT_TIMESPEC@
+UNISTD_H_HAVE_WINSOCK2_H = @UNISTD_H_HAVE_WINSOCK2_H@
+UNISTD_H_HAVE_WINSOCK2_H_AND_USE_SOCKETS = @UNISTD_H_HAVE_WINSOCK2_H_AND_USE_SOCKETS@
+USE_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@
+WINT_T_SUFFIX = @WINT_T_SUFFIX@
+XGETTEXT = @XGETTEXT@
+XGETTEXT_015 = @XGETTEXT_015@
+XGETTEXT_EXTRA_OPTIONS = @XGETTEXT_EXTRA_OPTIONS@
+YACC = @YACC@
+YFLAGS = @YFLAGS@
+YIELD_LIB = @YIELD_LIB@
+abs_aux_dir = @abs_aux_dir@
+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_RANLIB = @ac_ct_RANLIB@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+gl_LIBOBJS = @gl_LIBOBJS@
+gl_LTLIBOBJS = @gl_LTLIBOBJS@
+gltests_LIBOBJS = @gltests_LIBOBJS@
+gltests_LTLIBOBJS = @gltests_LTLIBOBJS@
+gltests_WITNESS = @gltests_WITNESS@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+lispdir = @lispdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+pkgpyexecdir = @pkgpyexecdir@
+pkgpythondir = @pkgpythondir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+pyexecdir = @pyexecdir@
+pythondir = @pythondir@
+runstatedir = @runstatedir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+AUTOMAKE_OPTIONS = dejagnu parallel-tests
+FIND = ../find
+FINDFLAGS =
+DEJATOOL = find
+EXTRA_DIST_XO = \
+find.gnu/access.xo \
+find.gnu/comma.xo \
+find.gnu/delete.xo \
+find.gnu/deletedir.xo \
+find.gnu/deletefile.xo \
+find.gnu/depth.xo \
+find.gnu/depth-d.xo \
+find.gnu/empty.xo \
+find.gnu/execdir-hier.xo \
+find.gnu/execdir-multiple.xo \
+find.gnu/execdir-one.xo \
+find.gnu/execdir-root-only.xo \
+find.gnu/exec-many-rtn-failure.xo \
+find.gnu/exec-many-rtn-success.xo \
+find.gnu/exec-one-rtn-fail.xo \
+find.gnu/exec-one-rtn-success.xo \
+find.gnu/false.xo \
+find.gnu/follow-arg-parent-symlink.xo \
+find.gnu/follow-basic.xo \
+find.gnu/fprint0_stdout.xo \
+find.gnu/gnuand.xo \
+find.gnu/gnunot.xo \
+find.gnu/gnu-or.xo \
+find.gnu/ilname.xo \
+find.gnu/iname.xo \
+find.gnu/inum.xo \
+find.gnu/ipath.xo \
+find.gnu/iregex1.xo \
+find.gnu/iwholename.xo \
+find.gnu/lname.xo \
+find.gnu/mindepth-arg.xo \
+find.gnu/name-opt.xo \
+find.gnu/name-period.xo \
+find.gnu/name-slash.xo \
+find.gnu/no-fdleak-test.xo \
+find.gnu/path.xo \
+find.gnu/print_stdout.xo \
+find.gnu/perm.xo \
+find.gnu/perm000.xo \
+find.gnu/perm-slash.xo \
+find.gnu/posix-dflt.xo \
+find.gnu/posix-h.xo \
+find.gnu/posix-l.xo \
+find.gnu/printfHdfl.xo \
+find.gnu/printf-nonlocal-symlink.xo \
+find.gnu/printf-slash.xo \
+find.gnu/printf-symlink.xo \
+find.gnu/printf-h.xo \
+find.gnu/printf.xo \
+find.gnu/print0.xo \
+find.gnu/prune-default-print.xo \
+find.gnu/regex1.xo \
+find.gnu/regex2.xo \
+find.gnu/samefile-copy.xo \
+find.gnu/samefile-link.xo \
+find.gnu/samefile-p-brokenlink.xo \
+find.gnu/samefile-same.xo \
+find.gnu/samefile-symlink.xo \
+find.gnu/sv-bug-17782.xo \
+find.gnu/sv-bug-18222.xo \
+find.gnu/sv-bug-27563-execdir.xo \
+find.gnu/true.xo \
+find.gnu/wholename.xo \
+find.gnu/xtype-symlink.xo \
+find.gnu/quit.xo \
+find.gnu/xtype.xo \
+find.posix/and.xo \
+find.posix/depth1.xo \
+find.posix/dotdotfiles.xo \
+find.posix/exec-nogaps.xo \
+find.posix/exec-one.xo \
+find.posix/files-not-expressions1.xo \
+find.posix/files-not-expressions2.xo \
+find.posix/files-not-expressions3.xo \
+find.posix/grouping.xo \
+find.posix/links.xo \
+find.posix/sv-bug-11175.xo \
+find.posix/sv-bug-12181.xo \
+find.posix/sv-bug-25359.xo \
+find.posix/sv-bug-27563-exec.xo \
+find.posix/mtime0.xo \
+find.posix/sizes.xo \
+find.posix/name.xo \
+find.posix/nameslash.xo \
+find.posix/parent.xo \
+find.posix/perm-X.xo \
+find.posix/perm-vanilla.xo \
+find.posix/posixnot.xo \
+find.posix/prune.xo \
+find.posix/prune-result.xo \
+find.posix/prune-stat.xo \
+find.posix/sizetype.xo \
+find.posix/sv-bug-15235.xo \
+find.posix/sv-bug-19613.xo \
+find.posix/typesize.xo
+
+EXTRA_DIST_EXP = \
+config/unix.exp \
+find.gnu/access.exp \
+find.gnu/comma.exp \
+find.gnu/delete.exp \
+find.gnu/deletedir.exp \
+find.gnu/deletefile.exp \
+find.gnu/depth.exp \
+find.gnu/depth-d.exp \
+find.gnu/empty.exp \
+find.gnu/execdir-hier.exp \
+find.gnu/execdir-in-unreadable.exp \
+find.gnu/execdir-multiple.exp \
+find.gnu/execdir-one.exp \
+find.gnu/execdir-pwd.exp \
+find.gnu/execdir-pwd1.exp \
+find.gnu/execdir-root-only.exp \
+find.gnu/exec-many-rtn-failure.exp \
+find.gnu/exec-many-rtn-success.exp \
+find.gnu/exec-one-rtn-fail.exp \
+find.gnu/exec-one-rtn-success.exp \
+find.gnu/false.exp \
+find.gnu/follow-arg-parent-symlink.exp \
+find.gnu/follow-basic.exp \
+find.gnu/fprint0_stdout.exp \
+find.gnu/fprintf-samefile.exp \
+find.gnu/fprint-unwritable.exp \
+find.gnu/gnuand.exp \
+find.gnu/gnunot.exp \
+find.gnu/gnu-or.exp \
+find.gnu/ilname.exp \
+find.gnu/iname.exp \
+find.gnu/inum.exp \
+find.gnu/ipath.exp \
+find.gnu/iregex1.exp \
+find.gnu/iwholename.exp \
+find.gnu/lname.exp \
+find.gnu/mindepth-arg.exp \
+find.gnu/mindepth-badarg.exp \
+find.gnu/name-opt.exp \
+find.gnu/name-period.exp \
+find.gnu/name-slash.exp \
+find.gnu/no-fdleak-test.exp \
+find.posix/parent.exp \
+find.gnu/path.exp \
+find.gnu/print_stdout.exp \
+find.gnu/print0.exp \
+find.gnu/perm.exp \
+find.gnu/perm000.exp \
+find.gnu/perm-slash.exp \
+find.gnu/posix-dflt.exp \
+find.gnu/posix-h.exp \
+find.gnu/posix-l.exp \
+find.gnu/posix-perminvalid.exp \
+find.gnu/printfHdfl.exp \
+find.gnu/printf.exp \
+find.gnu/printf-nonlocal-symlink.exp \
+find.gnu/printf-slash.exp \
+find.gnu/printf-symlink.exp \
+find.gnu/printf-h.exp \
+find.gnu/printf-reserved.exp \
+find.gnu/prune-default-print.exp \
+find.gnu/regex1.exp \
+find.gnu/regex2.exp \
+find.gnu/samefile-copy.exp \
+find.gnu/samefile-link.exp \
+find.gnu/samefile-missing.exp \
+find.gnu/samefile-p-brokenlink.exp \
+find.gnu/samefile-same.exp \
+find.gnu/samefile-symlink.exp \
+find.gnu/true.exp \
+find.gnu/wholename.exp \
+find.gnu/xtype-symlink.exp \
+find.gnu/sv-bug-12230.exp \
+find.gnu/sv-bug-17477.exp \
+find.gnu/sv-bug-17490.exp \
+find.gnu/sv-bug-17782.exp \
+find.gnu/sv-bug-18222.exp \
+find.gnu/sv-bug-24169.exp \
+find.gnu/sv-bug-27563-execdir.exp \
+find.gnu/quit.exp \
+find.gnu/used-invarg.exp \
+find.gnu/used-missing.exp \
+find.gnu/user-invalid.exp \
+find.gnu/xtype.exp \
+find.posix/and.exp \
+find.posix/bracket-depth.exp \
+find.posix/depth1.exp \
+find.posix/dotdotfiles.exp \
+find.posix/empty-parens.exp \
+find.posix/exec-nogaps.exp \
+find.posix/exec-one.exp \
+find.posix/files-not-expressions1.exp \
+find.posix/files-not-expressions2.exp \
+find.posix/files-not-expressions3.exp \
+find.posix/grouping.exp \
+find.posix/group-empty.exp \
+find.posix/group-missing.exp \
+find.posix/links.exp \
+find.posix/mtime0.exp \
+find.posix/sv-bug-11175.exp \
+find.posix/sv-bug-12181.exp \
+find.posix/sv-bug-25359.exp \
+find.posix/sv-bug-27563-exec.exp \
+find.posix/sv-bug-30777.exp \
+find.posix/sizes.exp \
+find.posix/name.exp \
+find.posix/nameslash.exp \
+find.posix/name-missing.exp \
+find.posix/perm-X.exp \
+find.posix/perm-vanilla.exp \
+find.posix/posixnot.exp \
+find.posix/prune.exp \
+find.posix/prune-result.exp \
+find.posix/prune-stat.exp \
+find.posix/size-invalid.exp \
+find.posix/size-missing.exp \
+find.posix/sizetype.exp \
+find.posix/typearg.exp \
+find.posix/sv-bug-15235.exp \
+find.posix/sv-bug-19605.exp \
+find.posix/sv-bug-19613.exp \
+find.posix/sv-bug-19617.exp \
+find.posix/typesize.exp \
+find.posix/user-empty.exp \
+find.posix/user-missing.exp
+
+EXTRA_DIST_GOLDEN = \
+ test_escapechars.golden
+
+test_shell_progs = \
+sv-bug-32043.sh \
+test_escapechars.sh \
+test_escape_c.sh \
+test_inode.sh \
+sv-34079.sh \
+sv-34976-execdir-fd-leak.sh
+
+EXTRA_DIST = $(EXTRA_DIST_EXP) $(EXTRA_DIST_XO) $(EXTRA_DIST_GOLDEN) \
+ $(test_shell_progs) binary_locations.sh checklists.py
+
+CLEANFILES = *.log *.sum site.exp site.bak configured-testfiles.txt
+
+#DIST_SUBDIRS = config
+TESTS = $(test_shell_progs)
+TEST_EXTENSIONS = .sh .py
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .log .py .py$(EXEEXT) .sh .sh$(EXEEXT) .trs
+$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnits find/testsuite/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --gnits find/testsuite/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+tags TAGS:
+
+ctags CTAGS:
+
+cscope cscopelist:
+
+
+check-DEJAGNU: site.exp
+ srcdir='$(srcdir)'; export srcdir; \
+ EXPECT=$(EXPECT); export EXPECT; \
+ if $(SHELL) -c "$(RUNTEST) --version" > /dev/null 2>&1; then \
+ exit_status=0; l='$(DEJATOOL)'; for tool in $$l; do \
+ if $(RUNTEST) $(AM_RUNTESTFLAGS) $(RUNTESTDEFAULTFLAGS) $(RUNTESTFLAGS); \
+ then :; else exit_status=1; fi; \
+ done; \
+ else echo "WARNING: could not find '$(RUNTEST)'" 1>&2; :;\
+ fi; \
+ exit $$exit_status
+site.exp: Makefile $(EXTRA_DEJAGNU_SITE_CONFIG)
+ @echo 'Making a new site.exp file ...'
+ @echo '## these variables are automatically generated by make ##' >site.tmp
+ @echo '# Do not edit here. If you wish to override these values' >>site.tmp
+ @echo '# edit the last section' >>site.tmp
+ @echo 'set srcdir "$(srcdir)"' >>site.tmp
+ @echo "set objdir `pwd`" >>site.tmp
+ @echo 'set build_alias "$(build_alias)"' >>site.tmp
+ @echo 'set build_triplet $(build_triplet)' >>site.tmp
+ @echo 'set host_alias "$(host_alias)"' >>site.tmp
+ @echo 'set host_triplet $(host_triplet)' >>site.tmp
+ @list='$(EXTRA_DEJAGNU_SITE_CONFIG)'; for f in $$list; do \
+ echo "## Begin content included from file $$f. Do not modify. ##" \
+ && cat `test -f "$$f" || echo '$(srcdir)/'`$$f \
+ && echo "## End content included from file $$f. ##" \
+ || exit 1; \
+ done >> site.tmp
+ @echo "## End of auto-generated content; you can edit from here. ##" >> site.tmp
+ @if test -f site.exp; then \
+ sed -e '1,/^## End of auto-generated content.*##/d' site.exp >> site.tmp; \
+ fi
+ @-rm -f site.bak
+ @test ! -f site.exp || mv site.exp site.bak
+ @mv site.tmp site.exp
+
+distclean-DEJAGNU:
+ -rm -f site.exp site.bak
+ -l='$(DEJATOOL)'; for tool in $$l; do \
+ rm -f $$tool.sum $$tool.log; \
+ done
+
+# Recover from deleted '.trs' file; this should ensure that
+# "rm -f foo.log; make foo.trs" re-run 'foo.test', and re-create
+# both 'foo.log' and 'foo.trs'. Break the recipe in two subshells
+# to avoid problems with "make -n".
+.log.trs:
+ rm -f $< $@
+ $(MAKE) $(AM_MAKEFLAGS) $<
+
+# Leading 'am--fnord' is there to ensure the list of targets does not
+# expand to empty, as could happen e.g. with make check TESTS=''.
+am--fnord $(TEST_LOGS) $(TEST_LOGS:.log=.trs): $(am__force_recheck)
+am--force-recheck:
+ @:
+
+$(TEST_SUITE_LOG): $(TEST_LOGS)
+ @$(am__set_TESTS_bases); \
+ am__f_ok () { test -f "$$1" && test -r "$$1"; }; \
+ redo_bases=`for i in $$bases; do \
+ am__f_ok $$i.trs && am__f_ok $$i.log || echo $$i; \
+ done`; \
+ if test -n "$$redo_bases"; then \
+ redo_logs=`for i in $$redo_bases; do echo $$i.log; done`; \
+ redo_results=`for i in $$redo_bases; do echo $$i.trs; done`; \
+ if $(am__make_dryrun); then :; else \
+ rm -f $$redo_logs && rm -f $$redo_results || exit 1; \
+ fi; \
+ fi; \
+ if test -n "$$am__remaking_logs"; then \
+ echo "fatal: making $(TEST_SUITE_LOG): possible infinite" \
+ "recursion detected" >&2; \
+ else \
+ am__remaking_logs=yes $(MAKE) $(AM_MAKEFLAGS) $$redo_logs; \
+ fi; \
+ if $(am__make_dryrun); then :; else \
+ st=0; \
+ errmsg="fatal: making $(TEST_SUITE_LOG): failed to create"; \
+ for i in $$redo_bases; do \
+ test -f $$i.trs && test -r $$i.trs \
+ || { echo "$$errmsg $$i.trs" >&2; st=1; }; \
+ test -f $$i.log && test -r $$i.log \
+ || { echo "$$errmsg $$i.log" >&2; st=1; }; \
+ done; \
+ test $$st -eq 0 || exit 1; \
+ fi
+ @$(am__sh_e_setup); $(am__tty_colors); $(am__set_TESTS_bases); \
+ ws='[ ]'; \
+ results=`for b in $$bases; do echo $$b.trs; done`; \
+ test -n "$$results" || results=/dev/null; \
+ all=` grep "^$$ws*:test-result:" $$results | wc -l`; \
+ pass=` grep "^$$ws*:test-result:$$ws*PASS" $$results | wc -l`; \
+ fail=` grep "^$$ws*:test-result:$$ws*FAIL" $$results | wc -l`; \
+ skip=` grep "^$$ws*:test-result:$$ws*SKIP" $$results | wc -l`; \
+ xfail=`grep "^$$ws*:test-result:$$ws*XFAIL" $$results | wc -l`; \
+ xpass=`grep "^$$ws*:test-result:$$ws*XPASS" $$results | wc -l`; \
+ error=`grep "^$$ws*:test-result:$$ws*ERROR" $$results | wc -l`; \
+ if test `expr $$fail + $$xpass + $$error` -eq 0; then \
+ success=true; \
+ else \
+ success=false; \
+ fi; \
+ br='==================='; br=$$br$$br$$br$$br; \
+ result_count () \
+ { \
+ if test x"$$1" = x"--maybe-color"; then \
+ maybe_colorize=yes; \
+ elif test x"$$1" = x"--no-color"; then \
+ maybe_colorize=no; \
+ else \
+ echo "$@: invalid 'result_count' usage" >&2; exit 4; \
+ fi; \
+ shift; \
+ desc=$$1 count=$$2; \
+ if test $$maybe_colorize = yes && test $$count -gt 0; then \
+ color_start=$$3 color_end=$$std; \
+ else \
+ color_start= color_end=; \
+ fi; \
+ echo "$${color_start}# $$desc $$count$${color_end}"; \
+ }; \
+ create_testsuite_report () \
+ { \
+ result_count $$1 "TOTAL:" $$all "$$brg"; \
+ result_count $$1 "PASS: " $$pass "$$grn"; \
+ result_count $$1 "SKIP: " $$skip "$$blu"; \
+ result_count $$1 "XFAIL:" $$xfail "$$lgn"; \
+ result_count $$1 "FAIL: " $$fail "$$red"; \
+ result_count $$1 "XPASS:" $$xpass "$$red"; \
+ result_count $$1 "ERROR:" $$error "$$mgn"; \
+ }; \
+ { \
+ echo "$(PACKAGE_STRING): $(subdir)/$(TEST_SUITE_LOG)" | \
+ $(am__rst_title); \
+ create_testsuite_report --no-color; \
+ echo; \
+ echo ".. contents:: :depth: 2"; \
+ echo; \
+ for b in $$bases; do echo $$b; done \
+ | $(am__create_global_log); \
+ } >$(TEST_SUITE_LOG).tmp || exit 1; \
+ mv $(TEST_SUITE_LOG).tmp $(TEST_SUITE_LOG); \
+ if $$success; then \
+ col="$$grn"; \
+ else \
+ col="$$red"; \
+ test x"$$VERBOSE" = x || cat $(TEST_SUITE_LOG); \
+ fi; \
+ echo "$${col}$$br$${std}"; \
+ echo "$${col}Testsuite summary for $(PACKAGE_STRING)$${std}"; \
+ echo "$${col}$$br$${std}"; \
+ create_testsuite_report --maybe-color; \
+ echo "$$col$$br$$std"; \
+ if $$success; then :; else \
+ echo "$${col}See $(subdir)/$(TEST_SUITE_LOG)$${std}"; \
+ if test -n "$(PACKAGE_BUGREPORT)"; then \
+ echo "$${col}Please report to $(PACKAGE_BUGREPORT)$${std}"; \
+ fi; \
+ echo "$$col$$br$$std"; \
+ fi; \
+ $$success || exit 1
+
+check-TESTS:
+ @list='$(RECHECK_LOGS)'; test -z "$$list" || rm -f $$list
+ @list='$(RECHECK_LOGS:.log=.trs)'; test -z "$$list" || rm -f $$list
+ @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
+ @set +e; $(am__set_TESTS_bases); \
+ log_list=`for i in $$bases; do echo $$i.log; done`; \
+ trs_list=`for i in $$bases; do echo $$i.trs; done`; \
+ log_list=`echo $$log_list`; trs_list=`echo $$trs_list`; \
+ $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) TEST_LOGS="$$log_list"; \
+ exit $$?;
+recheck: all
+ @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
+ @set +e; $(am__set_TESTS_bases); \
+ bases=`for i in $$bases; do echo $$i; done \
+ | $(am__list_recheck_tests)` || exit 1; \
+ log_list=`for i in $$bases; do echo $$i.log; done`; \
+ log_list=`echo $$log_list`; \
+ $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) \
+ am__force_recheck=am--force-recheck \
+ TEST_LOGS="$$log_list"; \
+ exit $$?
+.sh.log:
+ @p='$<'; \
+ $(am__set_b); \
+ $(am__check_pre) $(SH_LOG_DRIVER) --test-name "$$f" \
+ --log-file $$b.log --trs-file $$b.trs \
+ $(am__common_driver_flags) $(AM_SH_LOG_DRIVER_FLAGS) $(SH_LOG_DRIVER_FLAGS) -- $(SH_LOG_COMPILE) \
+ "$$tst" $(AM_TESTS_FD_REDIRECT)
+@am__EXEEXT_TRUE@.sh$(EXEEXT).log:
+@am__EXEEXT_TRUE@ @p='$<'; \
+@am__EXEEXT_TRUE@ $(am__set_b); \
+@am__EXEEXT_TRUE@ $(am__check_pre) $(SH_LOG_DRIVER) --test-name "$$f" \
+@am__EXEEXT_TRUE@ --log-file $$b.log --trs-file $$b.trs \
+@am__EXEEXT_TRUE@ $(am__common_driver_flags) $(AM_SH_LOG_DRIVER_FLAGS) $(SH_LOG_DRIVER_FLAGS) -- $(SH_LOG_COMPILE) \
+@am__EXEEXT_TRUE@ "$$tst" $(AM_TESTS_FD_REDIRECT)
+.py.log:
+ @p='$<'; \
+ $(am__set_b); \
+ $(am__check_pre) $(PY_LOG_DRIVER) --test-name "$$f" \
+ --log-file $$b.log --trs-file $$b.trs \
+ $(am__common_driver_flags) $(AM_PY_LOG_DRIVER_FLAGS) $(PY_LOG_DRIVER_FLAGS) -- $(PY_LOG_COMPILE) \
+ "$$tst" $(AM_TESTS_FD_REDIRECT)
+@am__EXEEXT_TRUE@.py$(EXEEXT).log:
+@am__EXEEXT_TRUE@ @p='$<'; \
+@am__EXEEXT_TRUE@ $(am__set_b); \
+@am__EXEEXT_TRUE@ $(am__check_pre) $(PY_LOG_DRIVER) --test-name "$$f" \
+@am__EXEEXT_TRUE@ --log-file $$b.log --trs-file $$b.trs \
+@am__EXEEXT_TRUE@ $(am__common_driver_flags) $(AM_PY_LOG_DRIVER_FLAGS) $(PY_LOG_DRIVER_FLAGS) -- $(PY_LOG_COMPILE) \
+@am__EXEEXT_TRUE@ "$$tst" $(AM_TESTS_FD_REDIRECT)
+
+distdir: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d "$(distdir)/$$file"; then \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+ else \
+ test -f "$(distdir)/$$file" \
+ || cp -p $$d/$$file "$(distdir)/$$file" \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+ $(MAKE) $(AM_MAKEFLAGS) check-DEJAGNU check-TESTS check-local
+check: check-am
+all-am: Makefile
+installdirs:
+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:
+ -test -z "$(TEST_LOGS)" || rm -f $(TEST_LOGS)
+ -test -z "$(TEST_LOGS:.log=.trs)" || rm -f $(TEST_LOGS:.log=.trs)
+ -test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
+
+clean-generic:
+ -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+ -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-generic mostlyclean-am
+
+distclean: distclean-am
+ -rm -f Makefile
+distclean-am: clean-am distclean-DEJAGNU distclean-generic
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am:
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-generic
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am:
+
+.MAKE: check-am install-am install-strip
+
+.PHONY: all all-am check check-DEJAGNU check-TESTS check-am \
+ check-local clean clean-generic cscopelist-am ctags-am \
+ distclean distclean-DEJAGNU distclean-generic distdir dvi \
+ dvi-am html html-am info info-am install install-am \
+ install-data install-data-am install-dvi install-dvi-am \
+ install-exec install-exec-am install-html install-html-am \
+ install-info install-info-am install-man install-pdf \
+ install-pdf-am install-ps install-ps-am install-strip \
+ installcheck installcheck-am installdirs maintainer-clean \
+ maintainer-clean-generic mostlyclean mostlyclean-generic pdf \
+ pdf-am ps ps-am recheck tags-am uninstall uninstall-am
+
+
+check-local: checklists
+
+configured-testfiles.txt: Makefile
+ @echo Generating $@
+ @( cd $(srcdir) && ls $(EXTRA_DIST_XO) && ls $(EXTRA_DIST_EXP) ) >| $@
+
+.PHONY: checklists
+
+checklists: configured-testfiles.txt Makefile
+ $(PYTHON) $(srcdir)/checklists.py configured-testfiles.txt $(srcdir) config find.gnu find.posix
+
+# 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/find/testsuite/binary_locations.sh b/find/testsuite/binary_locations.sh
new file mode 100644
index 0000000..a7775cb
--- /dev/null
+++ b/find/testsuite/binary_locations.sh
@@ -0,0 +1,34 @@
+# Source this file, don't execute it.
+#
+# Copyright (C) 2011-2015 Free Software Foundation, Inc.
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+
+if [ -z "${testname}" ]; then
+ echo 'Please set $testname before sourcing binary_locations.sh.' >&2
+ exit 1
+fi
+
+parent="$(cd .. && pwd)"
+if [ -f "${parent}/ftsfind" ]; then
+ ftsfind="${parent}/ftsfind"
+ oldfind="${parent}/find"
+elif [ -f "${parent}/oldfind" ]; then
+ ftsfind="${parent}/find"
+ oldfind="${parent}/oldfind"
+else
+ echo "Cannot find the executables to test." >&2
+ exit 1
+fi
diff --git a/find/testsuite/checklists.py b/find/testsuite/checklists.py
new file mode 100644
index 0000000..8552249
--- /dev/null
+++ b/find/testsuite/checklists.py
@@ -0,0 +1,107 @@
+# Copyright (C) 2014, 2015 Free Software Foundation, Inc.
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+"""Check that the list of test files in Makefile.am is complete and not redundant.
+
+Usage:
+ checklists file-listing-configured-files test-root subdir-1-containing-tests [subdir-2-containing-tests ...]
+"""
+
+import os
+import os.path
+import re
+import sys
+
+def report_unlisted(filename):
+ sys.stderr.write(
+ 'Error: test file %s is not listed in Makefile.am but exists on disk.\n'
+ % (filename,))
+
+
+def report_missing(filename):
+ sys.stderr.write(
+ 'Error: test file %s is listed in Makefile.am but does not exist on disk.\n'
+ % (filename,))
+
+def report_dupe(filename):
+ sys.stderr.write(
+ 'Error: test file %s is listed more than once in Makefile.am.\n'
+ % (filename,))
+
+
+def report_problems(problem_filenames, reporting_function):
+ for f in problem_filenames:
+ reporting_function(f)
+ return len(problem_filenames)
+
+
+def file_names(listfile_name):
+ for line in open(listfile_name, 'r').readlines():
+ yield line.rstrip('\n')
+
+
+def configured_file_names(listfile_name):
+ dupes = set()
+ result = set()
+ for filename in file_names(listfile_name):
+ if filename in result:
+ dupes.add(filename)
+ else:
+ result.add(filename)
+ return dupes, result
+
+
+def find_test_files(roots):
+ testfile_rx = re.compile(r'\.(exp|xo)$')
+ for root in roots:
+ for parent, dirs, files in os.walk(root):
+ for file_basename in files:
+ if testfile_rx.search(file_basename):
+ yield os.path.join(parent, file_basename)
+
+
+class TemporaryWorkingDirectory(object):
+
+ def __init__(self, cwd):
+ self.new_cwd = cwd
+ self.old_cwd = os.getcwd()
+
+ def __enter__(self):
+ os.chdir(self.new_cwd)
+
+ def __exit__(self, *unused_args):
+ os.chdir(self.old_cwd)
+
+
+def main(args):
+ if len(args) < 3:
+ sys.stderr.write(__doc__)
+ return 1
+ dupes, configured = configured_file_names(args[1])
+ with TemporaryWorkingDirectory(args[2]):
+ actual = set(find_test_files(args[3:]))
+ sys.stdout.write('%d test files configured for find, %s files on-disk'
+ % (len(configured), len(actual)))
+ problem_count = 0
+ problem_count += report_problems(dupes, report_dupe)
+ problem_count += report_problems(configured - actual, report_missing)
+ problem_count += report_problems(actual - configured, report_unlisted)
+ if problem_count:
+ return 1
+ else:
+ return 0
+
+if __name__ == '__main__':
+ sys.exit(main(sys.argv))
diff --git a/find/testsuite/config/unix.exp b/find/testsuite/config/unix.exp
new file mode 100644
index 0000000..dca3ea9
--- /dev/null
+++ b/find/testsuite/config/unix.exp
@@ -0,0 +1,306 @@
+# -*- TCL -*-
+# Test-specific TCL procedures required by DejaGNU.
+# Copyright (C) 2000, 2003, 2004, 2005, 2006, 2010, 2011 Free Software
+# Foundation, Inc.
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+# Modified by Kevin Dalley <kevind@rahul.net> from the xargs files.
+# Modified by David MacKenzie <djm@gnu.ai.mit.edu> from the gcc files
+# written by Rob Savoye <rob@cygnus.com>.
+
+
+global OLDFIND
+global FTSFIND
+
+verbose "base_dir is $base_dir" 2
+global env;
+set env(GNU_FINDUTILS_FD_LEAK_CHECK) "1"
+
+# look for OLDFIND and FTSFIND
+if { ![info exists OLDFIND] || ![info exists FTSFIND] } {
+ verbose "Searching for oldfind"
+ set dir "$base_dir/.."
+
+ set objfile "ftsfind.o"
+ if ![file exists "$dir/$objfile"] then {
+ error "dir is $dir, but I cannot see $objfile in that directory"
+ }
+ set OLDFIND [findfile $dir/oldfind $dir/oldfind [transform oldfind]]
+ set FTSFIND [findfile $dir/find $dir/find [transform find ]]
+}
+
+verbose "ftsfind is at $FTSFIND" 2
+verbose "oldfind is at $OLDFIND" 2
+
+if { [ string equal $FTSFIND $OLDFIND ] } {
+ error "OLDFIND and FTSFIND are set to $FTSFIND, which can't be right"
+}
+
+if [file exists $FTSFIND] then {
+ if [file exists $OLDFIND] then {
+ verbose "FTSFIND=$FTSFIND and OLDFIND=$OLDFIND both exist." 2
+ } else {
+ error "OLDFIND=$OLDFIND, but that program does not exist"
+ }
+} else {
+ error "FTSFIND=$FTSFIND, but that program does not exist (base_dir is $base_dir)"
+}
+
+
+global FINDFLAGS
+if ![info exists FINDFLAGS] then {
+ set FINDFLAGS ""
+}
+
+# Called by runtest.
+# Extract and print the version number of find.
+proc find_version {} {
+ global FTSFIND
+ global FINDFLAGS
+
+ if {[which $FTSFIND] != 0} then {
+ set tmp [ eval exec $FTSFIND $FINDFLAGS --version </dev/null | sed 1q ]
+ clone_output $tmp
+ } else {
+ warning "$FTSFIND, program does not exist"
+ }
+}
+
+# Run find
+# Called by individual test scripts.
+proc do_find_start { suffix findprogram flags passfail options infile output } {
+ global verbose
+
+ set scriptname [uplevel {info script}]
+ set testbase [file rootname $scriptname]
+
+
+ if { [string match "f*" $passfail] } {
+ set fail_good 1
+ } else {
+ if { [string match "p*" $passfail] } {
+ set fail_good 0
+ } else {
+ if { [string match "xf*" $passfail] } {
+ setup_xfail "*-*-*"
+ set fail_good 1
+ } else {
+ if { [string match "xp*" $passfail] } {
+ setup_xfail "*-*-*"
+ set fail_good 0
+ } else {
+ # badly formed
+ untested "Badly defined test"
+ error "The first argument to find_start was $passfail but it should begin with p (pass) or f (fail) or xf (should fail but we know it passes) or xp (should pass but we know it fails)"
+ }
+ }
+ }
+ }
+
+ set test [file tail $testbase]
+ set testname "$test.$suffix"
+
+ # set compareprog "cmp"
+ set compareprog "diff -u"
+
+ set tmpout ""
+ if { $output != "" } {
+ error "The output option is not supported yet"
+ }
+
+ set outfile "$testbase.xo"
+ if {$infile != ""} then {
+ set infile "[file dirname [file dirname $testbase]]/inputs/$infile"
+ } else {
+ set infile /dev/null
+ }
+
+ set cmd "$findprogram $flags $options < $infile > find.out.uns"
+ send_log "$cmd\n"
+ if $verbose>1 then {
+ send_user "Spawning \"$cmd\"\n"
+ }
+
+ if $fail_good then {
+ send_log "Hoping for this command to return nonzero\n"
+ } else {
+ send_log "Hoping for this command to return 0\n"
+ }
+ set failed [ catch "exec $cmd" result ]
+ send_log "return value is $failed, result is '$result'\n"
+ if $failed {
+ # The command failed.
+ if $fail_good then {
+ send_log "As expected, $cmd returned nonzero\n"
+ } else {
+ fail "$testname, $result"
+ }
+ } else {
+ # The command returned 0.
+ if $fail_good then {
+ fail "$testname, $result"
+ } else {
+ send_log "As expected, $cmd returned 0\n"
+ }
+ }
+
+ exec sort < find.out.uns > find.out
+ file delete find.out.uns
+
+ if [file exists $outfile] then {
+ # We use the 'sort' above to sort the output of find to ensure
+ # that the directory entries appear in a predictable order.
+ # Because in the general case the person compiling and running
+ # "make check" will have a different collating order to the
+ # maintainer, we can't guarantee that our "correct" answer
+ # is already sorted in the correct order. To avoid trying
+ # to figure out how to select a POSIX environment on a
+ # random system, we just sort the data again here, using
+ # the local user's environment.
+ exec sort < $outfile > cmp.out
+ set cmp_cmd "$compareprog find.out cmp.out"
+
+ send_log "$cmp_cmd\n"
+ catch "exec $cmp_cmd" cmpout
+ if {$cmpout != ""} then {
+ fail "$testname, standard output differs from the expected result:\n$cmpout"
+ return
+ }
+ } else {
+ if {[file size find.out] != 0} then {
+ fail "$testname, output should be empty"
+ return
+ }
+ }
+ pass "$testname"
+}
+
+proc optimisation_levels_to_test {} {
+ global OPTIMISATION_LEVELS
+ if [info exists OPTIMISATION_LEVELS] {
+ send_log "Running find at optimisation levels $OPTIMISATION_LEVELS\n"
+ return $OPTIMISATION_LEVELS
+ } else {
+ send_log "Running find at default optimisation levels\n"
+ return {0 1 2 3}
+ }
+}
+
+proc find_start { passfail options {infile ""} {output ""} {setup ""}} {
+ global OLDFIND
+ global FTSFIND
+ global FINDFLAGS
+ global SKIP_OLD
+ global SKIP_NEW
+
+ if {$infile != ""} then {
+ set msg "Did not expect infile parameter to be set"
+ untested $msg
+ error $msg
+ }
+
+ if {[which $FTSFIND] == 0} then {
+ error "$FTSFIND, program does not exist"
+ exit 1
+ }
+ if {[which $OLDFIND] == 0} then {
+ error "$OLDFIND, program does not exist"
+ exit 1
+ }
+
+ # Now run the test with each binary, once with each optimisation level.
+ foreach optlevel [optimisation_levels_to_test] {
+ set flags "$FINDFLAGS -O$optlevel"
+ if { ![info exists SKIP_OLD] || ! $SKIP_OLD } {
+ eval $setup
+ do_find_start old-O$optlevel $OLDFIND $flags $passfail $options $infile $output
+ }
+ if { ![info exists SKIP_NEW] || !$SKIP_NEW } {
+ eval $setup
+ do_find_start new-O$optlevel $FTSFIND $flags $passfail $options $infile $output
+ }
+ }
+}
+
+# Called by runtest.
+# Clean up (remove temporary files) before runtest exits.
+proc find_exit {} {
+ catch "exec rm -f find.out cmp.out"
+}
+
+proc path_setting_is_unsafe {} {
+ global env;
+ set itemlist [ split $env(PATH) : ]
+ foreach item $itemlist {
+ if { [ string equal $item "" ] } {
+ return 1;
+ }
+ if { [ string equal $item "." ] } {
+ return 1;
+ }
+ if { ! [ string match "/*" $item ] } {
+ # not an absolute path element.
+ return 1
+ }
+ }
+ return 0;
+}
+
+proc touch args {
+ foreach filename $args {
+ set f [open "$filename" "a"]
+ close $f
+ }
+}
+
+proc mkdir { dirname } {
+ # Not all versions of Tcl offer 'file mkdir'.
+ set failed [ catch "file mkdir $dirname" result ]
+ if $failed {
+ # Fall back on the external command.
+ send_log "file mkdir does not work, falling back on exec mkdir\n"
+ exec mkdir "$dirname"
+ }
+}
+
+
+proc safe_path [ ] {
+ if { [ path_setting_is_unsafe ] } {
+ warning { Cannot perform test as your $PATH environment variable includes a reference to the current directory or a directory name which is not absolute }
+ untested { skipping this test because your $PATH variable is wrongly set }
+ return 0
+ } else {
+ return 1
+ }
+}
+
+
+proc fs_superuser [ ] {
+ set tmpfile "tmp000"
+ exec rm -f $tmpfile
+ touch $tmpfile
+ exec chmod 000 $tmpfile
+ set retval 0
+
+ if [ file readable $tmpfile ] {
+ # On Cygwin, a user with admin rights can read all files, and
+ # access(foo,R_OK) correctly returns 1 for all files.
+ warning "You have superuser privileges, skipping this test."
+ untested {skipping this test because you have superuser privileges}
+ set retval 1
+ }
+ exec rm -f $tmpfile
+ return $retval
+}
diff --git a/find/testsuite/find.gnu/access.exp b/find/testsuite/find.gnu/access.exp
new file mode 100644
index 0000000..c6308b9
--- /dev/null
+++ b/find/testsuite/find.gnu/access.exp
@@ -0,0 +1,14 @@
+# tests for -readable, -writable, -executable
+exec rm -rf tmp
+exec mkdir tmp
+if { ! [ fs_superuser ] } {
+ touch tmp/x tmp/w tmp/r tmp/rw tmp/rwx tmp/0
+ exec chmod 400 tmp/r
+ exec chmod 200 tmp/w
+ exec chmod 100 tmp/x
+ exec chmod 000 tmp/0
+ exec chmod 600 tmp/rw
+ exec chmod 700 tmp/rwx
+ find_start p {tmp -readable -printf "r %p\n" , -writable -printf "w %p\n" , -executable -printf "x %p\n"}
+ exec rm -rf tmp
+}
diff --git a/find/testsuite/find.gnu/access.xo b/find/testsuite/find.gnu/access.xo
new file mode 100644
index 0000000..464957d
--- /dev/null
+++ b/find/testsuite/find.gnu/access.xo
@@ -0,0 +1,11 @@
+r tmp
+r tmp/r
+r tmp/rw
+r tmp/rwx
+w tmp
+w tmp/rw
+w tmp/rwx
+w tmp/w
+x tmp
+x tmp/rwx
+x tmp/x
diff --git a/find/testsuite/find.gnu/comma.exp b/find/testsuite/find.gnu/comma.exp
new file mode 100644
index 0000000..07a768b
--- /dev/null
+++ b/find/testsuite/find.gnu/comma.exp
@@ -0,0 +1 @@
+find_start p {. -maxdepth 2 -false , -name .}
diff --git a/find/testsuite/find.gnu/comma.xo b/find/testsuite/find.gnu/comma.xo
new file mode 100644
index 0000000..9c558e3
--- /dev/null
+++ b/find/testsuite/find.gnu/comma.xo
@@ -0,0 +1 @@
+.
diff --git a/find/testsuite/find.gnu/delete.exp b/find/testsuite/find.gnu/delete.exp
new file mode 100644
index 0000000..f748321
--- /dev/null
+++ b/find/testsuite/find.gnu/delete.exp
@@ -0,0 +1,7 @@
+global FTSFIND
+global FINDFLAGS
+exec rm -rf tmp
+exec mkdir tmp tmp/top tmp/top/one tmp/top/one/foo tmp/top/two
+eval exec $FTSFIND tmp $FINDFLAGS -path tmp/top/two -delete
+find_start p {tmp -print }
+exec rm -rf tmp
diff --git a/find/testsuite/find.gnu/delete.xo b/find/testsuite/find.gnu/delete.xo
new file mode 100644
index 0000000..c84cffb
--- /dev/null
+++ b/find/testsuite/find.gnu/delete.xo
@@ -0,0 +1,4 @@
+tmp
+tmp/top
+tmp/top/one
+tmp/top/one/foo
diff --git a/find/testsuite/find.gnu/deletedir.exp b/find/testsuite/find.gnu/deletedir.exp
new file mode 100644
index 0000000..8809747
--- /dev/null
+++ b/find/testsuite/find.gnu/deletedir.exp
@@ -0,0 +1,9 @@
+global FTSFIND
+global FINDFLAGS
+exec rm -rf tmp
+exec mkdir tmp tmp/top
+proc createdir {} {
+ exec mkdir tmp/top/dir
+}
+find_start p {tmp -path tmp/top/dir -delete -print} "" "" createdir
+exec rm -rf tmp
diff --git a/find/testsuite/find.gnu/deletedir.xo b/find/testsuite/find.gnu/deletedir.xo
new file mode 100644
index 0000000..9f0155f
--- /dev/null
+++ b/find/testsuite/find.gnu/deletedir.xo
@@ -0,0 +1 @@
+tmp/top/dir
diff --git a/find/testsuite/find.gnu/deletefile.exp b/find/testsuite/find.gnu/deletefile.exp
new file mode 100644
index 0000000..552cf67
--- /dev/null
+++ b/find/testsuite/find.gnu/deletefile.exp
@@ -0,0 +1,9 @@
+global FTSFIND
+global FINDFLAGS
+exec rm -rf tmp
+exec mkdir tmp tmp/top
+proc touchfile {} {
+ exec touch tmp/top/file
+}
+find_start p {tmp -path tmp/top/file -delete -print} "" "" touchfile
+exec rm -rf tmp
diff --git a/find/testsuite/find.gnu/deletefile.xo b/find/testsuite/find.gnu/deletefile.xo
new file mode 100644
index 0000000..425c112
--- /dev/null
+++ b/find/testsuite/find.gnu/deletefile.xo
@@ -0,0 +1 @@
+tmp/top/file
diff --git a/find/testsuite/find.gnu/depth-d.exp b/find/testsuite/find.gnu/depth-d.exp
new file mode 100644
index 0000000..8e264a8
--- /dev/null
+++ b/find/testsuite/find.gnu/depth-d.exp
@@ -0,0 +1,8 @@
+exec rm -rf tmp
+exec mkdir tmp
+exec mkdir tmp/top
+exec mkdir tmp/top/one
+exec touch tmp/top/one/foo
+exec mkdir tmp/top/two
+find_start p {tmp/top -d -mindepth 1 -type d -empty -print}
+# exec rm -rf tmp
diff --git a/find/testsuite/find.gnu/depth-d.xo b/find/testsuite/find.gnu/depth-d.xo
new file mode 100644
index 0000000..e5f6986
--- /dev/null
+++ b/find/testsuite/find.gnu/depth-d.xo
@@ -0,0 +1 @@
+tmp/top/two
diff --git a/find/testsuite/find.gnu/depth.exp b/find/testsuite/find.gnu/depth.exp
new file mode 100644
index 0000000..d4913b2
--- /dev/null
+++ b/find/testsuite/find.gnu/depth.exp
@@ -0,0 +1,8 @@
+exec rm -rf tmp
+exec mkdir tmp
+exec mkdir tmp/top
+exec mkdir tmp/top/one
+exec touch tmp/top/one/foo
+exec mkdir tmp/top/two
+find_start p {tmp/top -depth -mindepth 1 -type d -empty -print}
+exec rm -rf tmp
diff --git a/find/testsuite/find.gnu/depth.xo b/find/testsuite/find.gnu/depth.xo
new file mode 100644
index 0000000..e5f6986
--- /dev/null
+++ b/find/testsuite/find.gnu/depth.xo
@@ -0,0 +1 @@
+tmp/top/two
diff --git a/find/testsuite/find.gnu/empty.exp b/find/testsuite/find.gnu/empty.exp
new file mode 100644
index 0000000..78f94d7
--- /dev/null
+++ b/find/testsuite/find.gnu/empty.exp
@@ -0,0 +1,7 @@
+# tests for -empty
+exec rm -rf tmp
+exec mkdir tmp
+exec true > tmp/empty
+exec echo > tmp/notempty
+find_start p { tmp -type f -empty }
+exec rm -rf tmp
diff --git a/find/testsuite/find.gnu/empty.xo b/find/testsuite/find.gnu/empty.xo
new file mode 100644
index 0000000..f352040
--- /dev/null
+++ b/find/testsuite/find.gnu/empty.xo
@@ -0,0 +1 @@
+tmp/empty \ No newline at end of file
diff --git a/find/testsuite/find.gnu/exec-many-rtn-failure.exp b/find/testsuite/find.gnu/exec-many-rtn-failure.exp
new file mode 100644
index 0000000..463f8e2
--- /dev/null
+++ b/find/testsuite/find.gnu/exec-many-rtn-failure.exp
@@ -0,0 +1,4 @@
+# POSIX: If the invoked command fails, -exec still returns true if it
+# was punctuated with +, because that always returns true. However,
+# the program as a whole should return a NON-zero exit status.
+find_start f { /tmp -exec false \{\} + -printf "yep\n" -quit }
diff --git a/find/testsuite/find.gnu/exec-many-rtn-failure.xo b/find/testsuite/find.gnu/exec-many-rtn-failure.xo
new file mode 100644
index 0000000..3b6f27e
--- /dev/null
+++ b/find/testsuite/find.gnu/exec-many-rtn-failure.xo
@@ -0,0 +1 @@
+yep
diff --git a/find/testsuite/find.gnu/exec-many-rtn-success.exp b/find/testsuite/find.gnu/exec-many-rtn-success.exp
new file mode 100644
index 0000000..142929f
--- /dev/null
+++ b/find/testsuite/find.gnu/exec-many-rtn-success.exp
@@ -0,0 +1,4 @@
+# POSIX: If the invoked command succeeds, -exec should return true if
+# it was punctuated with +, because that always returns true. However,
+# the program as a whole should also return a zero exit status.
+find_start p { /tmp -exec true \{\} + -printf "yep\n" -quit }
diff --git a/find/testsuite/find.gnu/exec-many-rtn-success.xo b/find/testsuite/find.gnu/exec-many-rtn-success.xo
new file mode 100644
index 0000000..3b6f27e
--- /dev/null
+++ b/find/testsuite/find.gnu/exec-many-rtn-success.xo
@@ -0,0 +1 @@
+yep
diff --git a/find/testsuite/find.gnu/exec-one-rtn-fail.exp b/find/testsuite/find.gnu/exec-one-rtn-fail.exp
new file mode 100644
index 0000000..b761d1d
--- /dev/null
+++ b/find/testsuite/find.gnu/exec-one-rtn-fail.exp
@@ -0,0 +1,4 @@
+# If -exec \; fails, it should return false. The return
+# value of find should stil; be 0, unless another error has
+# happened.
+find_start p { /tmp -exec false \; -o \( -printf "yep\n" -quit \) }
diff --git a/find/testsuite/find.gnu/exec-one-rtn-fail.xo b/find/testsuite/find.gnu/exec-one-rtn-fail.xo
new file mode 100644
index 0000000..3b6f27e
--- /dev/null
+++ b/find/testsuite/find.gnu/exec-one-rtn-fail.xo
@@ -0,0 +1 @@
+yep
diff --git a/find/testsuite/find.gnu/exec-one-rtn-success.exp b/find/testsuite/find.gnu/exec-one-rtn-success.exp
new file mode 100644
index 0000000..d3c8b99
--- /dev/null
+++ b/find/testsuite/find.gnu/exec-one-rtn-success.exp
@@ -0,0 +1,3 @@
+# POSIX: If the invoked command succeeds, -exec should return true if
+# it was punctuated with ;
+find_start p { /tmp -exec true \; -printf "yep\n" -quit }
diff --git a/find/testsuite/find.gnu/exec-one-rtn-success.xo b/find/testsuite/find.gnu/exec-one-rtn-success.xo
new file mode 100644
index 0000000..3b6f27e
--- /dev/null
+++ b/find/testsuite/find.gnu/exec-one-rtn-success.xo
@@ -0,0 +1 @@
+yep
diff --git a/find/testsuite/find.gnu/execdir-hier.exp b/find/testsuite/find.gnu/execdir-hier.exp
new file mode 100644
index 0000000..59d877b
--- /dev/null
+++ b/find/testsuite/find.gnu/execdir-hier.exp
@@ -0,0 +1,8 @@
+# tests for -execdir ... \+
+# Specifically, ensure that output for separate directoires is not mixed.
+if { [ safe_path ] } {
+ exec rm -rf tmp
+ exec mkdir tmp tmp/two
+ find_start p { tmp -execdir echo \{\} \+ }
+ exec rm -rf tmp
+}
diff --git a/find/testsuite/find.gnu/execdir-hier.xo b/find/testsuite/find.gnu/execdir-hier.xo
new file mode 100644
index 0000000..d9fc49d
--- /dev/null
+++ b/find/testsuite/find.gnu/execdir-hier.xo
@@ -0,0 +1,2 @@
+./tmp
+./two
diff --git a/find/testsuite/find.gnu/execdir-in-unreadable.exp b/find/testsuite/find.gnu/execdir-in-unreadable.exp
new file mode 100644
index 0000000..fe78d5a
--- /dev/null
+++ b/find/testsuite/find.gnu/execdir-in-unreadable.exp
@@ -0,0 +1,11 @@
+# tests for -execdir ... \+ in a directory which is not readable
+if { [ safe_path ] } {
+ exec rm -rf tmp
+ exec mkdir tmp
+ exec chmod 755 tmp
+ exec mkdir tmp/sub
+ exec chmod 300 tmp/sub
+ find_start p { tmp -maxdepth 1 -execdir true \{\} \+ }
+ exec chmod 700 tmp/sub
+ exec rm -rf tmp
+}
diff --git a/find/testsuite/find.gnu/execdir-multiple.exp b/find/testsuite/find.gnu/execdir-multiple.exp
new file mode 100644
index 0000000..f292fff
--- /dev/null
+++ b/find/testsuite/find.gnu/execdir-multiple.exp
@@ -0,0 +1,58 @@
+# tests for -execdir ... \+
+
+# Create 4 empty files in each of 6 directories.
+# Also create a shell script in each of those 6 directories.
+# Run a find command which runs the shell script for each empty file.
+# Check to make sure that each file is mentioned exactly once, and that
+# the command was run with the correct working directory.
+#
+# The output is a sequence of lines of this form:
+#
+# cwd ./basename
+#
+# cmd is the basename of the current directory at the time the command
+# is run by -execidr. ./basename is the name of the file that was matched
+# (that is, it's the value passed in {}).
+
+# $body is the body of a shell script we use for testing.
+# It prints a series of lines of the form described above.
+# One line is printed for each command-line argument.
+set body {#! /bin/sh
+set -e
+here=`pwd`
+d=`basename $here`
+
+for arg;
+do
+ echo "$d" "$arg"
+done | LC_ALL=C sort
+}
+
+
+if { [ safe_path ] } {
+ global SKIP_OLD
+
+ exec rm -rf tmp
+ mkdir tmp
+
+ # Put a copy of our shell script in each
+ # directory, plus some files.
+ foreach dir { a b c d e f } {
+ mkdir "tmp/$dir"
+ set script_name "tmp/$dir/runme"
+ set f [open "$script_name" "w" 0700 ]
+ puts $f "$body"
+ close $f
+ foreach item { one two three four } {
+ touch "tmp/$dir/$item"
+ }
+ }
+
+ set SKIP_OLD 1
+ find_start p {tmp -type f -empty -execdir sh ./runme \{\} + } ""
+ # We also repeat this test (with the same expected output) for the
+ # non-multiple case (this detects Savannah bug #29949).
+ find_start p {tmp -type f -empty -execdir sh ./runme \{\} \; } ""
+ set SKIP_OLD 0
+ exec rm -rf tmp
+}
diff --git a/find/testsuite/find.gnu/execdir-multiple.xo b/find/testsuite/find.gnu/execdir-multiple.xo
new file mode 100644
index 0000000..a4f93d9
--- /dev/null
+++ b/find/testsuite/find.gnu/execdir-multiple.xo
@@ -0,0 +1,24 @@
+a ./one
+a ./two
+a ./three
+a ./four
+b ./one
+b ./two
+b ./three
+b ./four
+c ./one
+c ./two
+c ./three
+c ./four
+d ./one
+d ./two
+d ./three
+d ./four
+e ./one
+e ./two
+e ./three
+e ./four
+f ./one
+f ./two
+f ./three
+f ./four
diff --git a/find/testsuite/find.gnu/execdir-one.exp b/find/testsuite/find.gnu/execdir-one.exp
new file mode 100644
index 0000000..53f2e00
--- /dev/null
+++ b/find/testsuite/find.gnu/execdir-one.exp
@@ -0,0 +1,7 @@
+# tests for -name
+if { [ safe_path ] } {
+ exec rm -rf tmp
+ exec mkdir tmp tmp/fred tmp/jim
+ find_start p {tmp -name fred -execdir echo \{\} \; }
+ exec rm -rf tmp
+}
diff --git a/find/testsuite/find.gnu/execdir-one.xo b/find/testsuite/find.gnu/execdir-one.xo
new file mode 100644
index 0000000..8584084
--- /dev/null
+++ b/find/testsuite/find.gnu/execdir-one.xo
@@ -0,0 +1 @@
+./fred
diff --git a/find/testsuite/find.gnu/execdir-pwd.exp b/find/testsuite/find.gnu/execdir-pwd.exp
new file mode 100644
index 0000000..740785f
--- /dev/null
+++ b/find/testsuite/find.gnu/execdir-pwd.exp
@@ -0,0 +1,20 @@
+# tests for -execdir pwd \+
+if { [ safe_path ] } {
+ global SKIP_OLD
+
+ exec rm -rf tmp
+ exec mkdir tmp
+
+ # Create an empty shell script.
+ exec touch tmp/foo
+ exec chmod +x tmp/foo
+
+ # The -execdir should find the "foo" in the current directory.
+ # If not, the find command is probably executing the command
+ # built up by -execdir in the wrong directory.
+
+ set SKIP_OLD 1
+ find_start p {tmp -name foo -execdir sh ./foo \{\} + } ""
+ set SKIP_OLD 0
+ exec rm -rf tmp
+}
diff --git a/find/testsuite/find.gnu/execdir-pwd1.exp b/find/testsuite/find.gnu/execdir-pwd1.exp
new file mode 100644
index 0000000..e9863ac
--- /dev/null
+++ b/find/testsuite/find.gnu/execdir-pwd1.exp
@@ -0,0 +1,20 @@
+# tests for working directory of -execdir {} \;
+if { [ safe_path ] } {
+ global SKIP_OLD
+
+ exec rm -rf tmp
+ exec mkdir tmp
+
+ # Create an empty shell script.
+ exec touch tmp/foo
+ exec chmod +x tmp/foo
+
+ # The -execdir should find the "foo" in the current directory.
+ # If not, the find command is probably executing the command
+ # built up by -execdir in the wrong directory.
+
+ set SKIP_OLD 1
+ find_start p {tmp -name foo -execdir sh ./foo \{\} \; } ""
+ set SKIP_OLD 0
+ exec rm -rf tmp
+}
diff --git a/find/testsuite/find.gnu/execdir-root-only.exp b/find/testsuite/find.gnu/execdir-root-only.exp
new file mode 100644
index 0000000..c57fd31
--- /dev/null
+++ b/find/testsuite/find.gnu/execdir-root-only.exp
@@ -0,0 +1,21 @@
+# Bug report by Bas van Gompel:
+#
+# This appears to work well. However when the rootdir is passed,
+# something looks fishy:
+#
+# find / -mindepth 0 -maxdepth 0 -execdir echo {} \;
+# .//
+#
+# I also spotted, when `+' is used:
+#
+# find / -mindepth 0 -maxdepth 0 -execdir echo == {} +
+# ==
+# == .//
+#
+# (Notice the first line of output, which should not be there.)
+
+
+# This test checks the second of these two cases.
+if { [ safe_path ] } {
+ find_start p { / -mindepth 0 -maxdepth 0 -execdir echo == "{}" + }
+}
diff --git a/find/testsuite/find.gnu/execdir-root-only.xo b/find/testsuite/find.gnu/execdir-root-only.xo
new file mode 100644
index 0000000..c975392
--- /dev/null
+++ b/find/testsuite/find.gnu/execdir-root-only.xo
@@ -0,0 +1 @@
+== /
diff --git a/find/testsuite/find.gnu/false.exp b/find/testsuite/find.gnu/false.exp
new file mode 100644
index 0000000..31f98a5
--- /dev/null
+++ b/find/testsuite/find.gnu/false.exp
@@ -0,0 +1,5 @@
+# test for -false.
+exec rm -rf tmp
+exec mkdir tmp tmp/fred tmp/fred/jim
+find_start p { tmp -depth -print -false -print }
+exec rm -rf tmp
diff --git a/find/testsuite/find.gnu/false.xo b/find/testsuite/find.gnu/false.xo
new file mode 100644
index 0000000..9baad64
--- /dev/null
+++ b/find/testsuite/find.gnu/false.xo
@@ -0,0 +1,3 @@
+tmp/fred/jim
+tmp/fred
+tmp
diff --git a/find/testsuite/find.gnu/follow-arg-parent-symlink.exp b/find/testsuite/find.gnu/follow-arg-parent-symlink.exp
new file mode 100644
index 0000000..0ab9e47
--- /dev/null
+++ b/find/testsuite/find.gnu/follow-arg-parent-symlink.exp
@@ -0,0 +1,6 @@
+exec rm -rf tmp
+exec mkdir tmp tmp/dir1 tmp/dir1/dir2
+exec touch tmp/dir1/dir2/foo
+exec ln -s dir1 tmp/link1
+find_start p {tmp/link1/dir2 -type f -print }
+exec rm -rf tmp
diff --git a/find/testsuite/find.gnu/follow-arg-parent-symlink.xo b/find/testsuite/find.gnu/follow-arg-parent-symlink.xo
new file mode 100644
index 0000000..0cf5187
--- /dev/null
+++ b/find/testsuite/find.gnu/follow-arg-parent-symlink.xo
@@ -0,0 +1 @@
+tmp/link1/dir2/foo
diff --git a/find/testsuite/find.gnu/follow-basic.exp b/find/testsuite/find.gnu/follow-basic.exp
new file mode 100644
index 0000000..bc62a2d
--- /dev/null
+++ b/find/testsuite/find.gnu/follow-basic.exp
@@ -0,0 +1,10 @@
+# Verifies that the -follow option is correctly implemented,
+# but does this by using the GNU extension -printf.
+exec rm -rf tmp
+
+exec mkdir tmp
+exec ln -s /etc/passwd tmp/LINK
+exec ln -s /NOSUCHFILE tmp/BROKEN
+
+# Links should all be dereferenced unless they are broken.
+find_start p { tmp/LINK tmp/BROKEN tmp -follow -printf "%y %d %p\n" }
diff --git a/find/testsuite/find.gnu/follow-basic.xo b/find/testsuite/find.gnu/follow-basic.xo
new file mode 100644
index 0000000..f2c7940
--- /dev/null
+++ b/find/testsuite/find.gnu/follow-basic.xo
@@ -0,0 +1,5 @@
+d 0 tmp
+f 0 tmp/LINK
+f 1 tmp/LINK
+l 0 tmp/BROKEN
+l 1 tmp/BROKEN
diff --git a/find/testsuite/find.gnu/fprint-unwritable.exp b/find/testsuite/find.gnu/fprint-unwritable.exp
new file mode 100644
index 0000000..905894d
--- /dev/null
+++ b/find/testsuite/find.gnu/fprint-unwritable.exp
@@ -0,0 +1,9 @@
+# test for -fprint to unwritable dest (we expect this to fail)
+if { ! [ fs_superuser ] } {
+ exec rm -rf tmp
+ file mkdir tmp
+ exec touch tmp/unwritable
+ exec chmod 444 tmp/unwritable
+ find_start f { tmp -fprint tmp/unwritable }
+ exec rm -rf tmp
+}
diff --git a/find/testsuite/find.gnu/fprint0_stdout.exp b/find/testsuite/find.gnu/fprint0_stdout.exp
new file mode 100644
index 0000000..c5a5aa8
--- /dev/null
+++ b/find/testsuite/find.gnu/fprint0_stdout.exp
@@ -0,0 +1,5 @@
+# test for -fprint
+exec rm -rf tmp
+exec touch tmp
+find_start p { tmp -fprint0 /dev/stdout }
+exec rm -rf tmp
diff --git a/find/testsuite/find.gnu/fprint0_stdout.xo b/find/testsuite/find.gnu/fprint0_stdout.xo
new file mode 100644
index 0000000..60688dd
--- /dev/null
+++ b/find/testsuite/find.gnu/fprint0_stdout.xo
Binary files differ
diff --git a/find/testsuite/find.gnu/fprintf-samefile.exp b/find/testsuite/find.gnu/fprintf-samefile.exp
new file mode 100644
index 0000000..63e6fb7
--- /dev/null
+++ b/find/testsuite/find.gnu/fprintf-samefile.exp
@@ -0,0 +1,26 @@
+# This test was added as part of the fix for Savannah bug #24873, but it
+# does not exercise the relevant condition (which is a race). While making
+# the fix I found that there were no tests for -fprintf at all, so I added
+# one.
+exec rm -rf tmp
+exec mkdir tmp
+exec touch tmp/file tmp/top
+exec ln -s file tmp/same
+# This command line should exercise the case where sharefile_fopen
+# Detects that two destination files are actually the same.
+find_start p {tmp/top -fprintf tmp/file "1: %p\n" -fprintf tmp/same "2: %p\n" }
+
+# We get here after the final iteration through the various
+# find binaries and -O option. However -fprintf truncates the
+# output file, so there should be just one set of output in there
+# from
+
+# Check that we got the right output in tmp/file.
+set f [open "tmp/file" "r"]
+set data [read $f]
+close $f
+set expected "1: tmp/top\n2: tmp/top\n"
+if { [string compare $data $expected] } {
+ fail "fprintf-samefile: expected output:\n$expected\nbut got:\n$data"
+}
+exec rm -rf tmp
diff --git a/find/testsuite/find.gnu/gnu-or.exp b/find/testsuite/find.gnu/gnu-or.exp
new file mode 100644
index 0000000..92a2939
--- /dev/null
+++ b/find/testsuite/find.gnu/gnu-or.exp
@@ -0,0 +1,5 @@
+# test for -false.
+exec rm -rf tmp
+exec mkdir tmp tmp/fred tmp/fred/jim
+find_start p { tmp -depth -print -false -or -print }
+exec rm -rf tmp
diff --git a/find/testsuite/find.gnu/gnu-or.xo b/find/testsuite/find.gnu/gnu-or.xo
new file mode 100644
index 0000000..8484390
--- /dev/null
+++ b/find/testsuite/find.gnu/gnu-or.xo
@@ -0,0 +1,6 @@
+tmp/fred/jim
+tmp/fred/jim
+tmp/fred
+tmp/fred
+tmp
+tmp
diff --git a/find/testsuite/find.gnu/gnuand.exp b/find/testsuite/find.gnu/gnuand.exp
new file mode 100644
index 0000000..2e685ca
--- /dev/null
+++ b/find/testsuite/find.gnu/gnuand.exp
@@ -0,0 +1,5 @@
+# tests for -name
+exec rm -rf tmp
+exec mkdir tmp tmp/fred tmp/jim
+find_start p {tmp -name fred -and -print}
+exec rm -rf tmp
diff --git a/find/testsuite/find.gnu/gnuand.xo b/find/testsuite/find.gnu/gnuand.xo
new file mode 100644
index 0000000..8cc8940
--- /dev/null
+++ b/find/testsuite/find.gnu/gnuand.xo
@@ -0,0 +1 @@
+tmp/fred
diff --git a/find/testsuite/find.gnu/gnunot.exp b/find/testsuite/find.gnu/gnunot.exp
new file mode 100644
index 0000000..4951c1e
--- /dev/null
+++ b/find/testsuite/find.gnu/gnunot.exp
@@ -0,0 +1,5 @@
+# tests for !
+exec rm -rf tmp
+exec mkdir tmp tmp/fred tmp/jim
+find_start p {tmp -not -name fred -print}
+exec rm -rf tmp
diff --git a/find/testsuite/find.gnu/gnunot.xo b/find/testsuite/find.gnu/gnunot.xo
new file mode 100644
index 0000000..776fed4
--- /dev/null
+++ b/find/testsuite/find.gnu/gnunot.xo
@@ -0,0 +1,2 @@
+tmp
+tmp/jim \ No newline at end of file
diff --git a/find/testsuite/find.gnu/ilname.exp b/find/testsuite/find.gnu/ilname.exp
new file mode 100644
index 0000000..2d27617
--- /dev/null
+++ b/find/testsuite/find.gnu/ilname.exp
@@ -0,0 +1,7 @@
+# tests for -ilname
+exec rm -rf tmp
+exec mkdir tmp
+exec touch tmp/one
+exec ln -s one tmp/two
+find_start p {tmp -ilname One -print}
+exec rm -rf tmp
diff --git a/find/testsuite/find.gnu/ilname.xo b/find/testsuite/find.gnu/ilname.xo
new file mode 100644
index 0000000..c7b45df
--- /dev/null
+++ b/find/testsuite/find.gnu/ilname.xo
@@ -0,0 +1 @@
+tmp/two
diff --git a/find/testsuite/find.gnu/iname.exp b/find/testsuite/find.gnu/iname.exp
new file mode 100644
index 0000000..c8c26a4
--- /dev/null
+++ b/find/testsuite/find.gnu/iname.exp
@@ -0,0 +1,5 @@
+# tests for -name
+exec rm -rf tmp
+exec mkdir tmp tmp/fred tmp/jim
+find_start p {tmp -iname frED -print}
+exec rm -rf tmp
diff --git a/find/testsuite/find.gnu/iname.xo b/find/testsuite/find.gnu/iname.xo
new file mode 100644
index 0000000..8cc8940
--- /dev/null
+++ b/find/testsuite/find.gnu/iname.xo
@@ -0,0 +1 @@
+tmp/fred
diff --git a/find/testsuite/find.gnu/inum.exp b/find/testsuite/find.gnu/inum.exp
new file mode 100644
index 0000000..75614f5
--- /dev/null
+++ b/find/testsuite/find.gnu/inum.exp
@@ -0,0 +1,7 @@
+# test for -inum
+exec rm -rf tmp tmp2
+exec touch tmp tmp2
+set list [ split [ exec ls -1i tmp ] ]
+set inode [ lindex $list 0 ]
+find_start p " tmp tmp2 -inum $inode -print "
+exec rm -rf tmp tmp2
diff --git a/find/testsuite/find.gnu/inum.xo b/find/testsuite/find.gnu/inum.xo
new file mode 100644
index 0000000..a9a5aec
--- /dev/null
+++ b/find/testsuite/find.gnu/inum.xo
@@ -0,0 +1 @@
+tmp
diff --git a/find/testsuite/find.gnu/ipath.exp b/find/testsuite/find.gnu/ipath.exp
new file mode 100644
index 0000000..0013e48
--- /dev/null
+++ b/find/testsuite/find.gnu/ipath.exp
@@ -0,0 +1,5 @@
+# test for -path
+exec rm -rf tmp
+exec mkdir tmp tmp/top tmp/top/ONE tmp/top/ONE/two
+find_start p {tmp/top -ipath Tmp/TOP/one -print 2>/dev/null }
+exec rm -rf tmp
diff --git a/find/testsuite/find.gnu/ipath.xo b/find/testsuite/find.gnu/ipath.xo
new file mode 100644
index 0000000..6ac3ca0
--- /dev/null
+++ b/find/testsuite/find.gnu/ipath.xo
@@ -0,0 +1 @@
+tmp/top/ONE
diff --git a/find/testsuite/find.gnu/iregex1.exp b/find/testsuite/find.gnu/iregex1.exp
new file mode 100644
index 0000000..c24cdf0
--- /dev/null
+++ b/find/testsuite/find.gnu/iregex1.exp
@@ -0,0 +1,5 @@
+# test for -iregex
+exec rm -rf tmp
+exec mkdir tmp tmp/d tmp/d/D tmp/d/D/d tmp/d/D/d/e
+find_start p {tmp -iregex {tmp\(/d\)*} -print }
+exec rm -rf tmp
diff --git a/find/testsuite/find.gnu/iregex1.xo b/find/testsuite/find.gnu/iregex1.xo
new file mode 100644
index 0000000..8901de0
--- /dev/null
+++ b/find/testsuite/find.gnu/iregex1.xo
@@ -0,0 +1,4 @@
+tmp
+tmp/d
+tmp/d/D
+tmp/d/D/d
diff --git a/find/testsuite/find.gnu/iwholename.exp b/find/testsuite/find.gnu/iwholename.exp
new file mode 100644
index 0000000..d58656a
--- /dev/null
+++ b/find/testsuite/find.gnu/iwholename.exp
@@ -0,0 +1,5 @@
+# test for -iwholename
+exec rm -rf tmp
+exec mkdir tmp tmp/top tmp/top/one tmp/top/one/two
+find_start p {tmp/top -iwholename tmP/TOP/One -print }
+exec rm -rf tmp
diff --git a/find/testsuite/find.gnu/iwholename.xo b/find/testsuite/find.gnu/iwholename.xo
new file mode 100644
index 0000000..66d2877
--- /dev/null
+++ b/find/testsuite/find.gnu/iwholename.xo
@@ -0,0 +1 @@
+tmp/top/one
diff --git a/find/testsuite/find.gnu/lname.exp b/find/testsuite/find.gnu/lname.exp
new file mode 100644
index 0000000..65f8878
--- /dev/null
+++ b/find/testsuite/find.gnu/lname.exp
@@ -0,0 +1,7 @@
+# tests for -lname
+exec rm -rf tmp
+exec mkdir tmp
+exec touch tmp/one
+exec ln -s one tmp/two
+find_start p {tmp -lname one -print}
+exec rm -rf tmp
diff --git a/find/testsuite/find.gnu/lname.xo b/find/testsuite/find.gnu/lname.xo
new file mode 100644
index 0000000..c7b45df
--- /dev/null
+++ b/find/testsuite/find.gnu/lname.xo
@@ -0,0 +1 @@
+tmp/two
diff --git a/find/testsuite/find.gnu/mindepth-arg.exp b/find/testsuite/find.gnu/mindepth-arg.exp
new file mode 100644
index 0000000..ba4d0dc
--- /dev/null
+++ b/find/testsuite/find.gnu/mindepth-arg.exp
@@ -0,0 +1,9 @@
+# Argument validation for -mindepth and -maxdepth
+proc prepare {} {
+ exec rm -rf tmp
+ exec mkdir tmp tmp/top tmp/top/one
+}
+foreach predicate { -mindepth -maxdepth } {
+ find_start p "tmp/top $predicate 0 -print -quit" {} {} prepare
+}
+exec rm -rf tmp
diff --git a/find/testsuite/find.gnu/mindepth-arg.xo b/find/testsuite/find.gnu/mindepth-arg.xo
new file mode 100644
index 0000000..ddcb130
--- /dev/null
+++ b/find/testsuite/find.gnu/mindepth-arg.xo
@@ -0,0 +1 @@
+tmp/top \ No newline at end of file
diff --git a/find/testsuite/find.gnu/mindepth-badarg.exp b/find/testsuite/find.gnu/mindepth-badarg.exp
new file mode 100644
index 0000000..d098af0
--- /dev/null
+++ b/find/testsuite/find.gnu/mindepth-badarg.exp
@@ -0,0 +1,12 @@
+# Argument validation for -mindepth and -maxdepth
+
+exec rm -rf tmp
+exec mkdir tmp tmp/top tmp/top/one
+
+foreach predicate { -mindepth -maxdepth } {
+ # Try a variety of bad arguments.
+ foreach arg { x 0x01 Fnord "" +1 1.2 -3 3e1 } {
+ find_start f "tmp/top $predicate $arg -quit"
+ }
+}
+exec rm -rf tmp
diff --git a/find/testsuite/find.gnu/name-opt.exp b/find/testsuite/find.gnu/name-opt.exp
new file mode 100644
index 0000000..0ec1d8d
--- /dev/null
+++ b/find/testsuite/find.gnu/name-opt.exp
@@ -0,0 +1,8 @@
+# Verifies that -name is not optimized in front of -prune
+exec rm -rf tmp
+exec mkdir tmp
+exec mkdir tmp/top
+exec mkdir tmp/top/one
+exec touch tmp/top/one/foo
+find_start p {tmp/top -prune -name foo}
+exec rm -rf tmp
diff --git a/find/testsuite/find.gnu/name-opt.xo b/find/testsuite/find.gnu/name-opt.xo
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/find/testsuite/find.gnu/name-opt.xo
diff --git a/find/testsuite/find.gnu/name-period.exp b/find/testsuite/find.gnu/name-period.exp
new file mode 100644
index 0000000..42858fe
--- /dev/null
+++ b/find/testsuite/find.gnu/name-period.exp
@@ -0,0 +1,10 @@
+# Verifies that -name '*bar' will match quux/.foobar.
+# See http://standards.ieee.org/reading/ieee/interp/1003-2-92_int/pasc-1003.2-126.html
+# Also see http://savannah.gnu.org/bugs/?func=detailitem&item_id=10757
+exec rm -rf tmp
+exec mkdir tmp
+exec mkdir tmp/top
+exec mkdir tmp/top/.one
+exec mkdir tmp/top/bane
+find_start p {tmp/top -name \*ne -print}
+exec rm -rf tmp
diff --git a/find/testsuite/find.gnu/name-period.xo b/find/testsuite/find.gnu/name-period.xo
new file mode 100644
index 0000000..53cbcdc
--- /dev/null
+++ b/find/testsuite/find.gnu/name-period.xo
@@ -0,0 +1,2 @@
+tmp/top/bane
+tmp/top/.one
diff --git a/find/testsuite/find.gnu/name-slash.exp b/find/testsuite/find.gnu/name-slash.exp
new file mode 100644
index 0000000..bd9a187
--- /dev/null
+++ b/find/testsuite/find.gnu/name-slash.exp
@@ -0,0 +1,2 @@
+# tests for '-name /'
+find_start p {/ /// -maxdepth 0 -name /}
diff --git a/find/testsuite/find.gnu/name-slash.xo b/find/testsuite/find.gnu/name-slash.xo
new file mode 100644
index 0000000..6c24144
--- /dev/null
+++ b/find/testsuite/find.gnu/name-slash.xo
@@ -0,0 +1,2 @@
+/
+///
diff --git a/find/testsuite/find.gnu/no-fdleak-test.exp b/find/testsuite/find.gnu/no-fdleak-test.exp
new file mode 100644
index 0000000..f823047
--- /dev/null
+++ b/find/testsuite/find.gnu/no-fdleak-test.exp
@@ -0,0 +1,13 @@
+# Test with the FD leak check turned off. We make this test, just to
+# avoid failing to detect problems that only occur when the leak check
+# is turned off.
+set oldval $env(GNU_FINDUTILS_FD_LEAK_CHECK)
+unset env(GNU_FINDUTILS_FD_LEAK_CHECK)
+
+if { [ safe_path ] } {
+ exec rm -rf tmp
+ exec mkdir tmp tmp/fred tmp/jim
+ find_start p {tmp -name fred -execdir echo \{\} \; }
+ exec rm -rf tmp
+}
+set env(GNU_FINDUTILS_FD_LEAK_CHECK) $oldval
diff --git a/find/testsuite/find.gnu/no-fdleak-test.xo b/find/testsuite/find.gnu/no-fdleak-test.xo
new file mode 100644
index 0000000..8584084
--- /dev/null
+++ b/find/testsuite/find.gnu/no-fdleak-test.xo
@@ -0,0 +1 @@
+./fred
diff --git a/find/testsuite/find.gnu/path.exp b/find/testsuite/find.gnu/path.exp
new file mode 100644
index 0000000..40fa01e
--- /dev/null
+++ b/find/testsuite/find.gnu/path.exp
@@ -0,0 +1,5 @@
+# test for -path
+exec rm -rf tmp
+exec mkdir tmp tmp/top tmp/top/one tmp/top/one/two
+find_start p {tmp/top -path tmp/top/one -print }
+exec rm -rf tmp
diff --git a/find/testsuite/find.gnu/path.xo b/find/testsuite/find.gnu/path.xo
new file mode 100644
index 0000000..66d2877
--- /dev/null
+++ b/find/testsuite/find.gnu/path.xo
@@ -0,0 +1 @@
+tmp/top/one
diff --git a/find/testsuite/find.gnu/perm-slash.exp b/find/testsuite/find.gnu/perm-slash.exp
new file mode 100644
index 0000000..252d91a
--- /dev/null
+++ b/find/testsuite/find.gnu/perm-slash.exp
@@ -0,0 +1,19 @@
+# tests for -perm /nnn
+# The slash is a GNU extension
+
+exec rm -rf tmp
+exec mkdir tmp
+
+## set up a selection of test files
+foreach perm { 400 200 555 700 000 050 } {
+ exec touch "tmp/$perm"
+ exec chmod $perm "tmp/$perm"
+}
+
+#
+# The -o operator normally has a short-circuit effect,
+# so we have to use "-exec false \;" to make sure that
+# all the parenthesised expression actually fail.
+#
+find_start p {tmp -mindepth 1 -perm /555 -printf "p/555 %p\n" }
+# exec rm -rf tmp tmp2
diff --git a/find/testsuite/find.gnu/perm-slash.xo b/find/testsuite/find.gnu/perm-slash.xo
new file mode 100644
index 0000000..f84e5b7
--- /dev/null
+++ b/find/testsuite/find.gnu/perm-slash.xo
@@ -0,0 +1,4 @@
+p/555 tmp/050
+p/555 tmp/555
+p/555 tmp/400
+p/555 tmp/700 \ No newline at end of file
diff --git a/find/testsuite/find.gnu/perm.exp b/find/testsuite/find.gnu/perm.exp
new file mode 100644
index 0000000..d4913f8
--- /dev/null
+++ b/find/testsuite/find.gnu/perm.exp
@@ -0,0 +1,7 @@
+# tests for -perm -0100 (-perm with -)
+exec rm -rf tmp
+exec mkdir tmp
+exec touch tmp/fred
+exec chmod 444 tmp/fred
+find_start p {tmp -perm -0100}
+exec rm -rf tmp
diff --git a/find/testsuite/find.gnu/perm.xo b/find/testsuite/find.gnu/perm.xo
new file mode 100644
index 0000000..a9a5aec
--- /dev/null
+++ b/find/testsuite/find.gnu/perm.xo
@@ -0,0 +1 @@
+tmp
diff --git a/find/testsuite/find.gnu/perm000.exp b/find/testsuite/find.gnu/perm000.exp
new file mode 100644
index 0000000..9217129
--- /dev/null
+++ b/find/testsuite/find.gnu/perm000.exp
@@ -0,0 +1,7 @@
+# tests for -perm /000 (Savannah bug #14748).
+exec rm -rf tmp
+exec mkdir tmp
+exec touch tmp/fred tmp/wilma
+exec chmod 000 tmp/fred
+find_start p {tmp -perm /000 -print 2>/dev/null }
+exec rm -rf tmp
diff --git a/find/testsuite/find.gnu/perm000.xo b/find/testsuite/find.gnu/perm000.xo
new file mode 100644
index 0000000..7a1f6e9
--- /dev/null
+++ b/find/testsuite/find.gnu/perm000.xo
@@ -0,0 +1,3 @@
+tmp
+tmp/fred
+tmp/wilma
diff --git a/find/testsuite/find.gnu/posix-dflt.exp b/find/testsuite/find.gnu/posix-dflt.exp
new file mode 100644
index 0000000..3e7d573
--- /dev/null
+++ b/find/testsuite/find.gnu/posix-dflt.exp
@@ -0,0 +1,10 @@
+# Verifies that the POSIX behaviour without -P or -L options is
+# correctly implemented, but does this by using the GNU extension
+# -printf.
+exec rm -rf tmp
+
+exec mkdir tmp
+exec ln -s /etc/passwd tmp/LINK
+exec ln -s /NOSUCHFILE tmp/BROKEN
+
+find_start p { -P tmp/LINK tmp/BROKEN tmp -printf "%y %d %p\n" }
diff --git a/find/testsuite/find.gnu/posix-dflt.xo b/find/testsuite/find.gnu/posix-dflt.xo
new file mode 100644
index 0000000..7359d24
--- /dev/null
+++ b/find/testsuite/find.gnu/posix-dflt.xo
@@ -0,0 +1,5 @@
+d 0 tmp
+l 0 tmp/BROKEN
+l 0 tmp/LINK
+l 1 tmp/BROKEN
+l 1 tmp/LINK
diff --git a/find/testsuite/find.gnu/posix-h.exp b/find/testsuite/find.gnu/posix-h.exp
new file mode 100644
index 0000000..0ecbabe
--- /dev/null
+++ b/find/testsuite/find.gnu/posix-h.exp
@@ -0,0 +1,13 @@
+# Verifies that the POSIX -H option is correctly implemented,
+# but does this by using the GNU extension -printf.
+exec rm -rf tmp
+
+exec mkdir tmp
+exec ln -s /etc/passwd tmp/LINK
+exec ln -s /NOSUCHFILE tmp/BROKEN
+
+# If the file is not on the command line, the link is not
+# dereferenced, and so tmp/LINK should appear at depth 1
+# but as type "l". tmp itself appears first at depth 0 as
+# a directory.
+find_start p { -H tmp/LINK tmp/BROKEN tmp -printf "H1: %y %d %p\n" }
diff --git a/find/testsuite/find.gnu/posix-h.xo b/find/testsuite/find.gnu/posix-h.xo
new file mode 100644
index 0000000..4d503f7
--- /dev/null
+++ b/find/testsuite/find.gnu/posix-h.xo
@@ -0,0 +1,5 @@
+H1: d 0 tmp
+H1: f 0 tmp/LINK
+H1: l 0 tmp/BROKEN
+H1: l 1 tmp/BROKEN
+H1: l 1 tmp/LINK
diff --git a/find/testsuite/find.gnu/posix-l.exp b/find/testsuite/find.gnu/posix-l.exp
new file mode 100644
index 0000000..6055edf
--- /dev/null
+++ b/find/testsuite/find.gnu/posix-l.exp
@@ -0,0 +1,10 @@
+# Verifies that the POSIX -L option is correctly implemented,
+# but does this by using the GNU extension -printf.
+exec rm -rf tmp
+
+exec mkdir tmp
+exec ln -s /etc/passwd tmp/LINK
+exec ln -s /NOSUCHFILE tmp/BROKEN
+
+# Links should all be dereferenced unless they are broken.
+find_start p { -L tmp/LINK tmp/BROKEN tmp -printf "%y %d %p\n" }
diff --git a/find/testsuite/find.gnu/posix-l.xo b/find/testsuite/find.gnu/posix-l.xo
new file mode 100644
index 0000000..f2c7940
--- /dev/null
+++ b/find/testsuite/find.gnu/posix-l.xo
@@ -0,0 +1,5 @@
+d 0 tmp
+f 0 tmp/LINK
+f 1 tmp/LINK
+l 0 tmp/BROKEN
+l 1 tmp/BROKEN
diff --git a/find/testsuite/find.gnu/posix-perminvalid.exp b/find/testsuite/find.gnu/posix-perminvalid.exp
new file mode 100644
index 0000000..b773511
--- /dev/null
+++ b/find/testsuite/find.gnu/posix-perminvalid.exp
@@ -0,0 +1,16 @@
+# tests for non-POSIX-compliant argument to -perm
+# Remember any previous value of POSIXLY_CORRECT (if there was one)
+if [info exists env(POSIXLY_CORRECT)] {
+ set oldval env(POSIXLY_CORRECT)
+}
+
+# Set POSIXLY_CORRECT and perform the test
+set env(POSIXLY_CORRECT) 1
+find_start f {. -perm +a+x}
+
+# Set POSIXLY_CORRECT to its previous value
+if [info exists oldval] {
+ set env(POSIXLY_CORRECT) $oldval
+} else {
+ unset env(POSIXLY_CORRECT)
+}
diff --git a/find/testsuite/find.gnu/print0.exp b/find/testsuite/find.gnu/print0.exp
new file mode 100644
index 0000000..11a3cb6
--- /dev/null
+++ b/find/testsuite/find.gnu/print0.exp
@@ -0,0 +1,5 @@
+# test for -print0.
+exec rm -rf tmp
+exec touch tmp
+find_start p { tmp -print0 }
+exec rm -rf tmp
diff --git a/find/testsuite/find.gnu/print0.xo b/find/testsuite/find.gnu/print0.xo
new file mode 100644
index 0000000..b947b3b
--- /dev/null
+++ b/find/testsuite/find.gnu/print0.xo
Binary files differ
diff --git a/find/testsuite/find.gnu/print_stdout.exp b/find/testsuite/find.gnu/print_stdout.exp
new file mode 100644
index 0000000..5bbeefa
--- /dev/null
+++ b/find/testsuite/find.gnu/print_stdout.exp
@@ -0,0 +1,5 @@
+# test for -fprint
+exec rm -rf tmp
+exec touch tmp
+find_start p { tmp -fprint /dev/stdout }
+exec rm -rf tmp
diff --git a/find/testsuite/find.gnu/print_stdout.xo b/find/testsuite/find.gnu/print_stdout.xo
new file mode 100644
index 0000000..a9a5aec
--- /dev/null
+++ b/find/testsuite/find.gnu/print_stdout.xo
@@ -0,0 +1 @@
+tmp
diff --git a/find/testsuite/find.gnu/printf-h.exp b/find/testsuite/find.gnu/printf-h.exp
new file mode 100644
index 0000000..fb0187c
--- /dev/null
+++ b/find/testsuite/find.gnu/printf-h.exp
@@ -0,0 +1,5 @@
+# Test case for Savannah bug ID #12085.
+exec rm -rf tmp
+exec touch tmp
+find_start p {tmp -printf "RESULT: %h %f\n" }
+exec rm -rf tmp
diff --git a/find/testsuite/find.gnu/printf-h.xo b/find/testsuite/find.gnu/printf-h.xo
new file mode 100644
index 0000000..dc6ce01
--- /dev/null
+++ b/find/testsuite/find.gnu/printf-h.xo
@@ -0,0 +1 @@
+RESULT: . tmp
diff --git a/find/testsuite/find.gnu/printf-nonlocal-symlink.exp b/find/testsuite/find.gnu/printf-nonlocal-symlink.exp
new file mode 100644
index 0000000..f8e61e1
--- /dev/null
+++ b/find/testsuite/find.gnu/printf-nonlocal-symlink.exp
@@ -0,0 +1,7 @@
+exec rm -rf tmp
+exec mkdir tmp
+exec mkdir tmp/foo
+exec touch tmp/foo/file
+exec ln -s file tmp/foo/LINK
+find_start p {tmp -type l -printf "%p: %Y %y\n" }
+exec rm -rf tmp
diff --git a/find/testsuite/find.gnu/printf-nonlocal-symlink.xo b/find/testsuite/find.gnu/printf-nonlocal-symlink.xo
new file mode 100644
index 0000000..fcb338a
--- /dev/null
+++ b/find/testsuite/find.gnu/printf-nonlocal-symlink.xo
@@ -0,0 +1 @@
+tmp/foo/LINK: f l
diff --git a/find/testsuite/find.gnu/printf-reserved.exp b/find/testsuite/find.gnu/printf-reserved.exp
new file mode 100644
index 0000000..3072312
--- /dev/null
+++ b/find/testsuite/find.gnu/printf-reserved.exp
@@ -0,0 +1,3 @@
+find_start f { . -maxdepth 0 -printf '%(' }
+find_start f { . -maxdepth 0 -printf '%\{' }
+find_start f { . -maxdepth 0 -printf '%\[' }
diff --git a/find/testsuite/find.gnu/printf-slash.exp b/find/testsuite/find.gnu/printf-slash.exp
new file mode 100644
index 0000000..3f46023
--- /dev/null
+++ b/find/testsuite/find.gnu/printf-slash.exp
@@ -0,0 +1 @@
+find_start p {/ /// -maxdepth 0 -printf "%p %f\\n"}
diff --git a/find/testsuite/find.gnu/printf-slash.xo b/find/testsuite/find.gnu/printf-slash.xo
new file mode 100644
index 0000000..50f8192
--- /dev/null
+++ b/find/testsuite/find.gnu/printf-slash.xo
@@ -0,0 +1,2 @@
+/ /
+/// /
diff --git a/find/testsuite/find.gnu/printf-symlink.exp b/find/testsuite/find.gnu/printf-symlink.exp
new file mode 100644
index 0000000..6acc3e6
--- /dev/null
+++ b/find/testsuite/find.gnu/printf-symlink.exp
@@ -0,0 +1,6 @@
+exec rm -rf tmp
+exec mkdir tmp
+exec touch tmp/file
+exec ln -s file tmp/LINK
+find_start p {tmp/LINK -printf "RESULT: %y %Y %p\n" -printf "RESULT2: %Y %y %p\n" }
+exec rm -rf tmp
diff --git a/find/testsuite/find.gnu/printf-symlink.xo b/find/testsuite/find.gnu/printf-symlink.xo
new file mode 100644
index 0000000..cc2b69c
--- /dev/null
+++ b/find/testsuite/find.gnu/printf-symlink.xo
@@ -0,0 +1,2 @@
+RESULT: l f tmp/LINK
+RESULT2: f l tmp/LINK
diff --git a/find/testsuite/find.gnu/printf.exp b/find/testsuite/find.gnu/printf.exp
new file mode 100644
index 0000000..ba8e75b
--- /dev/null
+++ b/find/testsuite/find.gnu/printf.exp
@@ -0,0 +1,6 @@
+exec rm -rf tmp
+exec mkdir tmp
+exec touch tmp/file
+exec chmod 600 tmp/file
+find_start p {tmp -type f -printf "a %d\n" -printf "b %f\n" -printf "c %h\n" -printf "d %H\n" -printf "e %l\n" -printf "f %m\n" -printf "g %n\n" -printf "h %p\n" -printf "i %P\n" -printf "j %y\n" -printf "k %Y\n" -printf "percent it%%works%%\n" -printf "string-right !%10p!\n" -printf "string-left !%-10p!\n" -printf "trunc-R !%10.6p!\n" -printf "trunc-L !%-10.6p!\n" -printf "a5 !%5d!\n" -printf "a05 !%05d!\n" -printf "a+ %+d\n" }
+exec rm -rf tmp
diff --git a/find/testsuite/find.gnu/printf.xo b/find/testsuite/find.gnu/printf.xo
new file mode 100644
index 0000000..e607293
--- /dev/null
+++ b/find/testsuite/find.gnu/printf.xo
@@ -0,0 +1,19 @@
+a 1
+a+ +1
+a5 ! 1!
+a05 !00001!
+b file
+c tmp
+d tmp
+e
+f 600
+g 1
+h tmp/file
+i file
+j f
+k f
+percent it%works%
+string-left !tmp/file !
+string-right ! tmp/file!
+trunc-L !tmp/fi !
+trunc-R ! tmp/fi!
diff --git a/find/testsuite/find.gnu/printfHdfl.exp b/find/testsuite/find.gnu/printfHdfl.exp
new file mode 100644
index 0000000..517ecc5
--- /dev/null
+++ b/find/testsuite/find.gnu/printfHdfl.exp
@@ -0,0 +1,2 @@
+# verify that %H with no argument assumes "."
+find_start p { -maxdepth 0 -printf "%H" }
diff --git a/find/testsuite/find.gnu/printfHdfl.xo b/find/testsuite/find.gnu/printfHdfl.xo
new file mode 100644
index 0000000..9c558e3
--- /dev/null
+++ b/find/testsuite/find.gnu/printfHdfl.xo
@@ -0,0 +1 @@
+.
diff --git a/find/testsuite/find.gnu/prune-default-print.exp b/find/testsuite/find.gnu/prune-default-print.exp
new file mode 100644
index 0000000..b43a6b9
--- /dev/null
+++ b/find/testsuite/find.gnu/prune-default-print.exp
@@ -0,0 +1,5 @@
+# Verifies that default -print is used with -prune
+exec rm -rf tmp
+exec mkdir tmp
+find_start p {tmp -prune}
+exec rm -rf tmp
diff --git a/find/testsuite/find.gnu/prune-default-print.xo b/find/testsuite/find.gnu/prune-default-print.xo
new file mode 100644
index 0000000..a9a5aec
--- /dev/null
+++ b/find/testsuite/find.gnu/prune-default-print.xo
@@ -0,0 +1 @@
+tmp
diff --git a/find/testsuite/find.gnu/quit.exp b/find/testsuite/find.gnu/quit.exp
new file mode 100644
index 0000000..610ad7f
--- /dev/null
+++ b/find/testsuite/find.gnu/quit.exp
@@ -0,0 +1,5 @@
+# test for -quit.
+exec rm -rf tmp
+exec mkdir tmp tmp/top tmp/top/one tmp/top/one/foo tmp/top/two
+find_start p {tmp/top/one tmp/top/two -depth -print -name one -quit }
+exec rm -rf tmp
diff --git a/find/testsuite/find.gnu/quit.xo b/find/testsuite/find.gnu/quit.xo
new file mode 100644
index 0000000..14c1d8d
--- /dev/null
+++ b/find/testsuite/find.gnu/quit.xo
@@ -0,0 +1,2 @@
+tmp/top/one/foo
+tmp/top/one
diff --git a/find/testsuite/find.gnu/regex1.exp b/find/testsuite/find.gnu/regex1.exp
new file mode 100644
index 0000000..071dcaf
--- /dev/null
+++ b/find/testsuite/find.gnu/regex1.exp
@@ -0,0 +1,5 @@
+# test for -regex
+exec rm -rf tmp
+exec mkdir tmp tmp/d tmp/d/d tmp/d/d/d tmp/d/d/d/e
+find_start p {tmp -regex {tmp\(/d\)*} -print }
+exec rm -rf tmp
diff --git a/find/testsuite/find.gnu/regex1.xo b/find/testsuite/find.gnu/regex1.xo
new file mode 100644
index 0000000..c4259bb
--- /dev/null
+++ b/find/testsuite/find.gnu/regex1.xo
@@ -0,0 +1,4 @@
+tmp
+tmp/d
+tmp/d/d
+tmp/d/d/d
diff --git a/find/testsuite/find.gnu/regex2.exp b/find/testsuite/find.gnu/regex2.exp
new file mode 100644
index 0000000..71cc1e3
--- /dev/null
+++ b/find/testsuite/find.gnu/regex2.exp
@@ -0,0 +1,5 @@
+# test for -regex
+exec rm -rf tmp
+exec mkdir tmp tmp/d tmp/d/d tmp/d/d/d tmp/d/d/d/e
+find_start p {tmp -regextype posix-extended -regex {tmp(/d)*} -print }
+exec rm -rf tmp
diff --git a/find/testsuite/find.gnu/regex2.xo b/find/testsuite/find.gnu/regex2.xo
new file mode 100644
index 0000000..c4259bb
--- /dev/null
+++ b/find/testsuite/find.gnu/regex2.xo
@@ -0,0 +1,4 @@
+tmp
+tmp/d
+tmp/d/d
+tmp/d/d/d
diff --git a/find/testsuite/find.gnu/samefile-copy.exp b/find/testsuite/find.gnu/samefile-copy.exp
new file mode 100644
index 0000000..69e47cd
--- /dev/null
+++ b/find/testsuite/find.gnu/samefile-copy.exp
@@ -0,0 +1,8 @@
+# test for -samefile
+exec rm -rf tmp
+exec mkdir tmp tmp/one tmp/two
+exec touch tmp/file1 tmp/file2
+exec cp tmp/file1 tmp/one/link
+exec cp tmp/file2 tmp/two/link
+find_start p {tmp/one tmp/two -samefile tmp/file1 -print}
+# exec rm -rf tmp
diff --git a/find/testsuite/find.gnu/samefile-copy.xo b/find/testsuite/find.gnu/samefile-copy.xo
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/find/testsuite/find.gnu/samefile-copy.xo
diff --git a/find/testsuite/find.gnu/samefile-link.exp b/find/testsuite/find.gnu/samefile-link.exp
new file mode 100644
index 0000000..e288160
--- /dev/null
+++ b/find/testsuite/find.gnu/samefile-link.exp
@@ -0,0 +1,9 @@
+# test for -samefile
+exec rm -rf tmp
+exec mkdir tmp tmp/one tmp/two
+exec touch tmp/file1 tmp/file2
+exec ln tmp/file1 tmp/one/link
+exec ln -s tmp/file1 tmp/one/symlink
+exec ln tmp/file2 tmp/two/link
+find_start p {tmp/one tmp/two -samefile tmp/file1 -print}
+# exec rm -rf tmp
diff --git a/find/testsuite/find.gnu/samefile-link.xo b/find/testsuite/find.gnu/samefile-link.xo
new file mode 100644
index 0000000..e53b73e
--- /dev/null
+++ b/find/testsuite/find.gnu/samefile-link.xo
@@ -0,0 +1 @@
+tmp/one/link
diff --git a/find/testsuite/find.gnu/samefile-missing.exp b/find/testsuite/find.gnu/samefile-missing.exp
new file mode 100644
index 0000000..2d509c4
--- /dev/null
+++ b/find/testsuite/find.gnu/samefile-missing.exp
@@ -0,0 +1,2 @@
+# test for diagnosis of the fact that the argument to -samefile is missing
+find_start f ". -samefile"
diff --git a/find/testsuite/find.gnu/samefile-p-brokenlink.exp b/find/testsuite/find.gnu/samefile-p-brokenlink.exp
new file mode 100644
index 0000000..8ae1fad
--- /dev/null
+++ b/find/testsuite/find.gnu/samefile-p-brokenlink.exp
@@ -0,0 +1,11 @@
+# test for find -P -samefile with a broken link
+exec rm -rf tmp
+exec mkdir tmp
+exec touch tmp/file1
+exec ln tmp/file1 tmp/link
+exec ln -s tmp/file1 tmp/symlink
+exec ln -s tmp/file2 tmp/broken
+exec ln tmp/broken tmp/blink
+
+find_start p { -P tmp -samefile tmp/broken -print}
+exec rm -rf tmp
diff --git a/find/testsuite/find.gnu/samefile-p-brokenlink.xo b/find/testsuite/find.gnu/samefile-p-brokenlink.xo
new file mode 100644
index 0000000..aaa98f3
--- /dev/null
+++ b/find/testsuite/find.gnu/samefile-p-brokenlink.xo
@@ -0,0 +1,2 @@
+tmp/blink
+tmp/broken \ No newline at end of file
diff --git a/find/testsuite/find.gnu/samefile-same.exp b/find/testsuite/find.gnu/samefile-same.exp
new file mode 100644
index 0000000..739f6c6
--- /dev/null
+++ b/find/testsuite/find.gnu/samefile-same.exp
@@ -0,0 +1,6 @@
+# test for -samefile
+exec rm -rf tmp
+exec mkdir tmp tmp/one tmp/two
+exec touch tmp/file
+find_start p {tmp tmp/file -samefile tmp/file -print}
+exec rm -rf tmp
diff --git a/find/testsuite/find.gnu/samefile-same.xo b/find/testsuite/find.gnu/samefile-same.xo
new file mode 100644
index 0000000..061fd95
--- /dev/null
+++ b/find/testsuite/find.gnu/samefile-same.xo
@@ -0,0 +1,2 @@
+tmp/file
+tmp/file
diff --git a/find/testsuite/find.gnu/samefile-symlink.exp b/find/testsuite/find.gnu/samefile-symlink.exp
new file mode 100644
index 0000000..1c6aa1f
--- /dev/null
+++ b/find/testsuite/find.gnu/samefile-symlink.exp
@@ -0,0 +1,10 @@
+# test for -samefile
+exec rm -rf tmp
+exec mkdir tmp tmp/one tmp/two
+exec touch tmp/file1 tmp/file2
+exec ln tmp/file1 tmp/one/link
+exec ln -s ../file1 tmp/one/symlink
+exec ln tmp/file2 tmp/two/link
+exec ln -s ../file2 tmp/two/symlink
+find_start p { -L tmp/one tmp/two -samefile tmp/file1 -print}
+# exec rm -rf tmp
diff --git a/find/testsuite/find.gnu/samefile-symlink.xo b/find/testsuite/find.gnu/samefile-symlink.xo
new file mode 100644
index 0000000..ca1e727
--- /dev/null
+++ b/find/testsuite/find.gnu/samefile-symlink.xo
@@ -0,0 +1,2 @@
+tmp/one/link
+tmp/one/symlink
diff --git a/find/testsuite/find.gnu/sv-bug-12230.exp b/find/testsuite/find.gnu/sv-bug-12230.exp
new file mode 100644
index 0000000..3af22c6
--- /dev/null
+++ b/find/testsuite/find.gnu/sv-bug-12230.exp
@@ -0,0 +1,14 @@
+# Bug report by Dmitry V. Levin.
+#
+# The command:
+# find tmp -false -execdir echo == {} +
+# Actually produces one line of output. It
+# should produce none, because the echo command
+# should never be invoked.
+#
+if { [ safe_path ] } {
+ exec rm -rf tmp
+ exec mkdir tmp
+ find_start p { tmp -false -execdir echo == "{}" + }
+ exec rm -rf tmp
+}
diff --git a/find/testsuite/find.gnu/sv-bug-17477.exp b/find/testsuite/find.gnu/sv-bug-17477.exp
new file mode 100644
index 0000000..2cc7fe3
--- /dev/null
+++ b/find/testsuite/find.gnu/sv-bug-17477.exp
@@ -0,0 +1,2 @@
+# verify that % with no argument fails gracefully
+find_start f { -maxdepth 0 -printf "test: %" }
diff --git a/find/testsuite/find.gnu/sv-bug-17490.exp b/find/testsuite/find.gnu/sv-bug-17490.exp
new file mode 100644
index 0000000..f29bebf
--- /dev/null
+++ b/find/testsuite/find.gnu/sv-bug-17490.exp
@@ -0,0 +1,4 @@
+# test for Savannah bug #17490
+#
+# That bug was a coredump if the argument to -regex was the final argument.
+find_start p {. -maxdepth 0 -regex x }
diff --git a/find/testsuite/find.gnu/sv-bug-17782.exp b/find/testsuite/find.gnu/sv-bug-17782.exp
new file mode 100644
index 0000000..db6dba2
--- /dev/null
+++ b/find/testsuite/find.gnu/sv-bug-17782.exp
@@ -0,0 +1,15 @@
+# Savannah bug #17782.
+# While -execdir echo blah {} works, -execdir echo "blah {}" doesn't.
+# The bug is that the ./ prefix is prepended to the argument containing the
+# braces, not to the expansion of the braces, so you get output like
+# ./blah foo
+# instead of
+# blah ./foo
+#
+if { [ safe_path ] } {
+ exec rm -rf tmp
+ exec mkdir tmp
+ exec touch tmp/foo
+ find_start p { tmp -name foo -execdir echo "saw {}" \; }
+ exec rm -rf tmp
+}
diff --git a/find/testsuite/find.gnu/sv-bug-17782.xo b/find/testsuite/find.gnu/sv-bug-17782.xo
new file mode 100644
index 0000000..2bde550
--- /dev/null
+++ b/find/testsuite/find.gnu/sv-bug-17782.xo
@@ -0,0 +1 @@
+saw ./foo \ No newline at end of file
diff --git a/find/testsuite/find.gnu/sv-bug-18222.exp b/find/testsuite/find.gnu/sv-bug-18222.exp
new file mode 100644
index 0000000..148010a
--- /dev/null
+++ b/find/testsuite/find.gnu/sv-bug-18222.exp
@@ -0,0 +1,8 @@
+# Test for Savannah bug #18222
+#
+# That bug was a case were the expansion of %H is truncated if the name
+# of the second start point is longer than that of the first.
+exec rm -rf tmp
+exec mkdir tmp
+exec touch tmp/short tmp/longer
+find_start p { tmp/short tmp/longer -printf "%H\n" }
diff --git a/find/testsuite/find.gnu/sv-bug-18222.xo b/find/testsuite/find.gnu/sv-bug-18222.xo
new file mode 100644
index 0000000..4f5f863
--- /dev/null
+++ b/find/testsuite/find.gnu/sv-bug-18222.xo
@@ -0,0 +1,2 @@
+tmp/short
+tmp/longer
diff --git a/find/testsuite/find.gnu/sv-bug-24169.exp b/find/testsuite/find.gnu/sv-bug-24169.exp
new file mode 100644
index 0000000..120a18b
--- /dev/null
+++ b/find/testsuite/find.gnu/sv-bug-24169.exp
@@ -0,0 +1,47 @@
+# Bug report by Joey Hess.
+#
+# The command:
+# find -neweraa
+# is not valid because there is a missing argument.
+# The result should be a clean exit with nonzero status.
+# However, it segfaults in 4.4.0.
+#
+
+global FTSFIND
+if {[which $FTSFIND] == 0} then {
+ error "$FTSFIND, program does not exist"
+ exit 1
+}
+
+set scriptname [info script]
+set testbase [file rootname $scriptname]
+set test [file tail $testbase]
+set testname "$test.generic"
+
+set cmd "$FTSFIND -neweraa"
+set expected 1
+
+send_log "$cmd\n"
+eval spawn -noecho $cmd
+expect {
+ eof { set result [wait] }
+}
+send_log "result is '$result'\n"
+if { [ lindex $result 2 ] == 0 } then {
+ set status [ lindex $result 3]
+ if { [llength $result] > 4 } then {
+ if { [lindex $result 4] == "CHILDKILLED" } then {
+ fail "$testname, $cmd was killed: [lrange $result 5 end]"
+ } else {
+ unresolved "$testname, $cmd had unexpected extended status $result"
+ }
+ } else {
+ if { $status != 1 } then {
+ unresolved "$testname, $cmd had unexpected status $status"
+ } else {
+ pass "$testname"
+ }
+ }
+} else {
+ unresolved "$testname, failed to run $cmd"
+}
diff --git a/find/testsuite/find.gnu/sv-bug-27563-execdir.exp b/find/testsuite/find.gnu/sv-bug-27563-execdir.exp
new file mode 100644
index 0000000..c67fc88
--- /dev/null
+++ b/find/testsuite/find.gnu/sv-bug-27563-execdir.exp
@@ -0,0 +1,6 @@
+# tests for Savannah bug 27563 (result of find -L -exec ls {} \;)
+exec rm -rf tmp
+exec mkdir tmp
+exec touch tmp/yyyy
+find_start p {-L tmp -name yyyy -execdir ls \{\} \; }
+exec rm -rf tmp
diff --git a/find/testsuite/find.gnu/sv-bug-27563-execdir.xo b/find/testsuite/find.gnu/sv-bug-27563-execdir.xo
new file mode 100644
index 0000000..285260b
--- /dev/null
+++ b/find/testsuite/find.gnu/sv-bug-27563-execdir.xo
@@ -0,0 +1 @@
+./yyyy
diff --git a/find/testsuite/find.gnu/true.exp b/find/testsuite/find.gnu/true.exp
new file mode 100644
index 0000000..3da595b
--- /dev/null
+++ b/find/testsuite/find.gnu/true.exp
@@ -0,0 +1,5 @@
+# test for -true.
+exec rm -rf tmp
+exec mkdir tmp tmp/fred tmp/fred/jim
+find_start p { tmp -depth -print -true -print }
+exec rm -rf tmp
diff --git a/find/testsuite/find.gnu/true.xo b/find/testsuite/find.gnu/true.xo
new file mode 100644
index 0000000..8484390
--- /dev/null
+++ b/find/testsuite/find.gnu/true.xo
@@ -0,0 +1,6 @@
+tmp/fred/jim
+tmp/fred/jim
+tmp/fred
+tmp/fred
+tmp
+tmp
diff --git a/find/testsuite/find.gnu/used-invarg.exp b/find/testsuite/find.gnu/used-invarg.exp
new file mode 100644
index 0000000..966341f
--- /dev/null
+++ b/find/testsuite/find.gnu/used-invarg.exp
@@ -0,0 +1,2 @@
+# tests for invalid argument to -used
+find_start f {. -used ZZ}
diff --git a/find/testsuite/find.gnu/used-missing.exp b/find/testsuite/find.gnu/used-missing.exp
new file mode 100644
index 0000000..6218433
--- /dev/null
+++ b/find/testsuite/find.gnu/used-missing.exp
@@ -0,0 +1,2 @@
+# tests for missing argument to -used
+find_start f {. -used }
diff --git a/find/testsuite/find.gnu/user-invalid.exp b/find/testsuite/find.gnu/user-invalid.exp
new file mode 100644
index 0000000..ee1d02a
--- /dev/null
+++ b/find/testsuite/find.gnu/user-invalid.exp
@@ -0,0 +1,4 @@
+# tests for invalid argument to -user
+foreach user { : "" 14JJ 10.3 -4 } {
+ find_start f ". -user $user"
+}
diff --git a/find/testsuite/find.gnu/wholename.exp b/find/testsuite/find.gnu/wholename.exp
new file mode 100644
index 0000000..128d1ac
--- /dev/null
+++ b/find/testsuite/find.gnu/wholename.exp
@@ -0,0 +1,5 @@
+# test for -wholename
+exec rm -rf tmp
+exec mkdir tmp tmp/top tmp/top/one tmp/top/one/two
+find_start p {tmp/top -wholename tmp/top/one -print }
+exec rm -rf tmp
diff --git a/find/testsuite/find.gnu/wholename.xo b/find/testsuite/find.gnu/wholename.xo
new file mode 100644
index 0000000..66d2877
--- /dev/null
+++ b/find/testsuite/find.gnu/wholename.xo
@@ -0,0 +1 @@
+tmp/top/one
diff --git a/find/testsuite/find.gnu/xtype-symlink.exp b/find/testsuite/find.gnu/xtype-symlink.exp
new file mode 100644
index 0000000..d66a5c0
--- /dev/null
+++ b/find/testsuite/find.gnu/xtype-symlink.exp
@@ -0,0 +1,6 @@
+exec rm -rf tmp
+exec mkdir tmp
+exec touch tmp/file
+exec ln -s file tmp/LINK
+find_start p {tmp/LINK -xtype f }
+exec rm -rf tmp
diff --git a/find/testsuite/find.gnu/xtype-symlink.xo b/find/testsuite/find.gnu/xtype-symlink.xo
new file mode 100644
index 0000000..f46bde2
--- /dev/null
+++ b/find/testsuite/find.gnu/xtype-symlink.xo
@@ -0,0 +1 @@
+tmp/LINK
diff --git a/find/testsuite/find.gnu/xtype.exp b/find/testsuite/find.gnu/xtype.exp
new file mode 100644
index 0000000..62cb749
--- /dev/null
+++ b/find/testsuite/find.gnu/xtype.exp
@@ -0,0 +1,8 @@
+# checks for the -xtype test.
+exec rm -rf tmp
+
+exec mkdir tmp
+exec ln -s /etc/passwd tmp/LINK
+exec ln -s /NOSUCHFILE tmp/BROKEN
+
+find_start p { -H tmp/LINK tmp/BROKEN tmp -xtype l -printf "xtype is l: %p\n" , \! -xtype l -printf "xtype is not l: %p\n" }
diff --git a/find/testsuite/find.gnu/xtype.xo b/find/testsuite/find.gnu/xtype.xo
new file mode 100644
index 0000000..92b74ed
--- /dev/null
+++ b/find/testsuite/find.gnu/xtype.xo
@@ -0,0 +1,5 @@
+xtype is l: tmp/LINK
+xtype is l: tmp/BROKEN
+xtype is not l: tmp
+xtype is not l: tmp/LINK
+xtype is l: tmp/BROKEN
diff --git a/find/testsuite/find.posix/and.exp b/find/testsuite/find.posix/and.exp
new file mode 100644
index 0000000..ac1d622
--- /dev/null
+++ b/find/testsuite/find.posix/and.exp
@@ -0,0 +1,5 @@
+# tests for -name
+exec rm -rf tmp
+exec mkdir tmp tmp/fred tmp/jim
+find_start p {tmp -name fred -a -print}
+exec rm -rf tmp
diff --git a/find/testsuite/find.posix/and.xo b/find/testsuite/find.posix/and.xo
new file mode 100644
index 0000000..8cc8940
--- /dev/null
+++ b/find/testsuite/find.posix/and.xo
@@ -0,0 +1 @@
+tmp/fred
diff --git a/find/testsuite/find.posix/bracket-depth.exp b/find/testsuite/find.posix/bracket-depth.exp
new file mode 100644
index 0000000..8ebadcd
--- /dev/null
+++ b/find/testsuite/find.posix/bracket-depth.exp
@@ -0,0 +1,4 @@
+exec rm -rf tmp
+exec mkdir tmp
+# shoud not result in a fatal error.
+find_start p { tmp \( -depth \) -false -print }
diff --git a/find/testsuite/find.posix/depth1.exp b/find/testsuite/find.posix/depth1.exp
new file mode 100644
index 0000000..c730d22
--- /dev/null
+++ b/find/testsuite/find.posix/depth1.exp
@@ -0,0 +1,7 @@
+# tests for the bug reported at http://lists.gnu.org/archive/html/bug-findutils/2005-02/msg00077.html
+exec rm -rf tmp
+exec mkdir tmp
+exec mkdir tmp/1 tmp/1/2 tmp/1/2/3 tmp/1/2/20 tmp/1/2/37 tmp/1/2/54 tmp/1/2/55 tmp/1/2/55/56 tmp/1/2/55/57 tmp/1/2/55/58 tmp/1/2/55/59
+touch tmp/1/2/3/4 tmp/1/2/3/5 tmp/1/2/3/6 tmp/1/2/3/7 tmp/1/2/3/8 tmp/1/2/3/9 tmp/1/2/3/10 tmp/1/2/3/11 tmp/1/2/3/12 tmp/1/2/3/13 tmp/1/2/3/14 tmp/1/2/3/15 tmp/1/2/3/16 tmp/1/2/3/17 tmp/1/2/3/18 tmp/1/2/3/19 tmp/1/2/20/21 tmp/1/2/20/22 tmp/1/2/20/23 tmp/1/2/20/24 tmp/1/2/20/25 tmp/1/2/20/26 tmp/1/2/20/27 tmp/1/2/20/28 tmp/1/2/20/29 tmp/1/2/20/30 tmp/1/2/20/31 tmp/1/2/20/32 tmp/1/2/20/33 tmp/1/2/20/34 tmp/1/2/20/35 tmp/1/2/20/36 tmp/1/2/37/38 tmp/1/2/37/39 tmp/1/2/37/40 tmp/1/2/37/41 tmp/1/2/37/42 tmp/1/2/37/43 tmp/1/2/37/44 tmp/1/2/37/45 tmp/1/2/37/46 tmp/1/2/37/47 tmp/1/2/37/48 tmp/1/2/37/49 tmp/1/2/37/50 tmp/1/2/37/51 tmp/1/2/37/52 tmp/1/2/37/53 tmp/1/2/60 tmp/1/2/61 tmp/1/2/62 tmp/1/2/63 tmp/1/2/64 tmp/1/2/65 tmp/1/66 tmp/1/67 tmp/1/68 tmp/1/69 tmp/1/70 tmp/1/71 tmp/1/72 tmp/1/73 tmp/1/74 tmp/1/75 tmp/1/76 tmp/1/77 tmp/1/78 tmp/1/79 tmp/1/80 tmp/1/81
+find_start p {tmp/1 -depth -type d -print}
+exec rm -rf tmp
diff --git a/find/testsuite/find.posix/depth1.xo b/find/testsuite/find.posix/depth1.xo
new file mode 100644
index 0000000..0147ad5
--- /dev/null
+++ b/find/testsuite/find.posix/depth1.xo
@@ -0,0 +1,11 @@
+tmp/1
+tmp/1/2
+tmp/1/2/20
+tmp/1/2/3
+tmp/1/2/37
+tmp/1/2/54
+tmp/1/2/55
+tmp/1/2/55/56
+tmp/1/2/55/57
+tmp/1/2/55/58
+tmp/1/2/55/59
diff --git a/find/testsuite/find.posix/dotdotfiles.exp b/find/testsuite/find.posix/dotdotfiles.exp
new file mode 100644
index 0000000..80df7c6
--- /dev/null
+++ b/find/testsuite/find.posix/dotdotfiles.exp
@@ -0,0 +1,8 @@
+# Test entries starting with "..", e.g. "..tmp".
+# Commit v4.5.10-95-ga29e61b introduced a regression
+# which made oldfind(1) skip such entries.
+# This is Savannah bug #45090.
+exec rm -rf tmp
+exec mkdir tmp tmp/..tmp
+find_start p {tmp}
+exec rm -rf tmp
diff --git a/find/testsuite/find.posix/dotdotfiles.xo b/find/testsuite/find.posix/dotdotfiles.xo
new file mode 100644
index 0000000..16b52b2
--- /dev/null
+++ b/find/testsuite/find.posix/dotdotfiles.xo
@@ -0,0 +1,2 @@
+tmp
+tmp/..tmp
diff --git a/find/testsuite/find.posix/empty-parens.exp b/find/testsuite/find.posix/empty-parens.exp
new file mode 100644
index 0000000..abe43df
--- /dev/null
+++ b/find/testsuite/find.posix/empty-parens.exp
@@ -0,0 +1,2 @@
+# empty parentheses should be rejected as being invalid.
+find_start f { . \( -\) }
diff --git a/find/testsuite/find.posix/exec-nogaps.exp b/find/testsuite/find.posix/exec-nogaps.exp
new file mode 100644
index 0000000..108a7a1
--- /dev/null
+++ b/find/testsuite/find.posix/exec-nogaps.exp
@@ -0,0 +1,34 @@
+exec rm -rf tmp
+exec mkdir tmp tmp/a
+
+set testbase [file rootname [info script]]
+set outfile "$testbase.xo"
+send_log "outfile is $outfile\n"
+set file_list {}
+
+set f [open $outfile]
+while {[gets $f filename] >= 0} {
+ lappend flie_list $filename
+ set ftmp [open "$filename" "w"]
+ close $ftmp
+}
+close $f
+
+set script [open tmp/list.sh "w"]
+puts $script {#! /bin/sh
+for f; do echo "$f"; done
+}
+close $script
+exec chmod 0500 tmp/list.sh
+
+send_log "creeating files $file_list\n"
+foreach filename $file_list {
+}
+
+set OPTIMISATION_LEVELS {3}
+find_start p { tmp/a/ -type f -exec echo \{\} \; }
+
+find_start p { tmp/a/ -type f -exec sh tmp/list.sh \{\} \+ }
+
+exec rm -rf tmp/a tmp/list.sh
+exec rmdir tmp
diff --git a/find/testsuite/find.posix/exec-nogaps.xo b/find/testsuite/find.posix/exec-nogaps.xo
new file mode 100644
index 0000000..9330067
--- /dev/null
+++ b/find/testsuite/find.posix/exec-nogaps.xo
@@ -0,0 +1,7200 @@
+tmp/a/1
+tmp/a/2
+tmp/a/3
+tmp/a/4
+tmp/a/5
+tmp/a/6
+tmp/a/7
+tmp/a/8
+tmp/a/9
+tmp/a/10
+tmp/a/11
+tmp/a/12
+tmp/a/13
+tmp/a/14
+tmp/a/15
+tmp/a/16
+tmp/a/17
+tmp/a/18
+tmp/a/19
+tmp/a/20
+tmp/a/21
+tmp/a/22
+tmp/a/23
+tmp/a/24
+tmp/a/25
+tmp/a/26
+tmp/a/27
+tmp/a/28
+tmp/a/29
+tmp/a/30
+tmp/a/31
+tmp/a/32
+tmp/a/33
+tmp/a/34
+tmp/a/35
+tmp/a/36
+tmp/a/37
+tmp/a/38
+tmp/a/39
+tmp/a/40
+tmp/a/41
+tmp/a/42
+tmp/a/43
+tmp/a/44
+tmp/a/45
+tmp/a/46
+tmp/a/47
+tmp/a/48
+tmp/a/49
+tmp/a/50
+tmp/a/51
+tmp/a/52
+tmp/a/53
+tmp/a/54
+tmp/a/55
+tmp/a/56
+tmp/a/57
+tmp/a/58
+tmp/a/59
+tmp/a/60
+tmp/a/61
+tmp/a/62
+tmp/a/63
+tmp/a/64
+tmp/a/65
+tmp/a/66
+tmp/a/67
+tmp/a/68
+tmp/a/69
+tmp/a/70
+tmp/a/71
+tmp/a/72
+tmp/a/73
+tmp/a/74
+tmp/a/75
+tmp/a/76
+tmp/a/77
+tmp/a/78
+tmp/a/79
+tmp/a/80
+tmp/a/81
+tmp/a/82
+tmp/a/83
+tmp/a/84
+tmp/a/85
+tmp/a/86
+tmp/a/87
+tmp/a/88
+tmp/a/89
+tmp/a/90
+tmp/a/91
+tmp/a/92
+tmp/a/93
+tmp/a/94
+tmp/a/95
+tmp/a/96
+tmp/a/97
+tmp/a/98
+tmp/a/99
+tmp/a/100
+tmp/a/101
+tmp/a/102
+tmp/a/103
+tmp/a/104
+tmp/a/105
+tmp/a/106
+tmp/a/107
+tmp/a/108
+tmp/a/109
+tmp/a/110
+tmp/a/111
+tmp/a/112
+tmp/a/113
+tmp/a/114
+tmp/a/115
+tmp/a/116
+tmp/a/117
+tmp/a/118
+tmp/a/119
+tmp/a/120
+tmp/a/121
+tmp/a/122
+tmp/a/123
+tmp/a/124
+tmp/a/125
+tmp/a/126
+tmp/a/127
+tmp/a/128
+tmp/a/129
+tmp/a/130
+tmp/a/131
+tmp/a/132
+tmp/a/133
+tmp/a/134
+tmp/a/135
+tmp/a/136
+tmp/a/137
+tmp/a/138
+tmp/a/139
+tmp/a/140
+tmp/a/141
+tmp/a/142
+tmp/a/143
+tmp/a/144
+tmp/a/145
+tmp/a/146
+tmp/a/147
+tmp/a/148
+tmp/a/149
+tmp/a/150
+tmp/a/151
+tmp/a/152
+tmp/a/153
+tmp/a/154
+tmp/a/155
+tmp/a/156
+tmp/a/157
+tmp/a/158
+tmp/a/159
+tmp/a/160
+tmp/a/161
+tmp/a/162
+tmp/a/163
+tmp/a/164
+tmp/a/165
+tmp/a/166
+tmp/a/167
+tmp/a/168
+tmp/a/169
+tmp/a/170
+tmp/a/171
+tmp/a/172
+tmp/a/173
+tmp/a/174
+tmp/a/175
+tmp/a/176
+tmp/a/177
+tmp/a/178
+tmp/a/179
+tmp/a/180
+tmp/a/181
+tmp/a/182
+tmp/a/183
+tmp/a/184
+tmp/a/185
+tmp/a/186
+tmp/a/187
+tmp/a/188
+tmp/a/189
+tmp/a/190
+tmp/a/191
+tmp/a/192
+tmp/a/193
+tmp/a/194
+tmp/a/195
+tmp/a/196
+tmp/a/197
+tmp/a/198
+tmp/a/199
+tmp/a/200
+tmp/a/201
+tmp/a/202
+tmp/a/203
+tmp/a/204
+tmp/a/205
+tmp/a/206
+tmp/a/207
+tmp/a/208
+tmp/a/209
+tmp/a/210
+tmp/a/211
+tmp/a/212
+tmp/a/213
+tmp/a/214
+tmp/a/215
+tmp/a/216
+tmp/a/217
+tmp/a/218
+tmp/a/219
+tmp/a/220
+tmp/a/221
+tmp/a/222
+tmp/a/223
+tmp/a/224
+tmp/a/225
+tmp/a/226
+tmp/a/227
+tmp/a/228
+tmp/a/229
+tmp/a/230
+tmp/a/231
+tmp/a/232
+tmp/a/233
+tmp/a/234
+tmp/a/235
+tmp/a/236
+tmp/a/237
+tmp/a/238
+tmp/a/239
+tmp/a/240
+tmp/a/241
+tmp/a/242
+tmp/a/243
+tmp/a/244
+tmp/a/245
+tmp/a/246
+tmp/a/247
+tmp/a/248
+tmp/a/249
+tmp/a/250
+tmp/a/251
+tmp/a/252
+tmp/a/253
+tmp/a/254
+tmp/a/255
+tmp/a/256
+tmp/a/257
+tmp/a/258
+tmp/a/259
+tmp/a/260
+tmp/a/261
+tmp/a/262
+tmp/a/263
+tmp/a/264
+tmp/a/265
+tmp/a/266
+tmp/a/267
+tmp/a/268
+tmp/a/269
+tmp/a/270
+tmp/a/271
+tmp/a/272
+tmp/a/273
+tmp/a/274
+tmp/a/275
+tmp/a/276
+tmp/a/277
+tmp/a/278
+tmp/a/279
+tmp/a/280
+tmp/a/281
+tmp/a/282
+tmp/a/283
+tmp/a/284
+tmp/a/285
+tmp/a/286
+tmp/a/287
+tmp/a/288
+tmp/a/289
+tmp/a/290
+tmp/a/291
+tmp/a/292
+tmp/a/293
+tmp/a/294
+tmp/a/295
+tmp/a/296
+tmp/a/297
+tmp/a/298
+tmp/a/299
+tmp/a/300
+tmp/a/301
+tmp/a/302
+tmp/a/303
+tmp/a/304
+tmp/a/305
+tmp/a/306
+tmp/a/307
+tmp/a/308
+tmp/a/309
+tmp/a/310
+tmp/a/311
+tmp/a/312
+tmp/a/313
+tmp/a/314
+tmp/a/315
+tmp/a/316
+tmp/a/317
+tmp/a/318
+tmp/a/319
+tmp/a/320
+tmp/a/321
+tmp/a/322
+tmp/a/323
+tmp/a/324
+tmp/a/325
+tmp/a/326
+tmp/a/327
+tmp/a/328
+tmp/a/329
+tmp/a/330
+tmp/a/331
+tmp/a/332
+tmp/a/333
+tmp/a/334
+tmp/a/335
+tmp/a/336
+tmp/a/337
+tmp/a/338
+tmp/a/339
+tmp/a/340
+tmp/a/341
+tmp/a/342
+tmp/a/343
+tmp/a/344
+tmp/a/345
+tmp/a/346
+tmp/a/347
+tmp/a/348
+tmp/a/349
+tmp/a/350
+tmp/a/351
+tmp/a/352
+tmp/a/353
+tmp/a/354
+tmp/a/355
+tmp/a/356
+tmp/a/357
+tmp/a/358
+tmp/a/359
+tmp/a/360
+tmp/a/361
+tmp/a/362
+tmp/a/363
+tmp/a/364
+tmp/a/365
+tmp/a/366
+tmp/a/367
+tmp/a/368
+tmp/a/369
+tmp/a/370
+tmp/a/371
+tmp/a/372
+tmp/a/373
+tmp/a/374
+tmp/a/375
+tmp/a/376
+tmp/a/377
+tmp/a/378
+tmp/a/379
+tmp/a/380
+tmp/a/381
+tmp/a/382
+tmp/a/383
+tmp/a/384
+tmp/a/385
+tmp/a/386
+tmp/a/387
+tmp/a/388
+tmp/a/389
+tmp/a/390
+tmp/a/391
+tmp/a/392
+tmp/a/393
+tmp/a/394
+tmp/a/395
+tmp/a/396
+tmp/a/397
+tmp/a/398
+tmp/a/399
+tmp/a/400
+tmp/a/401
+tmp/a/402
+tmp/a/403
+tmp/a/404
+tmp/a/405
+tmp/a/406
+tmp/a/407
+tmp/a/408
+tmp/a/409
+tmp/a/410
+tmp/a/411
+tmp/a/412
+tmp/a/413
+tmp/a/414
+tmp/a/415
+tmp/a/416
+tmp/a/417
+tmp/a/418
+tmp/a/419
+tmp/a/420
+tmp/a/421
+tmp/a/422
+tmp/a/423
+tmp/a/424
+tmp/a/425
+tmp/a/426
+tmp/a/427
+tmp/a/428
+tmp/a/429
+tmp/a/430
+tmp/a/431
+tmp/a/432
+tmp/a/433
+tmp/a/434
+tmp/a/435
+tmp/a/436
+tmp/a/437
+tmp/a/438
+tmp/a/439
+tmp/a/440
+tmp/a/441
+tmp/a/442
+tmp/a/443
+tmp/a/444
+tmp/a/445
+tmp/a/446
+tmp/a/447
+tmp/a/448
+tmp/a/449
+tmp/a/450
+tmp/a/451
+tmp/a/452
+tmp/a/453
+tmp/a/454
+tmp/a/455
+tmp/a/456
+tmp/a/457
+tmp/a/458
+tmp/a/459
+tmp/a/460
+tmp/a/461
+tmp/a/462
+tmp/a/463
+tmp/a/464
+tmp/a/465
+tmp/a/466
+tmp/a/467
+tmp/a/468
+tmp/a/469
+tmp/a/470
+tmp/a/471
+tmp/a/472
+tmp/a/473
+tmp/a/474
+tmp/a/475
+tmp/a/476
+tmp/a/477
+tmp/a/478
+tmp/a/479
+tmp/a/480
+tmp/a/481
+tmp/a/482
+tmp/a/483
+tmp/a/484
+tmp/a/485
+tmp/a/486
+tmp/a/487
+tmp/a/488
+tmp/a/489
+tmp/a/490
+tmp/a/491
+tmp/a/492
+tmp/a/493
+tmp/a/494
+tmp/a/495
+tmp/a/496
+tmp/a/497
+tmp/a/498
+tmp/a/499
+tmp/a/500
+tmp/a/501
+tmp/a/502
+tmp/a/503
+tmp/a/504
+tmp/a/505
+tmp/a/506
+tmp/a/507
+tmp/a/508
+tmp/a/509
+tmp/a/510
+tmp/a/511
+tmp/a/512
+tmp/a/513
+tmp/a/514
+tmp/a/515
+tmp/a/516
+tmp/a/517
+tmp/a/518
+tmp/a/519
+tmp/a/520
+tmp/a/521
+tmp/a/522
+tmp/a/523
+tmp/a/524
+tmp/a/525
+tmp/a/526
+tmp/a/527
+tmp/a/528
+tmp/a/529
+tmp/a/530
+tmp/a/531
+tmp/a/532
+tmp/a/533
+tmp/a/534
+tmp/a/535
+tmp/a/536
+tmp/a/537
+tmp/a/538
+tmp/a/539
+tmp/a/540
+tmp/a/541
+tmp/a/542
+tmp/a/543
+tmp/a/544
+tmp/a/545
+tmp/a/546
+tmp/a/547
+tmp/a/548
+tmp/a/549
+tmp/a/550
+tmp/a/551
+tmp/a/552
+tmp/a/553
+tmp/a/554
+tmp/a/555
+tmp/a/556
+tmp/a/557
+tmp/a/558
+tmp/a/559
+tmp/a/560
+tmp/a/561
+tmp/a/562
+tmp/a/563
+tmp/a/564
+tmp/a/565
+tmp/a/566
+tmp/a/567
+tmp/a/568
+tmp/a/569
+tmp/a/570
+tmp/a/571
+tmp/a/572
+tmp/a/573
+tmp/a/574
+tmp/a/575
+tmp/a/576
+tmp/a/577
+tmp/a/578
+tmp/a/579
+tmp/a/580
+tmp/a/581
+tmp/a/582
+tmp/a/583
+tmp/a/584
+tmp/a/585
+tmp/a/586
+tmp/a/587
+tmp/a/588
+tmp/a/589
+tmp/a/590
+tmp/a/591
+tmp/a/592
+tmp/a/593
+tmp/a/594
+tmp/a/595
+tmp/a/596
+tmp/a/597
+tmp/a/598
+tmp/a/599
+tmp/a/600
+tmp/a/601
+tmp/a/602
+tmp/a/603
+tmp/a/604
+tmp/a/605
+tmp/a/606
+tmp/a/607
+tmp/a/608
+tmp/a/609
+tmp/a/610
+tmp/a/611
+tmp/a/612
+tmp/a/613
+tmp/a/614
+tmp/a/615
+tmp/a/616
+tmp/a/617
+tmp/a/618
+tmp/a/619
+tmp/a/620
+tmp/a/621
+tmp/a/622
+tmp/a/623
+tmp/a/624
+tmp/a/625
+tmp/a/626
+tmp/a/627
+tmp/a/628
+tmp/a/629
+tmp/a/630
+tmp/a/631
+tmp/a/632
+tmp/a/633
+tmp/a/634
+tmp/a/635
+tmp/a/636
+tmp/a/637
+tmp/a/638
+tmp/a/639
+tmp/a/640
+tmp/a/641
+tmp/a/642
+tmp/a/643
+tmp/a/644
+tmp/a/645
+tmp/a/646
+tmp/a/647
+tmp/a/648
+tmp/a/649
+tmp/a/650
+tmp/a/651
+tmp/a/652
+tmp/a/653
+tmp/a/654
+tmp/a/655
+tmp/a/656
+tmp/a/657
+tmp/a/658
+tmp/a/659
+tmp/a/660
+tmp/a/661
+tmp/a/662
+tmp/a/663
+tmp/a/664
+tmp/a/665
+tmp/a/666
+tmp/a/667
+tmp/a/668
+tmp/a/669
+tmp/a/670
+tmp/a/671
+tmp/a/672
+tmp/a/673
+tmp/a/674
+tmp/a/675
+tmp/a/676
+tmp/a/677
+tmp/a/678
+tmp/a/679
+tmp/a/680
+tmp/a/681
+tmp/a/682
+tmp/a/683
+tmp/a/684
+tmp/a/685
+tmp/a/686
+tmp/a/687
+tmp/a/688
+tmp/a/689
+tmp/a/690
+tmp/a/691
+tmp/a/692
+tmp/a/693
+tmp/a/694
+tmp/a/695
+tmp/a/696
+tmp/a/697
+tmp/a/698
+tmp/a/699
+tmp/a/700
+tmp/a/701
+tmp/a/702
+tmp/a/703
+tmp/a/704
+tmp/a/705
+tmp/a/706
+tmp/a/707
+tmp/a/708
+tmp/a/709
+tmp/a/710
+tmp/a/711
+tmp/a/712
+tmp/a/713
+tmp/a/714
+tmp/a/715
+tmp/a/716
+tmp/a/717
+tmp/a/718
+tmp/a/719
+tmp/a/720
+tmp/a/721
+tmp/a/722
+tmp/a/723
+tmp/a/724
+tmp/a/725
+tmp/a/726
+tmp/a/727
+tmp/a/728
+tmp/a/729
+tmp/a/730
+tmp/a/731
+tmp/a/732
+tmp/a/733
+tmp/a/734
+tmp/a/735
+tmp/a/736
+tmp/a/737
+tmp/a/738
+tmp/a/739
+tmp/a/740
+tmp/a/741
+tmp/a/742
+tmp/a/743
+tmp/a/744
+tmp/a/745
+tmp/a/746
+tmp/a/747
+tmp/a/748
+tmp/a/749
+tmp/a/750
+tmp/a/751
+tmp/a/752
+tmp/a/753
+tmp/a/754
+tmp/a/755
+tmp/a/756
+tmp/a/757
+tmp/a/758
+tmp/a/759
+tmp/a/760
+tmp/a/761
+tmp/a/762
+tmp/a/763
+tmp/a/764
+tmp/a/765
+tmp/a/766
+tmp/a/767
+tmp/a/768
+tmp/a/769
+tmp/a/770
+tmp/a/771
+tmp/a/772
+tmp/a/773
+tmp/a/774
+tmp/a/775
+tmp/a/776
+tmp/a/777
+tmp/a/778
+tmp/a/779
+tmp/a/780
+tmp/a/781
+tmp/a/782
+tmp/a/783
+tmp/a/784
+tmp/a/785
+tmp/a/786
+tmp/a/787
+tmp/a/788
+tmp/a/789
+tmp/a/790
+tmp/a/791
+tmp/a/792
+tmp/a/793
+tmp/a/794
+tmp/a/795
+tmp/a/796
+tmp/a/797
+tmp/a/798
+tmp/a/799
+tmp/a/800
+tmp/a/801
+tmp/a/802
+tmp/a/803
+tmp/a/804
+tmp/a/805
+tmp/a/806
+tmp/a/807
+tmp/a/808
+tmp/a/809
+tmp/a/810
+tmp/a/811
+tmp/a/812
+tmp/a/813
+tmp/a/814
+tmp/a/815
+tmp/a/816
+tmp/a/817
+tmp/a/818
+tmp/a/819
+tmp/a/820
+tmp/a/821
+tmp/a/822
+tmp/a/823
+tmp/a/824
+tmp/a/825
+tmp/a/826
+tmp/a/827
+tmp/a/828
+tmp/a/829
+tmp/a/830
+tmp/a/831
+tmp/a/832
+tmp/a/833
+tmp/a/834
+tmp/a/835
+tmp/a/836
+tmp/a/837
+tmp/a/838
+tmp/a/839
+tmp/a/840
+tmp/a/841
+tmp/a/842
+tmp/a/843
+tmp/a/844
+tmp/a/845
+tmp/a/846
+tmp/a/847
+tmp/a/848
+tmp/a/849
+tmp/a/850
+tmp/a/851
+tmp/a/852
+tmp/a/853
+tmp/a/854
+tmp/a/855
+tmp/a/856
+tmp/a/857
+tmp/a/858
+tmp/a/859
+tmp/a/860
+tmp/a/861
+tmp/a/862
+tmp/a/863
+tmp/a/864
+tmp/a/865
+tmp/a/866
+tmp/a/867
+tmp/a/868
+tmp/a/869
+tmp/a/870
+tmp/a/871
+tmp/a/872
+tmp/a/873
+tmp/a/874
+tmp/a/875
+tmp/a/876
+tmp/a/877
+tmp/a/878
+tmp/a/879
+tmp/a/880
+tmp/a/881
+tmp/a/882
+tmp/a/883
+tmp/a/884
+tmp/a/885
+tmp/a/886
+tmp/a/887
+tmp/a/888
+tmp/a/889
+tmp/a/890
+tmp/a/891
+tmp/a/892
+tmp/a/893
+tmp/a/894
+tmp/a/895
+tmp/a/896
+tmp/a/897
+tmp/a/898
+tmp/a/899
+tmp/a/900
+tmp/a/901
+tmp/a/902
+tmp/a/903
+tmp/a/904
+tmp/a/905
+tmp/a/906
+tmp/a/907
+tmp/a/908
+tmp/a/909
+tmp/a/910
+tmp/a/911
+tmp/a/912
+tmp/a/913
+tmp/a/914
+tmp/a/915
+tmp/a/916
+tmp/a/917
+tmp/a/918
+tmp/a/919
+tmp/a/920
+tmp/a/921
+tmp/a/922
+tmp/a/923
+tmp/a/924
+tmp/a/925
+tmp/a/926
+tmp/a/927
+tmp/a/928
+tmp/a/929
+tmp/a/930
+tmp/a/931
+tmp/a/932
+tmp/a/933
+tmp/a/934
+tmp/a/935
+tmp/a/936
+tmp/a/937
+tmp/a/938
+tmp/a/939
+tmp/a/940
+tmp/a/941
+tmp/a/942
+tmp/a/943
+tmp/a/944
+tmp/a/945
+tmp/a/946
+tmp/a/947
+tmp/a/948
+tmp/a/949
+tmp/a/950
+tmp/a/951
+tmp/a/952
+tmp/a/953
+tmp/a/954
+tmp/a/955
+tmp/a/956
+tmp/a/957
+tmp/a/958
+tmp/a/959
+tmp/a/960
+tmp/a/961
+tmp/a/962
+tmp/a/963
+tmp/a/964
+tmp/a/965
+tmp/a/966
+tmp/a/967
+tmp/a/968
+tmp/a/969
+tmp/a/970
+tmp/a/971
+tmp/a/972
+tmp/a/973
+tmp/a/974
+tmp/a/975
+tmp/a/976
+tmp/a/977
+tmp/a/978
+tmp/a/979
+tmp/a/980
+tmp/a/981
+tmp/a/982
+tmp/a/983
+tmp/a/984
+tmp/a/985
+tmp/a/986
+tmp/a/987
+tmp/a/988
+tmp/a/989
+tmp/a/990
+tmp/a/991
+tmp/a/992
+tmp/a/993
+tmp/a/994
+tmp/a/995
+tmp/a/996
+tmp/a/997
+tmp/a/998
+tmp/a/999
+tmp/a/1000
+tmp/a/1001
+tmp/a/1002
+tmp/a/1003
+tmp/a/1004
+tmp/a/1005
+tmp/a/1006
+tmp/a/1007
+tmp/a/1008
+tmp/a/1009
+tmp/a/1010
+tmp/a/1011
+tmp/a/1012
+tmp/a/1013
+tmp/a/1014
+tmp/a/1015
+tmp/a/1016
+tmp/a/1017
+tmp/a/1018
+tmp/a/1019
+tmp/a/1020
+tmp/a/1021
+tmp/a/1022
+tmp/a/1023
+tmp/a/1024
+tmp/a/1025
+tmp/a/1026
+tmp/a/1027
+tmp/a/1028
+tmp/a/1029
+tmp/a/1030
+tmp/a/1031
+tmp/a/1032
+tmp/a/1033
+tmp/a/1034
+tmp/a/1035
+tmp/a/1036
+tmp/a/1037
+tmp/a/1038
+tmp/a/1039
+tmp/a/1040
+tmp/a/1041
+tmp/a/1042
+tmp/a/1043
+tmp/a/1044
+tmp/a/1045
+tmp/a/1046
+tmp/a/1047
+tmp/a/1048
+tmp/a/1049
+tmp/a/1050
+tmp/a/1051
+tmp/a/1052
+tmp/a/1053
+tmp/a/1054
+tmp/a/1055
+tmp/a/1056
+tmp/a/1057
+tmp/a/1058
+tmp/a/1059
+tmp/a/1060
+tmp/a/1061
+tmp/a/1062
+tmp/a/1063
+tmp/a/1064
+tmp/a/1065
+tmp/a/1066
+tmp/a/1067
+tmp/a/1068
+tmp/a/1069
+tmp/a/1070
+tmp/a/1071
+tmp/a/1072
+tmp/a/1073
+tmp/a/1074
+tmp/a/1075
+tmp/a/1076
+tmp/a/1077
+tmp/a/1078
+tmp/a/1079
+tmp/a/1080
+tmp/a/1081
+tmp/a/1082
+tmp/a/1083
+tmp/a/1084
+tmp/a/1085
+tmp/a/1086
+tmp/a/1087
+tmp/a/1088
+tmp/a/1089
+tmp/a/1090
+tmp/a/1091
+tmp/a/1092
+tmp/a/1093
+tmp/a/1094
+tmp/a/1095
+tmp/a/1096
+tmp/a/1097
+tmp/a/1098
+tmp/a/1099
+tmp/a/1100
+tmp/a/1101
+tmp/a/1102
+tmp/a/1103
+tmp/a/1104
+tmp/a/1105
+tmp/a/1106
+tmp/a/1107
+tmp/a/1108
+tmp/a/1109
+tmp/a/1110
+tmp/a/1111
+tmp/a/1112
+tmp/a/1113
+tmp/a/1114
+tmp/a/1115
+tmp/a/1116
+tmp/a/1117
+tmp/a/1118
+tmp/a/1119
+tmp/a/1120
+tmp/a/1121
+tmp/a/1122
+tmp/a/1123
+tmp/a/1124
+tmp/a/1125
+tmp/a/1126
+tmp/a/1127
+tmp/a/1128
+tmp/a/1129
+tmp/a/1130
+tmp/a/1131
+tmp/a/1132
+tmp/a/1133
+tmp/a/1134
+tmp/a/1135
+tmp/a/1136
+tmp/a/1137
+tmp/a/1138
+tmp/a/1139
+tmp/a/1140
+tmp/a/1141
+tmp/a/1142
+tmp/a/1143
+tmp/a/1144
+tmp/a/1145
+tmp/a/1146
+tmp/a/1147
+tmp/a/1148
+tmp/a/1149
+tmp/a/1150
+tmp/a/1151
+tmp/a/1152
+tmp/a/1153
+tmp/a/1154
+tmp/a/1155
+tmp/a/1156
+tmp/a/1157
+tmp/a/1158
+tmp/a/1159
+tmp/a/1160
+tmp/a/1161
+tmp/a/1162
+tmp/a/1163
+tmp/a/1164
+tmp/a/1165
+tmp/a/1166
+tmp/a/1167
+tmp/a/1168
+tmp/a/1169
+tmp/a/1170
+tmp/a/1171
+tmp/a/1172
+tmp/a/1173
+tmp/a/1174
+tmp/a/1175
+tmp/a/1176
+tmp/a/1177
+tmp/a/1178
+tmp/a/1179
+tmp/a/1180
+tmp/a/1181
+tmp/a/1182
+tmp/a/1183
+tmp/a/1184
+tmp/a/1185
+tmp/a/1186
+tmp/a/1187
+tmp/a/1188
+tmp/a/1189
+tmp/a/1190
+tmp/a/1191
+tmp/a/1192
+tmp/a/1193
+tmp/a/1194
+tmp/a/1195
+tmp/a/1196
+tmp/a/1197
+tmp/a/1198
+tmp/a/1199
+tmp/a/1200
+tmp/a/1201
+tmp/a/1202
+tmp/a/1203
+tmp/a/1204
+tmp/a/1205
+tmp/a/1206
+tmp/a/1207
+tmp/a/1208
+tmp/a/1209
+tmp/a/1210
+tmp/a/1211
+tmp/a/1212
+tmp/a/1213
+tmp/a/1214
+tmp/a/1215
+tmp/a/1216
+tmp/a/1217
+tmp/a/1218
+tmp/a/1219
+tmp/a/1220
+tmp/a/1221
+tmp/a/1222
+tmp/a/1223
+tmp/a/1224
+tmp/a/1225
+tmp/a/1226
+tmp/a/1227
+tmp/a/1228
+tmp/a/1229
+tmp/a/1230
+tmp/a/1231
+tmp/a/1232
+tmp/a/1233
+tmp/a/1234
+tmp/a/1235
+tmp/a/1236
+tmp/a/1237
+tmp/a/1238
+tmp/a/1239
+tmp/a/1240
+tmp/a/1241
+tmp/a/1242
+tmp/a/1243
+tmp/a/1244
+tmp/a/1245
+tmp/a/1246
+tmp/a/1247
+tmp/a/1248
+tmp/a/1249
+tmp/a/1250
+tmp/a/1251
+tmp/a/1252
+tmp/a/1253
+tmp/a/1254
+tmp/a/1255
+tmp/a/1256
+tmp/a/1257
+tmp/a/1258
+tmp/a/1259
+tmp/a/1260
+tmp/a/1261
+tmp/a/1262
+tmp/a/1263
+tmp/a/1264
+tmp/a/1265
+tmp/a/1266
+tmp/a/1267
+tmp/a/1268
+tmp/a/1269
+tmp/a/1270
+tmp/a/1271
+tmp/a/1272
+tmp/a/1273
+tmp/a/1274
+tmp/a/1275
+tmp/a/1276
+tmp/a/1277
+tmp/a/1278
+tmp/a/1279
+tmp/a/1280
+tmp/a/1281
+tmp/a/1282
+tmp/a/1283
+tmp/a/1284
+tmp/a/1285
+tmp/a/1286
+tmp/a/1287
+tmp/a/1288
+tmp/a/1289
+tmp/a/1290
+tmp/a/1291
+tmp/a/1292
+tmp/a/1293
+tmp/a/1294
+tmp/a/1295
+tmp/a/1296
+tmp/a/1297
+tmp/a/1298
+tmp/a/1299
+tmp/a/1300
+tmp/a/1301
+tmp/a/1302
+tmp/a/1303
+tmp/a/1304
+tmp/a/1305
+tmp/a/1306
+tmp/a/1307
+tmp/a/1308
+tmp/a/1309
+tmp/a/1310
+tmp/a/1311
+tmp/a/1312
+tmp/a/1313
+tmp/a/1314
+tmp/a/1315
+tmp/a/1316
+tmp/a/1317
+tmp/a/1318
+tmp/a/1319
+tmp/a/1320
+tmp/a/1321
+tmp/a/1322
+tmp/a/1323
+tmp/a/1324
+tmp/a/1325
+tmp/a/1326
+tmp/a/1327
+tmp/a/1328
+tmp/a/1329
+tmp/a/1330
+tmp/a/1331
+tmp/a/1332
+tmp/a/1333
+tmp/a/1334
+tmp/a/1335
+tmp/a/1336
+tmp/a/1337
+tmp/a/1338
+tmp/a/1339
+tmp/a/1340
+tmp/a/1341
+tmp/a/1342
+tmp/a/1343
+tmp/a/1344
+tmp/a/1345
+tmp/a/1346
+tmp/a/1347
+tmp/a/1348
+tmp/a/1349
+tmp/a/1350
+tmp/a/1351
+tmp/a/1352
+tmp/a/1353
+tmp/a/1354
+tmp/a/1355
+tmp/a/1356
+tmp/a/1357
+tmp/a/1358
+tmp/a/1359
+tmp/a/1360
+tmp/a/1361
+tmp/a/1362
+tmp/a/1363
+tmp/a/1364
+tmp/a/1365
+tmp/a/1366
+tmp/a/1367
+tmp/a/1368
+tmp/a/1369
+tmp/a/1370
+tmp/a/1371
+tmp/a/1372
+tmp/a/1373
+tmp/a/1374
+tmp/a/1375
+tmp/a/1376
+tmp/a/1377
+tmp/a/1378
+tmp/a/1379
+tmp/a/1380
+tmp/a/1381
+tmp/a/1382
+tmp/a/1383
+tmp/a/1384
+tmp/a/1385
+tmp/a/1386
+tmp/a/1387
+tmp/a/1388
+tmp/a/1389
+tmp/a/1390
+tmp/a/1391
+tmp/a/1392
+tmp/a/1393
+tmp/a/1394
+tmp/a/1395
+tmp/a/1396
+tmp/a/1397
+tmp/a/1398
+tmp/a/1399
+tmp/a/1400
+tmp/a/1401
+tmp/a/1402
+tmp/a/1403
+tmp/a/1404
+tmp/a/1405
+tmp/a/1406
+tmp/a/1407
+tmp/a/1408
+tmp/a/1409
+tmp/a/1410
+tmp/a/1411
+tmp/a/1412
+tmp/a/1413
+tmp/a/1414
+tmp/a/1415
+tmp/a/1416
+tmp/a/1417
+tmp/a/1418
+tmp/a/1419
+tmp/a/1420
+tmp/a/1421
+tmp/a/1422
+tmp/a/1423
+tmp/a/1424
+tmp/a/1425
+tmp/a/1426
+tmp/a/1427
+tmp/a/1428
+tmp/a/1429
+tmp/a/1430
+tmp/a/1431
+tmp/a/1432
+tmp/a/1433
+tmp/a/1434
+tmp/a/1435
+tmp/a/1436
+tmp/a/1437
+tmp/a/1438
+tmp/a/1439
+tmp/a/1440
+tmp/a/1441
+tmp/a/1442
+tmp/a/1443
+tmp/a/1444
+tmp/a/1445
+tmp/a/1446
+tmp/a/1447
+tmp/a/1448
+tmp/a/1449
+tmp/a/1450
+tmp/a/1451
+tmp/a/1452
+tmp/a/1453
+tmp/a/1454
+tmp/a/1455
+tmp/a/1456
+tmp/a/1457
+tmp/a/1458
+tmp/a/1459
+tmp/a/1460
+tmp/a/1461
+tmp/a/1462
+tmp/a/1463
+tmp/a/1464
+tmp/a/1465
+tmp/a/1466
+tmp/a/1467
+tmp/a/1468
+tmp/a/1469
+tmp/a/1470
+tmp/a/1471
+tmp/a/1472
+tmp/a/1473
+tmp/a/1474
+tmp/a/1475
+tmp/a/1476
+tmp/a/1477
+tmp/a/1478
+tmp/a/1479
+tmp/a/1480
+tmp/a/1481
+tmp/a/1482
+tmp/a/1483
+tmp/a/1484
+tmp/a/1485
+tmp/a/1486
+tmp/a/1487
+tmp/a/1488
+tmp/a/1489
+tmp/a/1490
+tmp/a/1491
+tmp/a/1492
+tmp/a/1493
+tmp/a/1494
+tmp/a/1495
+tmp/a/1496
+tmp/a/1497
+tmp/a/1498
+tmp/a/1499
+tmp/a/1500
+tmp/a/1501
+tmp/a/1502
+tmp/a/1503
+tmp/a/1504
+tmp/a/1505
+tmp/a/1506
+tmp/a/1507
+tmp/a/1508
+tmp/a/1509
+tmp/a/1510
+tmp/a/1511
+tmp/a/1512
+tmp/a/1513
+tmp/a/1514
+tmp/a/1515
+tmp/a/1516
+tmp/a/1517
+tmp/a/1518
+tmp/a/1519
+tmp/a/1520
+tmp/a/1521
+tmp/a/1522
+tmp/a/1523
+tmp/a/1524
+tmp/a/1525
+tmp/a/1526
+tmp/a/1527
+tmp/a/1528
+tmp/a/1529
+tmp/a/1530
+tmp/a/1531
+tmp/a/1532
+tmp/a/1533
+tmp/a/1534
+tmp/a/1535
+tmp/a/1536
+tmp/a/1537
+tmp/a/1538
+tmp/a/1539
+tmp/a/1540
+tmp/a/1541
+tmp/a/1542
+tmp/a/1543
+tmp/a/1544
+tmp/a/1545
+tmp/a/1546
+tmp/a/1547
+tmp/a/1548
+tmp/a/1549
+tmp/a/1550
+tmp/a/1551
+tmp/a/1552
+tmp/a/1553
+tmp/a/1554
+tmp/a/1555
+tmp/a/1556
+tmp/a/1557
+tmp/a/1558
+tmp/a/1559
+tmp/a/1560
+tmp/a/1561
+tmp/a/1562
+tmp/a/1563
+tmp/a/1564
+tmp/a/1565
+tmp/a/1566
+tmp/a/1567
+tmp/a/1568
+tmp/a/1569
+tmp/a/1570
+tmp/a/1571
+tmp/a/1572
+tmp/a/1573
+tmp/a/1574
+tmp/a/1575
+tmp/a/1576
+tmp/a/1577
+tmp/a/1578
+tmp/a/1579
+tmp/a/1580
+tmp/a/1581
+tmp/a/1582
+tmp/a/1583
+tmp/a/1584
+tmp/a/1585
+tmp/a/1586
+tmp/a/1587
+tmp/a/1588
+tmp/a/1589
+tmp/a/1590
+tmp/a/1591
+tmp/a/1592
+tmp/a/1593
+tmp/a/1594
+tmp/a/1595
+tmp/a/1596
+tmp/a/1597
+tmp/a/1598
+tmp/a/1599
+tmp/a/1600
+tmp/a/1601
+tmp/a/1602
+tmp/a/1603
+tmp/a/1604
+tmp/a/1605
+tmp/a/1606
+tmp/a/1607
+tmp/a/1608
+tmp/a/1609
+tmp/a/1610
+tmp/a/1611
+tmp/a/1612
+tmp/a/1613
+tmp/a/1614
+tmp/a/1615
+tmp/a/1616
+tmp/a/1617
+tmp/a/1618
+tmp/a/1619
+tmp/a/1620
+tmp/a/1621
+tmp/a/1622
+tmp/a/1623
+tmp/a/1624
+tmp/a/1625
+tmp/a/1626
+tmp/a/1627
+tmp/a/1628
+tmp/a/1629
+tmp/a/1630
+tmp/a/1631
+tmp/a/1632
+tmp/a/1633
+tmp/a/1634
+tmp/a/1635
+tmp/a/1636
+tmp/a/1637
+tmp/a/1638
+tmp/a/1639
+tmp/a/1640
+tmp/a/1641
+tmp/a/1642
+tmp/a/1643
+tmp/a/1644
+tmp/a/1645
+tmp/a/1646
+tmp/a/1647
+tmp/a/1648
+tmp/a/1649
+tmp/a/1650
+tmp/a/1651
+tmp/a/1652
+tmp/a/1653
+tmp/a/1654
+tmp/a/1655
+tmp/a/1656
+tmp/a/1657
+tmp/a/1658
+tmp/a/1659
+tmp/a/1660
+tmp/a/1661
+tmp/a/1662
+tmp/a/1663
+tmp/a/1664
+tmp/a/1665
+tmp/a/1666
+tmp/a/1667
+tmp/a/1668
+tmp/a/1669
+tmp/a/1670
+tmp/a/1671
+tmp/a/1672
+tmp/a/1673
+tmp/a/1674
+tmp/a/1675
+tmp/a/1676
+tmp/a/1677
+tmp/a/1678
+tmp/a/1679
+tmp/a/1680
+tmp/a/1681
+tmp/a/1682
+tmp/a/1683
+tmp/a/1684
+tmp/a/1685
+tmp/a/1686
+tmp/a/1687
+tmp/a/1688
+tmp/a/1689
+tmp/a/1690
+tmp/a/1691
+tmp/a/1692
+tmp/a/1693
+tmp/a/1694
+tmp/a/1695
+tmp/a/1696
+tmp/a/1697
+tmp/a/1698
+tmp/a/1699
+tmp/a/1700
+tmp/a/1701
+tmp/a/1702
+tmp/a/1703
+tmp/a/1704
+tmp/a/1705
+tmp/a/1706
+tmp/a/1707
+tmp/a/1708
+tmp/a/1709
+tmp/a/1710
+tmp/a/1711
+tmp/a/1712
+tmp/a/1713
+tmp/a/1714
+tmp/a/1715
+tmp/a/1716
+tmp/a/1717
+tmp/a/1718
+tmp/a/1719
+tmp/a/1720
+tmp/a/1721
+tmp/a/1722
+tmp/a/1723
+tmp/a/1724
+tmp/a/1725
+tmp/a/1726
+tmp/a/1727
+tmp/a/1728
+tmp/a/1729
+tmp/a/1730
+tmp/a/1731
+tmp/a/1732
+tmp/a/1733
+tmp/a/1734
+tmp/a/1735
+tmp/a/1736
+tmp/a/1737
+tmp/a/1738
+tmp/a/1739
+tmp/a/1740
+tmp/a/1741
+tmp/a/1742
+tmp/a/1743
+tmp/a/1744
+tmp/a/1745
+tmp/a/1746
+tmp/a/1747
+tmp/a/1748
+tmp/a/1749
+tmp/a/1750
+tmp/a/1751
+tmp/a/1752
+tmp/a/1753
+tmp/a/1754
+tmp/a/1755
+tmp/a/1756
+tmp/a/1757
+tmp/a/1758
+tmp/a/1759
+tmp/a/1760
+tmp/a/1761
+tmp/a/1762
+tmp/a/1763
+tmp/a/1764
+tmp/a/1765
+tmp/a/1766
+tmp/a/1767
+tmp/a/1768
+tmp/a/1769
+tmp/a/1770
+tmp/a/1771
+tmp/a/1772
+tmp/a/1773
+tmp/a/1774
+tmp/a/1775
+tmp/a/1776
+tmp/a/1777
+tmp/a/1778
+tmp/a/1779
+tmp/a/1780
+tmp/a/1781
+tmp/a/1782
+tmp/a/1783
+tmp/a/1784
+tmp/a/1785
+tmp/a/1786
+tmp/a/1787
+tmp/a/1788
+tmp/a/1789
+tmp/a/1790
+tmp/a/1791
+tmp/a/1792
+tmp/a/1793
+tmp/a/1794
+tmp/a/1795
+tmp/a/1796
+tmp/a/1797
+tmp/a/1798
+tmp/a/1799
+tmp/a/1800
+tmp/a/1801
+tmp/a/1802
+tmp/a/1803
+tmp/a/1804
+tmp/a/1805
+tmp/a/1806
+tmp/a/1807
+tmp/a/1808
+tmp/a/1809
+tmp/a/1810
+tmp/a/1811
+tmp/a/1812
+tmp/a/1813
+tmp/a/1814
+tmp/a/1815
+tmp/a/1816
+tmp/a/1817
+tmp/a/1818
+tmp/a/1819
+tmp/a/1820
+tmp/a/1821
+tmp/a/1822
+tmp/a/1823
+tmp/a/1824
+tmp/a/1825
+tmp/a/1826
+tmp/a/1827
+tmp/a/1828
+tmp/a/1829
+tmp/a/1830
+tmp/a/1831
+tmp/a/1832
+tmp/a/1833
+tmp/a/1834
+tmp/a/1835
+tmp/a/1836
+tmp/a/1837
+tmp/a/1838
+tmp/a/1839
+tmp/a/1840
+tmp/a/1841
+tmp/a/1842
+tmp/a/1843
+tmp/a/1844
+tmp/a/1845
+tmp/a/1846
+tmp/a/1847
+tmp/a/1848
+tmp/a/1849
+tmp/a/1850
+tmp/a/1851
+tmp/a/1852
+tmp/a/1853
+tmp/a/1854
+tmp/a/1855
+tmp/a/1856
+tmp/a/1857
+tmp/a/1858
+tmp/a/1859
+tmp/a/1860
+tmp/a/1861
+tmp/a/1862
+tmp/a/1863
+tmp/a/1864
+tmp/a/1865
+tmp/a/1866
+tmp/a/1867
+tmp/a/1868
+tmp/a/1869
+tmp/a/1870
+tmp/a/1871
+tmp/a/1872
+tmp/a/1873
+tmp/a/1874
+tmp/a/1875
+tmp/a/1876
+tmp/a/1877
+tmp/a/1878
+tmp/a/1879
+tmp/a/1880
+tmp/a/1881
+tmp/a/1882
+tmp/a/1883
+tmp/a/1884
+tmp/a/1885
+tmp/a/1886
+tmp/a/1887
+tmp/a/1888
+tmp/a/1889
+tmp/a/1890
+tmp/a/1891
+tmp/a/1892
+tmp/a/1893
+tmp/a/1894
+tmp/a/1895
+tmp/a/1896
+tmp/a/1897
+tmp/a/1898
+tmp/a/1899
+tmp/a/1900
+tmp/a/1901
+tmp/a/1902
+tmp/a/1903
+tmp/a/1904
+tmp/a/1905
+tmp/a/1906
+tmp/a/1907
+tmp/a/1908
+tmp/a/1909
+tmp/a/1910
+tmp/a/1911
+tmp/a/1912
+tmp/a/1913
+tmp/a/1914
+tmp/a/1915
+tmp/a/1916
+tmp/a/1917
+tmp/a/1918
+tmp/a/1919
+tmp/a/1920
+tmp/a/1921
+tmp/a/1922
+tmp/a/1923
+tmp/a/1924
+tmp/a/1925
+tmp/a/1926
+tmp/a/1927
+tmp/a/1928
+tmp/a/1929
+tmp/a/1930
+tmp/a/1931
+tmp/a/1932
+tmp/a/1933
+tmp/a/1934
+tmp/a/1935
+tmp/a/1936
+tmp/a/1937
+tmp/a/1938
+tmp/a/1939
+tmp/a/1940
+tmp/a/1941
+tmp/a/1942
+tmp/a/1943
+tmp/a/1944
+tmp/a/1945
+tmp/a/1946
+tmp/a/1947
+tmp/a/1948
+tmp/a/1949
+tmp/a/1950
+tmp/a/1951
+tmp/a/1952
+tmp/a/1953
+tmp/a/1954
+tmp/a/1955
+tmp/a/1956
+tmp/a/1957
+tmp/a/1958
+tmp/a/1959
+tmp/a/1960
+tmp/a/1961
+tmp/a/1962
+tmp/a/1963
+tmp/a/1964
+tmp/a/1965
+tmp/a/1966
+tmp/a/1967
+tmp/a/1968
+tmp/a/1969
+tmp/a/1970
+tmp/a/1971
+tmp/a/1972
+tmp/a/1973
+tmp/a/1974
+tmp/a/1975
+tmp/a/1976
+tmp/a/1977
+tmp/a/1978
+tmp/a/1979
+tmp/a/1980
+tmp/a/1981
+tmp/a/1982
+tmp/a/1983
+tmp/a/1984
+tmp/a/1985
+tmp/a/1986
+tmp/a/1987
+tmp/a/1988
+tmp/a/1989
+tmp/a/1990
+tmp/a/1991
+tmp/a/1992
+tmp/a/1993
+tmp/a/1994
+tmp/a/1995
+tmp/a/1996
+tmp/a/1997
+tmp/a/1998
+tmp/a/1999
+tmp/a/2000
+tmp/a/2001
+tmp/a/2002
+tmp/a/2003
+tmp/a/2004
+tmp/a/2005
+tmp/a/2006
+tmp/a/2007
+tmp/a/2008
+tmp/a/2009
+tmp/a/2010
+tmp/a/2011
+tmp/a/2012
+tmp/a/2013
+tmp/a/2014
+tmp/a/2015
+tmp/a/2016
+tmp/a/2017
+tmp/a/2018
+tmp/a/2019
+tmp/a/2020
+tmp/a/2021
+tmp/a/2022
+tmp/a/2023
+tmp/a/2024
+tmp/a/2025
+tmp/a/2026
+tmp/a/2027
+tmp/a/2028
+tmp/a/2029
+tmp/a/2030
+tmp/a/2031
+tmp/a/2032
+tmp/a/2033
+tmp/a/2034
+tmp/a/2035
+tmp/a/2036
+tmp/a/2037
+tmp/a/2038
+tmp/a/2039
+tmp/a/2040
+tmp/a/2041
+tmp/a/2042
+tmp/a/2043
+tmp/a/2044
+tmp/a/2045
+tmp/a/2046
+tmp/a/2047
+tmp/a/2048
+tmp/a/2049
+tmp/a/2050
+tmp/a/2051
+tmp/a/2052
+tmp/a/2053
+tmp/a/2054
+tmp/a/2055
+tmp/a/2056
+tmp/a/2057
+tmp/a/2058
+tmp/a/2059
+tmp/a/2060
+tmp/a/2061
+tmp/a/2062
+tmp/a/2063
+tmp/a/2064
+tmp/a/2065
+tmp/a/2066
+tmp/a/2067
+tmp/a/2068
+tmp/a/2069
+tmp/a/2070
+tmp/a/2071
+tmp/a/2072
+tmp/a/2073
+tmp/a/2074
+tmp/a/2075
+tmp/a/2076
+tmp/a/2077
+tmp/a/2078
+tmp/a/2079
+tmp/a/2080
+tmp/a/2081
+tmp/a/2082
+tmp/a/2083
+tmp/a/2084
+tmp/a/2085
+tmp/a/2086
+tmp/a/2087
+tmp/a/2088
+tmp/a/2089
+tmp/a/2090
+tmp/a/2091
+tmp/a/2092
+tmp/a/2093
+tmp/a/2094
+tmp/a/2095
+tmp/a/2096
+tmp/a/2097
+tmp/a/2098
+tmp/a/2099
+tmp/a/2100
+tmp/a/2101
+tmp/a/2102
+tmp/a/2103
+tmp/a/2104
+tmp/a/2105
+tmp/a/2106
+tmp/a/2107
+tmp/a/2108
+tmp/a/2109
+tmp/a/2110
+tmp/a/2111
+tmp/a/2112
+tmp/a/2113
+tmp/a/2114
+tmp/a/2115
+tmp/a/2116
+tmp/a/2117
+tmp/a/2118
+tmp/a/2119
+tmp/a/2120
+tmp/a/2121
+tmp/a/2122
+tmp/a/2123
+tmp/a/2124
+tmp/a/2125
+tmp/a/2126
+tmp/a/2127
+tmp/a/2128
+tmp/a/2129
+tmp/a/2130
+tmp/a/2131
+tmp/a/2132
+tmp/a/2133
+tmp/a/2134
+tmp/a/2135
+tmp/a/2136
+tmp/a/2137
+tmp/a/2138
+tmp/a/2139
+tmp/a/2140
+tmp/a/2141
+tmp/a/2142
+tmp/a/2143
+tmp/a/2144
+tmp/a/2145
+tmp/a/2146
+tmp/a/2147
+tmp/a/2148
+tmp/a/2149
+tmp/a/2150
+tmp/a/2151
+tmp/a/2152
+tmp/a/2153
+tmp/a/2154
+tmp/a/2155
+tmp/a/2156
+tmp/a/2157
+tmp/a/2158
+tmp/a/2159
+tmp/a/2160
+tmp/a/2161
+tmp/a/2162
+tmp/a/2163
+tmp/a/2164
+tmp/a/2165
+tmp/a/2166
+tmp/a/2167
+tmp/a/2168
+tmp/a/2169
+tmp/a/2170
+tmp/a/2171
+tmp/a/2172
+tmp/a/2173
+tmp/a/2174
+tmp/a/2175
+tmp/a/2176
+tmp/a/2177
+tmp/a/2178
+tmp/a/2179
+tmp/a/2180
+tmp/a/2181
+tmp/a/2182
+tmp/a/2183
+tmp/a/2184
+tmp/a/2185
+tmp/a/2186
+tmp/a/2187
+tmp/a/2188
+tmp/a/2189
+tmp/a/2190
+tmp/a/2191
+tmp/a/2192
+tmp/a/2193
+tmp/a/2194
+tmp/a/2195
+tmp/a/2196
+tmp/a/2197
+tmp/a/2198
+tmp/a/2199
+tmp/a/2200
+tmp/a/2201
+tmp/a/2202
+tmp/a/2203
+tmp/a/2204
+tmp/a/2205
+tmp/a/2206
+tmp/a/2207
+tmp/a/2208
+tmp/a/2209
+tmp/a/2210
+tmp/a/2211
+tmp/a/2212
+tmp/a/2213
+tmp/a/2214
+tmp/a/2215
+tmp/a/2216
+tmp/a/2217
+tmp/a/2218
+tmp/a/2219
+tmp/a/2220
+tmp/a/2221
+tmp/a/2222
+tmp/a/2223
+tmp/a/2224
+tmp/a/2225
+tmp/a/2226
+tmp/a/2227
+tmp/a/2228
+tmp/a/2229
+tmp/a/2230
+tmp/a/2231
+tmp/a/2232
+tmp/a/2233
+tmp/a/2234
+tmp/a/2235
+tmp/a/2236
+tmp/a/2237
+tmp/a/2238
+tmp/a/2239
+tmp/a/2240
+tmp/a/2241
+tmp/a/2242
+tmp/a/2243
+tmp/a/2244
+tmp/a/2245
+tmp/a/2246
+tmp/a/2247
+tmp/a/2248
+tmp/a/2249
+tmp/a/2250
+tmp/a/2251
+tmp/a/2252
+tmp/a/2253
+tmp/a/2254
+tmp/a/2255
+tmp/a/2256
+tmp/a/2257
+tmp/a/2258
+tmp/a/2259
+tmp/a/2260
+tmp/a/2261
+tmp/a/2262
+tmp/a/2263
+tmp/a/2264
+tmp/a/2265
+tmp/a/2266
+tmp/a/2267
+tmp/a/2268
+tmp/a/2269
+tmp/a/2270
+tmp/a/2271
+tmp/a/2272
+tmp/a/2273
+tmp/a/2274
+tmp/a/2275
+tmp/a/2276
+tmp/a/2277
+tmp/a/2278
+tmp/a/2279
+tmp/a/2280
+tmp/a/2281
+tmp/a/2282
+tmp/a/2283
+tmp/a/2284
+tmp/a/2285
+tmp/a/2286
+tmp/a/2287
+tmp/a/2288
+tmp/a/2289
+tmp/a/2290
+tmp/a/2291
+tmp/a/2292
+tmp/a/2293
+tmp/a/2294
+tmp/a/2295
+tmp/a/2296
+tmp/a/2297
+tmp/a/2298
+tmp/a/2299
+tmp/a/2300
+tmp/a/2301
+tmp/a/2302
+tmp/a/2303
+tmp/a/2304
+tmp/a/2305
+tmp/a/2306
+tmp/a/2307
+tmp/a/2308
+tmp/a/2309
+tmp/a/2310
+tmp/a/2311
+tmp/a/2312
+tmp/a/2313
+tmp/a/2314
+tmp/a/2315
+tmp/a/2316
+tmp/a/2317
+tmp/a/2318
+tmp/a/2319
+tmp/a/2320
+tmp/a/2321
+tmp/a/2322
+tmp/a/2323
+tmp/a/2324
+tmp/a/2325
+tmp/a/2326
+tmp/a/2327
+tmp/a/2328
+tmp/a/2329
+tmp/a/2330
+tmp/a/2331
+tmp/a/2332
+tmp/a/2333
+tmp/a/2334
+tmp/a/2335
+tmp/a/2336
+tmp/a/2337
+tmp/a/2338
+tmp/a/2339
+tmp/a/2340
+tmp/a/2341
+tmp/a/2342
+tmp/a/2343
+tmp/a/2344
+tmp/a/2345
+tmp/a/2346
+tmp/a/2347
+tmp/a/2348
+tmp/a/2349
+tmp/a/2350
+tmp/a/2351
+tmp/a/2352
+tmp/a/2353
+tmp/a/2354
+tmp/a/2355
+tmp/a/2356
+tmp/a/2357
+tmp/a/2358
+tmp/a/2359
+tmp/a/2360
+tmp/a/2361
+tmp/a/2362
+tmp/a/2363
+tmp/a/2364
+tmp/a/2365
+tmp/a/2366
+tmp/a/2367
+tmp/a/2368
+tmp/a/2369
+tmp/a/2370
+tmp/a/2371
+tmp/a/2372
+tmp/a/2373
+tmp/a/2374
+tmp/a/2375
+tmp/a/2376
+tmp/a/2377
+tmp/a/2378
+tmp/a/2379
+tmp/a/2380
+tmp/a/2381
+tmp/a/2382
+tmp/a/2383
+tmp/a/2384
+tmp/a/2385
+tmp/a/2386
+tmp/a/2387
+tmp/a/2388
+tmp/a/2389
+tmp/a/2390
+tmp/a/2391
+tmp/a/2392
+tmp/a/2393
+tmp/a/2394
+tmp/a/2395
+tmp/a/2396
+tmp/a/2397
+tmp/a/2398
+tmp/a/2399
+tmp/a/2400
+tmp/a/2401
+tmp/a/2402
+tmp/a/2403
+tmp/a/2404
+tmp/a/2405
+tmp/a/2406
+tmp/a/2407
+tmp/a/2408
+tmp/a/2409
+tmp/a/2410
+tmp/a/2411
+tmp/a/2412
+tmp/a/2413
+tmp/a/2414
+tmp/a/2415
+tmp/a/2416
+tmp/a/2417
+tmp/a/2418
+tmp/a/2419
+tmp/a/2420
+tmp/a/2421
+tmp/a/2422
+tmp/a/2423
+tmp/a/2424
+tmp/a/2425
+tmp/a/2426
+tmp/a/2427
+tmp/a/2428
+tmp/a/2429
+tmp/a/2430
+tmp/a/2431
+tmp/a/2432
+tmp/a/2433
+tmp/a/2434
+tmp/a/2435
+tmp/a/2436
+tmp/a/2437
+tmp/a/2438
+tmp/a/2439
+tmp/a/2440
+tmp/a/2441
+tmp/a/2442
+tmp/a/2443
+tmp/a/2444
+tmp/a/2445
+tmp/a/2446
+tmp/a/2447
+tmp/a/2448
+tmp/a/2449
+tmp/a/2450
+tmp/a/2451
+tmp/a/2452
+tmp/a/2453
+tmp/a/2454
+tmp/a/2455
+tmp/a/2456
+tmp/a/2457
+tmp/a/2458
+tmp/a/2459
+tmp/a/2460
+tmp/a/2461
+tmp/a/2462
+tmp/a/2463
+tmp/a/2464
+tmp/a/2465
+tmp/a/2466
+tmp/a/2467
+tmp/a/2468
+tmp/a/2469
+tmp/a/2470
+tmp/a/2471
+tmp/a/2472
+tmp/a/2473
+tmp/a/2474
+tmp/a/2475
+tmp/a/2476
+tmp/a/2477
+tmp/a/2478
+tmp/a/2479
+tmp/a/2480
+tmp/a/2481
+tmp/a/2482
+tmp/a/2483
+tmp/a/2484
+tmp/a/2485
+tmp/a/2486
+tmp/a/2487
+tmp/a/2488
+tmp/a/2489
+tmp/a/2490
+tmp/a/2491
+tmp/a/2492
+tmp/a/2493
+tmp/a/2494
+tmp/a/2495
+tmp/a/2496
+tmp/a/2497
+tmp/a/2498
+tmp/a/2499
+tmp/a/2500
+tmp/a/2501
+tmp/a/2502
+tmp/a/2503
+tmp/a/2504
+tmp/a/2505
+tmp/a/2506
+tmp/a/2507
+tmp/a/2508
+tmp/a/2509
+tmp/a/2510
+tmp/a/2511
+tmp/a/2512
+tmp/a/2513
+tmp/a/2514
+tmp/a/2515
+tmp/a/2516
+tmp/a/2517
+tmp/a/2518
+tmp/a/2519
+tmp/a/2520
+tmp/a/2521
+tmp/a/2522
+tmp/a/2523
+tmp/a/2524
+tmp/a/2525
+tmp/a/2526
+tmp/a/2527
+tmp/a/2528
+tmp/a/2529
+tmp/a/2530
+tmp/a/2531
+tmp/a/2532
+tmp/a/2533
+tmp/a/2534
+tmp/a/2535
+tmp/a/2536
+tmp/a/2537
+tmp/a/2538
+tmp/a/2539
+tmp/a/2540
+tmp/a/2541
+tmp/a/2542
+tmp/a/2543
+tmp/a/2544
+tmp/a/2545
+tmp/a/2546
+tmp/a/2547
+tmp/a/2548
+tmp/a/2549
+tmp/a/2550
+tmp/a/2551
+tmp/a/2552
+tmp/a/2553
+tmp/a/2554
+tmp/a/2555
+tmp/a/2556
+tmp/a/2557
+tmp/a/2558
+tmp/a/2559
+tmp/a/2560
+tmp/a/2561
+tmp/a/2562
+tmp/a/2563
+tmp/a/2564
+tmp/a/2565
+tmp/a/2566
+tmp/a/2567
+tmp/a/2568
+tmp/a/2569
+tmp/a/2570
+tmp/a/2571
+tmp/a/2572
+tmp/a/2573
+tmp/a/2574
+tmp/a/2575
+tmp/a/2576
+tmp/a/2577
+tmp/a/2578
+tmp/a/2579
+tmp/a/2580
+tmp/a/2581
+tmp/a/2582
+tmp/a/2583
+tmp/a/2584
+tmp/a/2585
+tmp/a/2586
+tmp/a/2587
+tmp/a/2588
+tmp/a/2589
+tmp/a/2590
+tmp/a/2591
+tmp/a/2592
+tmp/a/2593
+tmp/a/2594
+tmp/a/2595
+tmp/a/2596
+tmp/a/2597
+tmp/a/2598
+tmp/a/2599
+tmp/a/2600
+tmp/a/2601
+tmp/a/2602
+tmp/a/2603
+tmp/a/2604
+tmp/a/2605
+tmp/a/2606
+tmp/a/2607
+tmp/a/2608
+tmp/a/2609
+tmp/a/2610
+tmp/a/2611
+tmp/a/2612
+tmp/a/2613
+tmp/a/2614
+tmp/a/2615
+tmp/a/2616
+tmp/a/2617
+tmp/a/2618
+tmp/a/2619
+tmp/a/2620
+tmp/a/2621
+tmp/a/2622
+tmp/a/2623
+tmp/a/2624
+tmp/a/2625
+tmp/a/2626
+tmp/a/2627
+tmp/a/2628
+tmp/a/2629
+tmp/a/2630
+tmp/a/2631
+tmp/a/2632
+tmp/a/2633
+tmp/a/2634
+tmp/a/2635
+tmp/a/2636
+tmp/a/2637
+tmp/a/2638
+tmp/a/2639
+tmp/a/2640
+tmp/a/2641
+tmp/a/2642
+tmp/a/2643
+tmp/a/2644
+tmp/a/2645
+tmp/a/2646
+tmp/a/2647
+tmp/a/2648
+tmp/a/2649
+tmp/a/2650
+tmp/a/2651
+tmp/a/2652
+tmp/a/2653
+tmp/a/2654
+tmp/a/2655
+tmp/a/2656
+tmp/a/2657
+tmp/a/2658
+tmp/a/2659
+tmp/a/2660
+tmp/a/2661
+tmp/a/2662
+tmp/a/2663
+tmp/a/2664
+tmp/a/2665
+tmp/a/2666
+tmp/a/2667
+tmp/a/2668
+tmp/a/2669
+tmp/a/2670
+tmp/a/2671
+tmp/a/2672
+tmp/a/2673
+tmp/a/2674
+tmp/a/2675
+tmp/a/2676
+tmp/a/2677
+tmp/a/2678
+tmp/a/2679
+tmp/a/2680
+tmp/a/2681
+tmp/a/2682
+tmp/a/2683
+tmp/a/2684
+tmp/a/2685
+tmp/a/2686
+tmp/a/2687
+tmp/a/2688
+tmp/a/2689
+tmp/a/2690
+tmp/a/2691
+tmp/a/2692
+tmp/a/2693
+tmp/a/2694
+tmp/a/2695
+tmp/a/2696
+tmp/a/2697
+tmp/a/2698
+tmp/a/2699
+tmp/a/2700
+tmp/a/2701
+tmp/a/2702
+tmp/a/2703
+tmp/a/2704
+tmp/a/2705
+tmp/a/2706
+tmp/a/2707
+tmp/a/2708
+tmp/a/2709
+tmp/a/2710
+tmp/a/2711
+tmp/a/2712
+tmp/a/2713
+tmp/a/2714
+tmp/a/2715
+tmp/a/2716
+tmp/a/2717
+tmp/a/2718
+tmp/a/2719
+tmp/a/2720
+tmp/a/2721
+tmp/a/2722
+tmp/a/2723
+tmp/a/2724
+tmp/a/2725
+tmp/a/2726
+tmp/a/2727
+tmp/a/2728
+tmp/a/2729
+tmp/a/2730
+tmp/a/2731
+tmp/a/2732
+tmp/a/2733
+tmp/a/2734
+tmp/a/2735
+tmp/a/2736
+tmp/a/2737
+tmp/a/2738
+tmp/a/2739
+tmp/a/2740
+tmp/a/2741
+tmp/a/2742
+tmp/a/2743
+tmp/a/2744
+tmp/a/2745
+tmp/a/2746
+tmp/a/2747
+tmp/a/2748
+tmp/a/2749
+tmp/a/2750
+tmp/a/2751
+tmp/a/2752
+tmp/a/2753
+tmp/a/2754
+tmp/a/2755
+tmp/a/2756
+tmp/a/2757
+tmp/a/2758
+tmp/a/2759
+tmp/a/2760
+tmp/a/2761
+tmp/a/2762
+tmp/a/2763
+tmp/a/2764
+tmp/a/2765
+tmp/a/2766
+tmp/a/2767
+tmp/a/2768
+tmp/a/2769
+tmp/a/2770
+tmp/a/2771
+tmp/a/2772
+tmp/a/2773
+tmp/a/2774
+tmp/a/2775
+tmp/a/2776
+tmp/a/2777
+tmp/a/2778
+tmp/a/2779
+tmp/a/2780
+tmp/a/2781
+tmp/a/2782
+tmp/a/2783
+tmp/a/2784
+tmp/a/2785
+tmp/a/2786
+tmp/a/2787
+tmp/a/2788
+tmp/a/2789
+tmp/a/2790
+tmp/a/2791
+tmp/a/2792
+tmp/a/2793
+tmp/a/2794
+tmp/a/2795
+tmp/a/2796
+tmp/a/2797
+tmp/a/2798
+tmp/a/2799
+tmp/a/2800
+tmp/a/2801
+tmp/a/2802
+tmp/a/2803
+tmp/a/2804
+tmp/a/2805
+tmp/a/2806
+tmp/a/2807
+tmp/a/2808
+tmp/a/2809
+tmp/a/2810
+tmp/a/2811
+tmp/a/2812
+tmp/a/2813
+tmp/a/2814
+tmp/a/2815
+tmp/a/2816
+tmp/a/2817
+tmp/a/2818
+tmp/a/2819
+tmp/a/2820
+tmp/a/2821
+tmp/a/2822
+tmp/a/2823
+tmp/a/2824
+tmp/a/2825
+tmp/a/2826
+tmp/a/2827
+tmp/a/2828
+tmp/a/2829
+tmp/a/2830
+tmp/a/2831
+tmp/a/2832
+tmp/a/2833
+tmp/a/2834
+tmp/a/2835
+tmp/a/2836
+tmp/a/2837
+tmp/a/2838
+tmp/a/2839
+tmp/a/2840
+tmp/a/2841
+tmp/a/2842
+tmp/a/2843
+tmp/a/2844
+tmp/a/2845
+tmp/a/2846
+tmp/a/2847
+tmp/a/2848
+tmp/a/2849
+tmp/a/2850
+tmp/a/2851
+tmp/a/2852
+tmp/a/2853
+tmp/a/2854
+tmp/a/2855
+tmp/a/2856
+tmp/a/2857
+tmp/a/2858
+tmp/a/2859
+tmp/a/2860
+tmp/a/2861
+tmp/a/2862
+tmp/a/2863
+tmp/a/2864
+tmp/a/2865
+tmp/a/2866
+tmp/a/2867
+tmp/a/2868
+tmp/a/2869
+tmp/a/2870
+tmp/a/2871
+tmp/a/2872
+tmp/a/2873
+tmp/a/2874
+tmp/a/2875
+tmp/a/2876
+tmp/a/2877
+tmp/a/2878
+tmp/a/2879
+tmp/a/2880
+tmp/a/2881
+tmp/a/2882
+tmp/a/2883
+tmp/a/2884
+tmp/a/2885
+tmp/a/2886
+tmp/a/2887
+tmp/a/2888
+tmp/a/2889
+tmp/a/2890
+tmp/a/2891
+tmp/a/2892
+tmp/a/2893
+tmp/a/2894
+tmp/a/2895
+tmp/a/2896
+tmp/a/2897
+tmp/a/2898
+tmp/a/2899
+tmp/a/2900
+tmp/a/2901
+tmp/a/2902
+tmp/a/2903
+tmp/a/2904
+tmp/a/2905
+tmp/a/2906
+tmp/a/2907
+tmp/a/2908
+tmp/a/2909
+tmp/a/2910
+tmp/a/2911
+tmp/a/2912
+tmp/a/2913
+tmp/a/2914
+tmp/a/2915
+tmp/a/2916
+tmp/a/2917
+tmp/a/2918
+tmp/a/2919
+tmp/a/2920
+tmp/a/2921
+tmp/a/2922
+tmp/a/2923
+tmp/a/2924
+tmp/a/2925
+tmp/a/2926
+tmp/a/2927
+tmp/a/2928
+tmp/a/2929
+tmp/a/2930
+tmp/a/2931
+tmp/a/2932
+tmp/a/2933
+tmp/a/2934
+tmp/a/2935
+tmp/a/2936
+tmp/a/2937
+tmp/a/2938
+tmp/a/2939
+tmp/a/2940
+tmp/a/2941
+tmp/a/2942
+tmp/a/2943
+tmp/a/2944
+tmp/a/2945
+tmp/a/2946
+tmp/a/2947
+tmp/a/2948
+tmp/a/2949
+tmp/a/2950
+tmp/a/2951
+tmp/a/2952
+tmp/a/2953
+tmp/a/2954
+tmp/a/2955
+tmp/a/2956
+tmp/a/2957
+tmp/a/2958
+tmp/a/2959
+tmp/a/2960
+tmp/a/2961
+tmp/a/2962
+tmp/a/2963
+tmp/a/2964
+tmp/a/2965
+tmp/a/2966
+tmp/a/2967
+tmp/a/2968
+tmp/a/2969
+tmp/a/2970
+tmp/a/2971
+tmp/a/2972
+tmp/a/2973
+tmp/a/2974
+tmp/a/2975
+tmp/a/2976
+tmp/a/2977
+tmp/a/2978
+tmp/a/2979
+tmp/a/2980
+tmp/a/2981
+tmp/a/2982
+tmp/a/2983
+tmp/a/2984
+tmp/a/2985
+tmp/a/2986
+tmp/a/2987
+tmp/a/2988
+tmp/a/2989
+tmp/a/2990
+tmp/a/2991
+tmp/a/2992
+tmp/a/2993
+tmp/a/2994
+tmp/a/2995
+tmp/a/2996
+tmp/a/2997
+tmp/a/2998
+tmp/a/2999
+tmp/a/3000
+tmp/a/3001
+tmp/a/3002
+tmp/a/3003
+tmp/a/3004
+tmp/a/3005
+tmp/a/3006
+tmp/a/3007
+tmp/a/3008
+tmp/a/3009
+tmp/a/3010
+tmp/a/3011
+tmp/a/3012
+tmp/a/3013
+tmp/a/3014
+tmp/a/3015
+tmp/a/3016
+tmp/a/3017
+tmp/a/3018
+tmp/a/3019
+tmp/a/3020
+tmp/a/3021
+tmp/a/3022
+tmp/a/3023
+tmp/a/3024
+tmp/a/3025
+tmp/a/3026
+tmp/a/3027
+tmp/a/3028
+tmp/a/3029
+tmp/a/3030
+tmp/a/3031
+tmp/a/3032
+tmp/a/3033
+tmp/a/3034
+tmp/a/3035
+tmp/a/3036
+tmp/a/3037
+tmp/a/3038
+tmp/a/3039
+tmp/a/3040
+tmp/a/3041
+tmp/a/3042
+tmp/a/3043
+tmp/a/3044
+tmp/a/3045
+tmp/a/3046
+tmp/a/3047
+tmp/a/3048
+tmp/a/3049
+tmp/a/3050
+tmp/a/3051
+tmp/a/3052
+tmp/a/3053
+tmp/a/3054
+tmp/a/3055
+tmp/a/3056
+tmp/a/3057
+tmp/a/3058
+tmp/a/3059
+tmp/a/3060
+tmp/a/3061
+tmp/a/3062
+tmp/a/3063
+tmp/a/3064
+tmp/a/3065
+tmp/a/3066
+tmp/a/3067
+tmp/a/3068
+tmp/a/3069
+tmp/a/3070
+tmp/a/3071
+tmp/a/3072
+tmp/a/3073
+tmp/a/3074
+tmp/a/3075
+tmp/a/3076
+tmp/a/3077
+tmp/a/3078
+tmp/a/3079
+tmp/a/3080
+tmp/a/3081
+tmp/a/3082
+tmp/a/3083
+tmp/a/3084
+tmp/a/3085
+tmp/a/3086
+tmp/a/3087
+tmp/a/3088
+tmp/a/3089
+tmp/a/3090
+tmp/a/3091
+tmp/a/3092
+tmp/a/3093
+tmp/a/3094
+tmp/a/3095
+tmp/a/3096
+tmp/a/3097
+tmp/a/3098
+tmp/a/3099
+tmp/a/3100
+tmp/a/3101
+tmp/a/3102
+tmp/a/3103
+tmp/a/3104
+tmp/a/3105
+tmp/a/3106
+tmp/a/3107
+tmp/a/3108
+tmp/a/3109
+tmp/a/3110
+tmp/a/3111
+tmp/a/3112
+tmp/a/3113
+tmp/a/3114
+tmp/a/3115
+tmp/a/3116
+tmp/a/3117
+tmp/a/3118
+tmp/a/3119
+tmp/a/3120
+tmp/a/3121
+tmp/a/3122
+tmp/a/3123
+tmp/a/3124
+tmp/a/3125
+tmp/a/3126
+tmp/a/3127
+tmp/a/3128
+tmp/a/3129
+tmp/a/3130
+tmp/a/3131
+tmp/a/3132
+tmp/a/3133
+tmp/a/3134
+tmp/a/3135
+tmp/a/3136
+tmp/a/3137
+tmp/a/3138
+tmp/a/3139
+tmp/a/3140
+tmp/a/3141
+tmp/a/3142
+tmp/a/3143
+tmp/a/3144
+tmp/a/3145
+tmp/a/3146
+tmp/a/3147
+tmp/a/3148
+tmp/a/3149
+tmp/a/3150
+tmp/a/3151
+tmp/a/3152
+tmp/a/3153
+tmp/a/3154
+tmp/a/3155
+tmp/a/3156
+tmp/a/3157
+tmp/a/3158
+tmp/a/3159
+tmp/a/3160
+tmp/a/3161
+tmp/a/3162
+tmp/a/3163
+tmp/a/3164
+tmp/a/3165
+tmp/a/3166
+tmp/a/3167
+tmp/a/3168
+tmp/a/3169
+tmp/a/3170
+tmp/a/3171
+tmp/a/3172
+tmp/a/3173
+tmp/a/3174
+tmp/a/3175
+tmp/a/3176
+tmp/a/3177
+tmp/a/3178
+tmp/a/3179
+tmp/a/3180
+tmp/a/3181
+tmp/a/3182
+tmp/a/3183
+tmp/a/3184
+tmp/a/3185
+tmp/a/3186
+tmp/a/3187
+tmp/a/3188
+tmp/a/3189
+tmp/a/3190
+tmp/a/3191
+tmp/a/3192
+tmp/a/3193
+tmp/a/3194
+tmp/a/3195
+tmp/a/3196
+tmp/a/3197
+tmp/a/3198
+tmp/a/3199
+tmp/a/3200
+tmp/a/3201
+tmp/a/3202
+tmp/a/3203
+tmp/a/3204
+tmp/a/3205
+tmp/a/3206
+tmp/a/3207
+tmp/a/3208
+tmp/a/3209
+tmp/a/3210
+tmp/a/3211
+tmp/a/3212
+tmp/a/3213
+tmp/a/3214
+tmp/a/3215
+tmp/a/3216
+tmp/a/3217
+tmp/a/3218
+tmp/a/3219
+tmp/a/3220
+tmp/a/3221
+tmp/a/3222
+tmp/a/3223
+tmp/a/3224
+tmp/a/3225
+tmp/a/3226
+tmp/a/3227
+tmp/a/3228
+tmp/a/3229
+tmp/a/3230
+tmp/a/3231
+tmp/a/3232
+tmp/a/3233
+tmp/a/3234
+tmp/a/3235
+tmp/a/3236
+tmp/a/3237
+tmp/a/3238
+tmp/a/3239
+tmp/a/3240
+tmp/a/3241
+tmp/a/3242
+tmp/a/3243
+tmp/a/3244
+tmp/a/3245
+tmp/a/3246
+tmp/a/3247
+tmp/a/3248
+tmp/a/3249
+tmp/a/3250
+tmp/a/3251
+tmp/a/3252
+tmp/a/3253
+tmp/a/3254
+tmp/a/3255
+tmp/a/3256
+tmp/a/3257
+tmp/a/3258
+tmp/a/3259
+tmp/a/3260
+tmp/a/3261
+tmp/a/3262
+tmp/a/3263
+tmp/a/3264
+tmp/a/3265
+tmp/a/3266
+tmp/a/3267
+tmp/a/3268
+tmp/a/3269
+tmp/a/3270
+tmp/a/3271
+tmp/a/3272
+tmp/a/3273
+tmp/a/3274
+tmp/a/3275
+tmp/a/3276
+tmp/a/3277
+tmp/a/3278
+tmp/a/3279
+tmp/a/3280
+tmp/a/3281
+tmp/a/3282
+tmp/a/3283
+tmp/a/3284
+tmp/a/3285
+tmp/a/3286
+tmp/a/3287
+tmp/a/3288
+tmp/a/3289
+tmp/a/3290
+tmp/a/3291
+tmp/a/3292
+tmp/a/3293
+tmp/a/3294
+tmp/a/3295
+tmp/a/3296
+tmp/a/3297
+tmp/a/3298
+tmp/a/3299
+tmp/a/3300
+tmp/a/3301
+tmp/a/3302
+tmp/a/3303
+tmp/a/3304
+tmp/a/3305
+tmp/a/3306
+tmp/a/3307
+tmp/a/3308
+tmp/a/3309
+tmp/a/3310
+tmp/a/3311
+tmp/a/3312
+tmp/a/3313
+tmp/a/3314
+tmp/a/3315
+tmp/a/3316
+tmp/a/3317
+tmp/a/3318
+tmp/a/3319
+tmp/a/3320
+tmp/a/3321
+tmp/a/3322
+tmp/a/3323
+tmp/a/3324
+tmp/a/3325
+tmp/a/3326
+tmp/a/3327
+tmp/a/3328
+tmp/a/3329
+tmp/a/3330
+tmp/a/3331
+tmp/a/3332
+tmp/a/3333
+tmp/a/3334
+tmp/a/3335
+tmp/a/3336
+tmp/a/3337
+tmp/a/3338
+tmp/a/3339
+tmp/a/3340
+tmp/a/3341
+tmp/a/3342
+tmp/a/3343
+tmp/a/3344
+tmp/a/3345
+tmp/a/3346
+tmp/a/3347
+tmp/a/3348
+tmp/a/3349
+tmp/a/3350
+tmp/a/3351
+tmp/a/3352
+tmp/a/3353
+tmp/a/3354
+tmp/a/3355
+tmp/a/3356
+tmp/a/3357
+tmp/a/3358
+tmp/a/3359
+tmp/a/3360
+tmp/a/3361
+tmp/a/3362
+tmp/a/3363
+tmp/a/3364
+tmp/a/3365
+tmp/a/3366
+tmp/a/3367
+tmp/a/3368
+tmp/a/3369
+tmp/a/3370
+tmp/a/3371
+tmp/a/3372
+tmp/a/3373
+tmp/a/3374
+tmp/a/3375
+tmp/a/3376
+tmp/a/3377
+tmp/a/3378
+tmp/a/3379
+tmp/a/3380
+tmp/a/3381
+tmp/a/3382
+tmp/a/3383
+tmp/a/3384
+tmp/a/3385
+tmp/a/3386
+tmp/a/3387
+tmp/a/3388
+tmp/a/3389
+tmp/a/3390
+tmp/a/3391
+tmp/a/3392
+tmp/a/3393
+tmp/a/3394
+tmp/a/3395
+tmp/a/3396
+tmp/a/3397
+tmp/a/3398
+tmp/a/3399
+tmp/a/3400
+tmp/a/3401
+tmp/a/3402
+tmp/a/3403
+tmp/a/3404
+tmp/a/3405
+tmp/a/3406
+tmp/a/3407
+tmp/a/3408
+tmp/a/3409
+tmp/a/3410
+tmp/a/3411
+tmp/a/3412
+tmp/a/3413
+tmp/a/3414
+tmp/a/3415
+tmp/a/3416
+tmp/a/3417
+tmp/a/3418
+tmp/a/3419
+tmp/a/3420
+tmp/a/3421
+tmp/a/3422
+tmp/a/3423
+tmp/a/3424
+tmp/a/3425
+tmp/a/3426
+tmp/a/3427
+tmp/a/3428
+tmp/a/3429
+tmp/a/3430
+tmp/a/3431
+tmp/a/3432
+tmp/a/3433
+tmp/a/3434
+tmp/a/3435
+tmp/a/3436
+tmp/a/3437
+tmp/a/3438
+tmp/a/3439
+tmp/a/3440
+tmp/a/3441
+tmp/a/3442
+tmp/a/3443
+tmp/a/3444
+tmp/a/3445
+tmp/a/3446
+tmp/a/3447
+tmp/a/3448
+tmp/a/3449
+tmp/a/3450
+tmp/a/3451
+tmp/a/3452
+tmp/a/3453
+tmp/a/3454
+tmp/a/3455
+tmp/a/3456
+tmp/a/3457
+tmp/a/3458
+tmp/a/3459
+tmp/a/3460
+tmp/a/3461
+tmp/a/3462
+tmp/a/3463
+tmp/a/3464
+tmp/a/3465
+tmp/a/3466
+tmp/a/3467
+tmp/a/3468
+tmp/a/3469
+tmp/a/3470
+tmp/a/3471
+tmp/a/3472
+tmp/a/3473
+tmp/a/3474
+tmp/a/3475
+tmp/a/3476
+tmp/a/3477
+tmp/a/3478
+tmp/a/3479
+tmp/a/3480
+tmp/a/3481
+tmp/a/3482
+tmp/a/3483
+tmp/a/3484
+tmp/a/3485
+tmp/a/3486
+tmp/a/3487
+tmp/a/3488
+tmp/a/3489
+tmp/a/3490
+tmp/a/3491
+tmp/a/3492
+tmp/a/3493
+tmp/a/3494
+tmp/a/3495
+tmp/a/3496
+tmp/a/3497
+tmp/a/3498
+tmp/a/3499
+tmp/a/3500
+tmp/a/3501
+tmp/a/3502
+tmp/a/3503
+tmp/a/3504
+tmp/a/3505
+tmp/a/3506
+tmp/a/3507
+tmp/a/3508
+tmp/a/3509
+tmp/a/3510
+tmp/a/3511
+tmp/a/3512
+tmp/a/3513
+tmp/a/3514
+tmp/a/3515
+tmp/a/3516
+tmp/a/3517
+tmp/a/3518
+tmp/a/3519
+tmp/a/3520
+tmp/a/3521
+tmp/a/3522
+tmp/a/3523
+tmp/a/3524
+tmp/a/3525
+tmp/a/3526
+tmp/a/3527
+tmp/a/3528
+tmp/a/3529
+tmp/a/3530
+tmp/a/3531
+tmp/a/3532
+tmp/a/3533
+tmp/a/3534
+tmp/a/3535
+tmp/a/3536
+tmp/a/3537
+tmp/a/3538
+tmp/a/3539
+tmp/a/3540
+tmp/a/3541
+tmp/a/3542
+tmp/a/3543
+tmp/a/3544
+tmp/a/3545
+tmp/a/3546
+tmp/a/3547
+tmp/a/3548
+tmp/a/3549
+tmp/a/3550
+tmp/a/3551
+tmp/a/3552
+tmp/a/3553
+tmp/a/3554
+tmp/a/3555
+tmp/a/3556
+tmp/a/3557
+tmp/a/3558
+tmp/a/3559
+tmp/a/3560
+tmp/a/3561
+tmp/a/3562
+tmp/a/3563
+tmp/a/3564
+tmp/a/3565
+tmp/a/3566
+tmp/a/3567
+tmp/a/3568
+tmp/a/3569
+tmp/a/3570
+tmp/a/3571
+tmp/a/3572
+tmp/a/3573
+tmp/a/3574
+tmp/a/3575
+tmp/a/3576
+tmp/a/3577
+tmp/a/3578
+tmp/a/3579
+tmp/a/3580
+tmp/a/3581
+tmp/a/3582
+tmp/a/3583
+tmp/a/3584
+tmp/a/3585
+tmp/a/3586
+tmp/a/3587
+tmp/a/3588
+tmp/a/3589
+tmp/a/3590
+tmp/a/3591
+tmp/a/3592
+tmp/a/3593
+tmp/a/3594
+tmp/a/3595
+tmp/a/3596
+tmp/a/3597
+tmp/a/3598
+tmp/a/3599
+tmp/a/3600
+tmp/a/3601
+tmp/a/3602
+tmp/a/3603
+tmp/a/3604
+tmp/a/3605
+tmp/a/3606
+tmp/a/3607
+tmp/a/3608
+tmp/a/3609
+tmp/a/3610
+tmp/a/3611
+tmp/a/3612
+tmp/a/3613
+tmp/a/3614
+tmp/a/3615
+tmp/a/3616
+tmp/a/3617
+tmp/a/3618
+tmp/a/3619
+tmp/a/3620
+tmp/a/3621
+tmp/a/3622
+tmp/a/3623
+tmp/a/3624
+tmp/a/3625
+tmp/a/3626
+tmp/a/3627
+tmp/a/3628
+tmp/a/3629
+tmp/a/3630
+tmp/a/3631
+tmp/a/3632
+tmp/a/3633
+tmp/a/3634
+tmp/a/3635
+tmp/a/3636
+tmp/a/3637
+tmp/a/3638
+tmp/a/3639
+tmp/a/3640
+tmp/a/3641
+tmp/a/3642
+tmp/a/3643
+tmp/a/3644
+tmp/a/3645
+tmp/a/3646
+tmp/a/3647
+tmp/a/3648
+tmp/a/3649
+tmp/a/3650
+tmp/a/3651
+tmp/a/3652
+tmp/a/3653
+tmp/a/3654
+tmp/a/3655
+tmp/a/3656
+tmp/a/3657
+tmp/a/3658
+tmp/a/3659
+tmp/a/3660
+tmp/a/3661
+tmp/a/3662
+tmp/a/3663
+tmp/a/3664
+tmp/a/3665
+tmp/a/3666
+tmp/a/3667
+tmp/a/3668
+tmp/a/3669
+tmp/a/3670
+tmp/a/3671
+tmp/a/3672
+tmp/a/3673
+tmp/a/3674
+tmp/a/3675
+tmp/a/3676
+tmp/a/3677
+tmp/a/3678
+tmp/a/3679
+tmp/a/3680
+tmp/a/3681
+tmp/a/3682
+tmp/a/3683
+tmp/a/3684
+tmp/a/3685
+tmp/a/3686
+tmp/a/3687
+tmp/a/3688
+tmp/a/3689
+tmp/a/3690
+tmp/a/3691
+tmp/a/3692
+tmp/a/3693
+tmp/a/3694
+tmp/a/3695
+tmp/a/3696
+tmp/a/3697
+tmp/a/3698
+tmp/a/3699
+tmp/a/3700
+tmp/a/3701
+tmp/a/3702
+tmp/a/3703
+tmp/a/3704
+tmp/a/3705
+tmp/a/3706
+tmp/a/3707
+tmp/a/3708
+tmp/a/3709
+tmp/a/3710
+tmp/a/3711
+tmp/a/3712
+tmp/a/3713
+tmp/a/3714
+tmp/a/3715
+tmp/a/3716
+tmp/a/3717
+tmp/a/3718
+tmp/a/3719
+tmp/a/3720
+tmp/a/3721
+tmp/a/3722
+tmp/a/3723
+tmp/a/3724
+tmp/a/3725
+tmp/a/3726
+tmp/a/3727
+tmp/a/3728
+tmp/a/3729
+tmp/a/3730
+tmp/a/3731
+tmp/a/3732
+tmp/a/3733
+tmp/a/3734
+tmp/a/3735
+tmp/a/3736
+tmp/a/3737
+tmp/a/3738
+tmp/a/3739
+tmp/a/3740
+tmp/a/3741
+tmp/a/3742
+tmp/a/3743
+tmp/a/3744
+tmp/a/3745
+tmp/a/3746
+tmp/a/3747
+tmp/a/3748
+tmp/a/3749
+tmp/a/3750
+tmp/a/3751
+tmp/a/3752
+tmp/a/3753
+tmp/a/3754
+tmp/a/3755
+tmp/a/3756
+tmp/a/3757
+tmp/a/3758
+tmp/a/3759
+tmp/a/3760
+tmp/a/3761
+tmp/a/3762
+tmp/a/3763
+tmp/a/3764
+tmp/a/3765
+tmp/a/3766
+tmp/a/3767
+tmp/a/3768
+tmp/a/3769
+tmp/a/3770
+tmp/a/3771
+tmp/a/3772
+tmp/a/3773
+tmp/a/3774
+tmp/a/3775
+tmp/a/3776
+tmp/a/3777
+tmp/a/3778
+tmp/a/3779
+tmp/a/3780
+tmp/a/3781
+tmp/a/3782
+tmp/a/3783
+tmp/a/3784
+tmp/a/3785
+tmp/a/3786
+tmp/a/3787
+tmp/a/3788
+tmp/a/3789
+tmp/a/3790
+tmp/a/3791
+tmp/a/3792
+tmp/a/3793
+tmp/a/3794
+tmp/a/3795
+tmp/a/3796
+tmp/a/3797
+tmp/a/3798
+tmp/a/3799
+tmp/a/3800
+tmp/a/3801
+tmp/a/3802
+tmp/a/3803
+tmp/a/3804
+tmp/a/3805
+tmp/a/3806
+tmp/a/3807
+tmp/a/3808
+tmp/a/3809
+tmp/a/3810
+tmp/a/3811
+tmp/a/3812
+tmp/a/3813
+tmp/a/3814
+tmp/a/3815
+tmp/a/3816
+tmp/a/3817
+tmp/a/3818
+tmp/a/3819
+tmp/a/3820
+tmp/a/3821
+tmp/a/3822
+tmp/a/3823
+tmp/a/3824
+tmp/a/3825
+tmp/a/3826
+tmp/a/3827
+tmp/a/3828
+tmp/a/3829
+tmp/a/3830
+tmp/a/3831
+tmp/a/3832
+tmp/a/3833
+tmp/a/3834
+tmp/a/3835
+tmp/a/3836
+tmp/a/3837
+tmp/a/3838
+tmp/a/3839
+tmp/a/3840
+tmp/a/3841
+tmp/a/3842
+tmp/a/3843
+tmp/a/3844
+tmp/a/3845
+tmp/a/3846
+tmp/a/3847
+tmp/a/3848
+tmp/a/3849
+tmp/a/3850
+tmp/a/3851
+tmp/a/3852
+tmp/a/3853
+tmp/a/3854
+tmp/a/3855
+tmp/a/3856
+tmp/a/3857
+tmp/a/3858
+tmp/a/3859
+tmp/a/3860
+tmp/a/3861
+tmp/a/3862
+tmp/a/3863
+tmp/a/3864
+tmp/a/3865
+tmp/a/3866
+tmp/a/3867
+tmp/a/3868
+tmp/a/3869
+tmp/a/3870
+tmp/a/3871
+tmp/a/3872
+tmp/a/3873
+tmp/a/3874
+tmp/a/3875
+tmp/a/3876
+tmp/a/3877
+tmp/a/3878
+tmp/a/3879
+tmp/a/3880
+tmp/a/3881
+tmp/a/3882
+tmp/a/3883
+tmp/a/3884
+tmp/a/3885
+tmp/a/3886
+tmp/a/3887
+tmp/a/3888
+tmp/a/3889
+tmp/a/3890
+tmp/a/3891
+tmp/a/3892
+tmp/a/3893
+tmp/a/3894
+tmp/a/3895
+tmp/a/3896
+tmp/a/3897
+tmp/a/3898
+tmp/a/3899
+tmp/a/3900
+tmp/a/3901
+tmp/a/3902
+tmp/a/3903
+tmp/a/3904
+tmp/a/3905
+tmp/a/3906
+tmp/a/3907
+tmp/a/3908
+tmp/a/3909
+tmp/a/3910
+tmp/a/3911
+tmp/a/3912
+tmp/a/3913
+tmp/a/3914
+tmp/a/3915
+tmp/a/3916
+tmp/a/3917
+tmp/a/3918
+tmp/a/3919
+tmp/a/3920
+tmp/a/3921
+tmp/a/3922
+tmp/a/3923
+tmp/a/3924
+tmp/a/3925
+tmp/a/3926
+tmp/a/3927
+tmp/a/3928
+tmp/a/3929
+tmp/a/3930
+tmp/a/3931
+tmp/a/3932
+tmp/a/3933
+tmp/a/3934
+tmp/a/3935
+tmp/a/3936
+tmp/a/3937
+tmp/a/3938
+tmp/a/3939
+tmp/a/3940
+tmp/a/3941
+tmp/a/3942
+tmp/a/3943
+tmp/a/3944
+tmp/a/3945
+tmp/a/3946
+tmp/a/3947
+tmp/a/3948
+tmp/a/3949
+tmp/a/3950
+tmp/a/3951
+tmp/a/3952
+tmp/a/3953
+tmp/a/3954
+tmp/a/3955
+tmp/a/3956
+tmp/a/3957
+tmp/a/3958
+tmp/a/3959
+tmp/a/3960
+tmp/a/3961
+tmp/a/3962
+tmp/a/3963
+tmp/a/3964
+tmp/a/3965
+tmp/a/3966
+tmp/a/3967
+tmp/a/3968
+tmp/a/3969
+tmp/a/3970
+tmp/a/3971
+tmp/a/3972
+tmp/a/3973
+tmp/a/3974
+tmp/a/3975
+tmp/a/3976
+tmp/a/3977
+tmp/a/3978
+tmp/a/3979
+tmp/a/3980
+tmp/a/3981
+tmp/a/3982
+tmp/a/3983
+tmp/a/3984
+tmp/a/3985
+tmp/a/3986
+tmp/a/3987
+tmp/a/3988
+tmp/a/3989
+tmp/a/3990
+tmp/a/3991
+tmp/a/3992
+tmp/a/3993
+tmp/a/3994
+tmp/a/3995
+tmp/a/3996
+tmp/a/3997
+tmp/a/3998
+tmp/a/3999
+tmp/a/4000
+tmp/a/4001
+tmp/a/4002
+tmp/a/4003
+tmp/a/4004
+tmp/a/4005
+tmp/a/4006
+tmp/a/4007
+tmp/a/4008
+tmp/a/4009
+tmp/a/4010
+tmp/a/4011
+tmp/a/4012
+tmp/a/4013
+tmp/a/4014
+tmp/a/4015
+tmp/a/4016
+tmp/a/4017
+tmp/a/4018
+tmp/a/4019
+tmp/a/4020
+tmp/a/4021
+tmp/a/4022
+tmp/a/4023
+tmp/a/4024
+tmp/a/4025
+tmp/a/4026
+tmp/a/4027
+tmp/a/4028
+tmp/a/4029
+tmp/a/4030
+tmp/a/4031
+tmp/a/4032
+tmp/a/4033
+tmp/a/4034
+tmp/a/4035
+tmp/a/4036
+tmp/a/4037
+tmp/a/4038
+tmp/a/4039
+tmp/a/4040
+tmp/a/4041
+tmp/a/4042
+tmp/a/4043
+tmp/a/4044
+tmp/a/4045
+tmp/a/4046
+tmp/a/4047
+tmp/a/4048
+tmp/a/4049
+tmp/a/4050
+tmp/a/4051
+tmp/a/4052
+tmp/a/4053
+tmp/a/4054
+tmp/a/4055
+tmp/a/4056
+tmp/a/4057
+tmp/a/4058
+tmp/a/4059
+tmp/a/4060
+tmp/a/4061
+tmp/a/4062
+tmp/a/4063
+tmp/a/4064
+tmp/a/4065
+tmp/a/4066
+tmp/a/4067
+tmp/a/4068
+tmp/a/4069
+tmp/a/4070
+tmp/a/4071
+tmp/a/4072
+tmp/a/4073
+tmp/a/4074
+tmp/a/4075
+tmp/a/4076
+tmp/a/4077
+tmp/a/4078
+tmp/a/4079
+tmp/a/4080
+tmp/a/4081
+tmp/a/4082
+tmp/a/4083
+tmp/a/4084
+tmp/a/4085
+tmp/a/4086
+tmp/a/4087
+tmp/a/4088
+tmp/a/4089
+tmp/a/4090
+tmp/a/4091
+tmp/a/4092
+tmp/a/4093
+tmp/a/4094
+tmp/a/4095
+tmp/a/4096
+tmp/a/4097
+tmp/a/4098
+tmp/a/4099
+tmp/a/4100
+tmp/a/4101
+tmp/a/4102
+tmp/a/4103
+tmp/a/4104
+tmp/a/4105
+tmp/a/4106
+tmp/a/4107
+tmp/a/4108
+tmp/a/4109
+tmp/a/4110
+tmp/a/4111
+tmp/a/4112
+tmp/a/4113
+tmp/a/4114
+tmp/a/4115
+tmp/a/4116
+tmp/a/4117
+tmp/a/4118
+tmp/a/4119
+tmp/a/4120
+tmp/a/4121
+tmp/a/4122
+tmp/a/4123
+tmp/a/4124
+tmp/a/4125
+tmp/a/4126
+tmp/a/4127
+tmp/a/4128
+tmp/a/4129
+tmp/a/4130
+tmp/a/4131
+tmp/a/4132
+tmp/a/4133
+tmp/a/4134
+tmp/a/4135
+tmp/a/4136
+tmp/a/4137
+tmp/a/4138
+tmp/a/4139
+tmp/a/4140
+tmp/a/4141
+tmp/a/4142
+tmp/a/4143
+tmp/a/4144
+tmp/a/4145
+tmp/a/4146
+tmp/a/4147
+tmp/a/4148
+tmp/a/4149
+tmp/a/4150
+tmp/a/4151
+tmp/a/4152
+tmp/a/4153
+tmp/a/4154
+tmp/a/4155
+tmp/a/4156
+tmp/a/4157
+tmp/a/4158
+tmp/a/4159
+tmp/a/4160
+tmp/a/4161
+tmp/a/4162
+tmp/a/4163
+tmp/a/4164
+tmp/a/4165
+tmp/a/4166
+tmp/a/4167
+tmp/a/4168
+tmp/a/4169
+tmp/a/4170
+tmp/a/4171
+tmp/a/4172
+tmp/a/4173
+tmp/a/4174
+tmp/a/4175
+tmp/a/4176
+tmp/a/4177
+tmp/a/4178
+tmp/a/4179
+tmp/a/4180
+tmp/a/4181
+tmp/a/4182
+tmp/a/4183
+tmp/a/4184
+tmp/a/4185
+tmp/a/4186
+tmp/a/4187
+tmp/a/4188
+tmp/a/4189
+tmp/a/4190
+tmp/a/4191
+tmp/a/4192
+tmp/a/4193
+tmp/a/4194
+tmp/a/4195
+tmp/a/4196
+tmp/a/4197
+tmp/a/4198
+tmp/a/4199
+tmp/a/4200
+tmp/a/4201
+tmp/a/4202
+tmp/a/4203
+tmp/a/4204
+tmp/a/4205
+tmp/a/4206
+tmp/a/4207
+tmp/a/4208
+tmp/a/4209
+tmp/a/4210
+tmp/a/4211
+tmp/a/4212
+tmp/a/4213
+tmp/a/4214
+tmp/a/4215
+tmp/a/4216
+tmp/a/4217
+tmp/a/4218
+tmp/a/4219
+tmp/a/4220
+tmp/a/4221
+tmp/a/4222
+tmp/a/4223
+tmp/a/4224
+tmp/a/4225
+tmp/a/4226
+tmp/a/4227
+tmp/a/4228
+tmp/a/4229
+tmp/a/4230
+tmp/a/4231
+tmp/a/4232
+tmp/a/4233
+tmp/a/4234
+tmp/a/4235
+tmp/a/4236
+tmp/a/4237
+tmp/a/4238
+tmp/a/4239
+tmp/a/4240
+tmp/a/4241
+tmp/a/4242
+tmp/a/4243
+tmp/a/4244
+tmp/a/4245
+tmp/a/4246
+tmp/a/4247
+tmp/a/4248
+tmp/a/4249
+tmp/a/4250
+tmp/a/4251
+tmp/a/4252
+tmp/a/4253
+tmp/a/4254
+tmp/a/4255
+tmp/a/4256
+tmp/a/4257
+tmp/a/4258
+tmp/a/4259
+tmp/a/4260
+tmp/a/4261
+tmp/a/4262
+tmp/a/4263
+tmp/a/4264
+tmp/a/4265
+tmp/a/4266
+tmp/a/4267
+tmp/a/4268
+tmp/a/4269
+tmp/a/4270
+tmp/a/4271
+tmp/a/4272
+tmp/a/4273
+tmp/a/4274
+tmp/a/4275
+tmp/a/4276
+tmp/a/4277
+tmp/a/4278
+tmp/a/4279
+tmp/a/4280
+tmp/a/4281
+tmp/a/4282
+tmp/a/4283
+tmp/a/4284
+tmp/a/4285
+tmp/a/4286
+tmp/a/4287
+tmp/a/4288
+tmp/a/4289
+tmp/a/4290
+tmp/a/4291
+tmp/a/4292
+tmp/a/4293
+tmp/a/4294
+tmp/a/4295
+tmp/a/4296
+tmp/a/4297
+tmp/a/4298
+tmp/a/4299
+tmp/a/4300
+tmp/a/4301
+tmp/a/4302
+tmp/a/4303
+tmp/a/4304
+tmp/a/4305
+tmp/a/4306
+tmp/a/4307
+tmp/a/4308
+tmp/a/4309
+tmp/a/4310
+tmp/a/4311
+tmp/a/4312
+tmp/a/4313
+tmp/a/4314
+tmp/a/4315
+tmp/a/4316
+tmp/a/4317
+tmp/a/4318
+tmp/a/4319
+tmp/a/4320
+tmp/a/4321
+tmp/a/4322
+tmp/a/4323
+tmp/a/4324
+tmp/a/4325
+tmp/a/4326
+tmp/a/4327
+tmp/a/4328
+tmp/a/4329
+tmp/a/4330
+tmp/a/4331
+tmp/a/4332
+tmp/a/4333
+tmp/a/4334
+tmp/a/4335
+tmp/a/4336
+tmp/a/4337
+tmp/a/4338
+tmp/a/4339
+tmp/a/4340
+tmp/a/4341
+tmp/a/4342
+tmp/a/4343
+tmp/a/4344
+tmp/a/4345
+tmp/a/4346
+tmp/a/4347
+tmp/a/4348
+tmp/a/4349
+tmp/a/4350
+tmp/a/4351
+tmp/a/4352
+tmp/a/4353
+tmp/a/4354
+tmp/a/4355
+tmp/a/4356
+tmp/a/4357
+tmp/a/4358
+tmp/a/4359
+tmp/a/4360
+tmp/a/4361
+tmp/a/4362
+tmp/a/4363
+tmp/a/4364
+tmp/a/4365
+tmp/a/4366
+tmp/a/4367
+tmp/a/4368
+tmp/a/4369
+tmp/a/4370
+tmp/a/4371
+tmp/a/4372
+tmp/a/4373
+tmp/a/4374
+tmp/a/4375
+tmp/a/4376
+tmp/a/4377
+tmp/a/4378
+tmp/a/4379
+tmp/a/4380
+tmp/a/4381
+tmp/a/4382
+tmp/a/4383
+tmp/a/4384
+tmp/a/4385
+tmp/a/4386
+tmp/a/4387
+tmp/a/4388
+tmp/a/4389
+tmp/a/4390
+tmp/a/4391
+tmp/a/4392
+tmp/a/4393
+tmp/a/4394
+tmp/a/4395
+tmp/a/4396
+tmp/a/4397
+tmp/a/4398
+tmp/a/4399
+tmp/a/4400
+tmp/a/4401
+tmp/a/4402
+tmp/a/4403
+tmp/a/4404
+tmp/a/4405
+tmp/a/4406
+tmp/a/4407
+tmp/a/4408
+tmp/a/4409
+tmp/a/4410
+tmp/a/4411
+tmp/a/4412
+tmp/a/4413
+tmp/a/4414
+tmp/a/4415
+tmp/a/4416
+tmp/a/4417
+tmp/a/4418
+tmp/a/4419
+tmp/a/4420
+tmp/a/4421
+tmp/a/4422
+tmp/a/4423
+tmp/a/4424
+tmp/a/4425
+tmp/a/4426
+tmp/a/4427
+tmp/a/4428
+tmp/a/4429
+tmp/a/4430
+tmp/a/4431
+tmp/a/4432
+tmp/a/4433
+tmp/a/4434
+tmp/a/4435
+tmp/a/4436
+tmp/a/4437
+tmp/a/4438
+tmp/a/4439
+tmp/a/4440
+tmp/a/4441
+tmp/a/4442
+tmp/a/4443
+tmp/a/4444
+tmp/a/4445
+tmp/a/4446
+tmp/a/4447
+tmp/a/4448
+tmp/a/4449
+tmp/a/4450
+tmp/a/4451
+tmp/a/4452
+tmp/a/4453
+tmp/a/4454
+tmp/a/4455
+tmp/a/4456
+tmp/a/4457
+tmp/a/4458
+tmp/a/4459
+tmp/a/4460
+tmp/a/4461
+tmp/a/4462
+tmp/a/4463
+tmp/a/4464
+tmp/a/4465
+tmp/a/4466
+tmp/a/4467
+tmp/a/4468
+tmp/a/4469
+tmp/a/4470
+tmp/a/4471
+tmp/a/4472
+tmp/a/4473
+tmp/a/4474
+tmp/a/4475
+tmp/a/4476
+tmp/a/4477
+tmp/a/4478
+tmp/a/4479
+tmp/a/4480
+tmp/a/4481
+tmp/a/4482
+tmp/a/4483
+tmp/a/4484
+tmp/a/4485
+tmp/a/4486
+tmp/a/4487
+tmp/a/4488
+tmp/a/4489
+tmp/a/4490
+tmp/a/4491
+tmp/a/4492
+tmp/a/4493
+tmp/a/4494
+tmp/a/4495
+tmp/a/4496
+tmp/a/4497
+tmp/a/4498
+tmp/a/4499
+tmp/a/4500
+tmp/a/4501
+tmp/a/4502
+tmp/a/4503
+tmp/a/4504
+tmp/a/4505
+tmp/a/4506
+tmp/a/4507
+tmp/a/4508
+tmp/a/4509
+tmp/a/4510
+tmp/a/4511
+tmp/a/4512
+tmp/a/4513
+tmp/a/4514
+tmp/a/4515
+tmp/a/4516
+tmp/a/4517
+tmp/a/4518
+tmp/a/4519
+tmp/a/4520
+tmp/a/4521
+tmp/a/4522
+tmp/a/4523
+tmp/a/4524
+tmp/a/4525
+tmp/a/4526
+tmp/a/4527
+tmp/a/4528
+tmp/a/4529
+tmp/a/4530
+tmp/a/4531
+tmp/a/4532
+tmp/a/4533
+tmp/a/4534
+tmp/a/4535
+tmp/a/4536
+tmp/a/4537
+tmp/a/4538
+tmp/a/4539
+tmp/a/4540
+tmp/a/4541
+tmp/a/4542
+tmp/a/4543
+tmp/a/4544
+tmp/a/4545
+tmp/a/4546
+tmp/a/4547
+tmp/a/4548
+tmp/a/4549
+tmp/a/4550
+tmp/a/4551
+tmp/a/4552
+tmp/a/4553
+tmp/a/4554
+tmp/a/4555
+tmp/a/4556
+tmp/a/4557
+tmp/a/4558
+tmp/a/4559
+tmp/a/4560
+tmp/a/4561
+tmp/a/4562
+tmp/a/4563
+tmp/a/4564
+tmp/a/4565
+tmp/a/4566
+tmp/a/4567
+tmp/a/4568
+tmp/a/4569
+tmp/a/4570
+tmp/a/4571
+tmp/a/4572
+tmp/a/4573
+tmp/a/4574
+tmp/a/4575
+tmp/a/4576
+tmp/a/4577
+tmp/a/4578
+tmp/a/4579
+tmp/a/4580
+tmp/a/4581
+tmp/a/4582
+tmp/a/4583
+tmp/a/4584
+tmp/a/4585
+tmp/a/4586
+tmp/a/4587
+tmp/a/4588
+tmp/a/4589
+tmp/a/4590
+tmp/a/4591
+tmp/a/4592
+tmp/a/4593
+tmp/a/4594
+tmp/a/4595
+tmp/a/4596
+tmp/a/4597
+tmp/a/4598
+tmp/a/4599
+tmp/a/4600
+tmp/a/4601
+tmp/a/4602
+tmp/a/4603
+tmp/a/4604
+tmp/a/4605
+tmp/a/4606
+tmp/a/4607
+tmp/a/4608
+tmp/a/4609
+tmp/a/4610
+tmp/a/4611
+tmp/a/4612
+tmp/a/4613
+tmp/a/4614
+tmp/a/4615
+tmp/a/4616
+tmp/a/4617
+tmp/a/4618
+tmp/a/4619
+tmp/a/4620
+tmp/a/4621
+tmp/a/4622
+tmp/a/4623
+tmp/a/4624
+tmp/a/4625
+tmp/a/4626
+tmp/a/4627
+tmp/a/4628
+tmp/a/4629
+tmp/a/4630
+tmp/a/4631
+tmp/a/4632
+tmp/a/4633
+tmp/a/4634
+tmp/a/4635
+tmp/a/4636
+tmp/a/4637
+tmp/a/4638
+tmp/a/4639
+tmp/a/4640
+tmp/a/4641
+tmp/a/4642
+tmp/a/4643
+tmp/a/4644
+tmp/a/4645
+tmp/a/4646
+tmp/a/4647
+tmp/a/4648
+tmp/a/4649
+tmp/a/4650
+tmp/a/4651
+tmp/a/4652
+tmp/a/4653
+tmp/a/4654
+tmp/a/4655
+tmp/a/4656
+tmp/a/4657
+tmp/a/4658
+tmp/a/4659
+tmp/a/4660
+tmp/a/4661
+tmp/a/4662
+tmp/a/4663
+tmp/a/4664
+tmp/a/4665
+tmp/a/4666
+tmp/a/4667
+tmp/a/4668
+tmp/a/4669
+tmp/a/4670
+tmp/a/4671
+tmp/a/4672
+tmp/a/4673
+tmp/a/4674
+tmp/a/4675
+tmp/a/4676
+tmp/a/4677
+tmp/a/4678
+tmp/a/4679
+tmp/a/4680
+tmp/a/4681
+tmp/a/4682
+tmp/a/4683
+tmp/a/4684
+tmp/a/4685
+tmp/a/4686
+tmp/a/4687
+tmp/a/4688
+tmp/a/4689
+tmp/a/4690
+tmp/a/4691
+tmp/a/4692
+tmp/a/4693
+tmp/a/4694
+tmp/a/4695
+tmp/a/4696
+tmp/a/4697
+tmp/a/4698
+tmp/a/4699
+tmp/a/4700
+tmp/a/4701
+tmp/a/4702
+tmp/a/4703
+tmp/a/4704
+tmp/a/4705
+tmp/a/4706
+tmp/a/4707
+tmp/a/4708
+tmp/a/4709
+tmp/a/4710
+tmp/a/4711
+tmp/a/4712
+tmp/a/4713
+tmp/a/4714
+tmp/a/4715
+tmp/a/4716
+tmp/a/4717
+tmp/a/4718
+tmp/a/4719
+tmp/a/4720
+tmp/a/4721
+tmp/a/4722
+tmp/a/4723
+tmp/a/4724
+tmp/a/4725
+tmp/a/4726
+tmp/a/4727
+tmp/a/4728
+tmp/a/4729
+tmp/a/4730
+tmp/a/4731
+tmp/a/4732
+tmp/a/4733
+tmp/a/4734
+tmp/a/4735
+tmp/a/4736
+tmp/a/4737
+tmp/a/4738
+tmp/a/4739
+tmp/a/4740
+tmp/a/4741
+tmp/a/4742
+tmp/a/4743
+tmp/a/4744
+tmp/a/4745
+tmp/a/4746
+tmp/a/4747
+tmp/a/4748
+tmp/a/4749
+tmp/a/4750
+tmp/a/4751
+tmp/a/4752
+tmp/a/4753
+tmp/a/4754
+tmp/a/4755
+tmp/a/4756
+tmp/a/4757
+tmp/a/4758
+tmp/a/4759
+tmp/a/4760
+tmp/a/4761
+tmp/a/4762
+tmp/a/4763
+tmp/a/4764
+tmp/a/4765
+tmp/a/4766
+tmp/a/4767
+tmp/a/4768
+tmp/a/4769
+tmp/a/4770
+tmp/a/4771
+tmp/a/4772
+tmp/a/4773
+tmp/a/4774
+tmp/a/4775
+tmp/a/4776
+tmp/a/4777
+tmp/a/4778
+tmp/a/4779
+tmp/a/4780
+tmp/a/4781
+tmp/a/4782
+tmp/a/4783
+tmp/a/4784
+tmp/a/4785
+tmp/a/4786
+tmp/a/4787
+tmp/a/4788
+tmp/a/4789
+tmp/a/4790
+tmp/a/4791
+tmp/a/4792
+tmp/a/4793
+tmp/a/4794
+tmp/a/4795
+tmp/a/4796
+tmp/a/4797
+tmp/a/4798
+tmp/a/4799
+tmp/a/4800
+tmp/a/4801
+tmp/a/4802
+tmp/a/4803
+tmp/a/4804
+tmp/a/4805
+tmp/a/4806
+tmp/a/4807
+tmp/a/4808
+tmp/a/4809
+tmp/a/4810
+tmp/a/4811
+tmp/a/4812
+tmp/a/4813
+tmp/a/4814
+tmp/a/4815
+tmp/a/4816
+tmp/a/4817
+tmp/a/4818
+tmp/a/4819
+tmp/a/4820
+tmp/a/4821
+tmp/a/4822
+tmp/a/4823
+tmp/a/4824
+tmp/a/4825
+tmp/a/4826
+tmp/a/4827
+tmp/a/4828
+tmp/a/4829
+tmp/a/4830
+tmp/a/4831
+tmp/a/4832
+tmp/a/4833
+tmp/a/4834
+tmp/a/4835
+tmp/a/4836
+tmp/a/4837
+tmp/a/4838
+tmp/a/4839
+tmp/a/4840
+tmp/a/4841
+tmp/a/4842
+tmp/a/4843
+tmp/a/4844
+tmp/a/4845
+tmp/a/4846
+tmp/a/4847
+tmp/a/4848
+tmp/a/4849
+tmp/a/4850
+tmp/a/4851
+tmp/a/4852
+tmp/a/4853
+tmp/a/4854
+tmp/a/4855
+tmp/a/4856
+tmp/a/4857
+tmp/a/4858
+tmp/a/4859
+tmp/a/4860
+tmp/a/4861
+tmp/a/4862
+tmp/a/4863
+tmp/a/4864
+tmp/a/4865
+tmp/a/4866
+tmp/a/4867
+tmp/a/4868
+tmp/a/4869
+tmp/a/4870
+tmp/a/4871
+tmp/a/4872
+tmp/a/4873
+tmp/a/4874
+tmp/a/4875
+tmp/a/4876
+tmp/a/4877
+tmp/a/4878
+tmp/a/4879
+tmp/a/4880
+tmp/a/4881
+tmp/a/4882
+tmp/a/4883
+tmp/a/4884
+tmp/a/4885
+tmp/a/4886
+tmp/a/4887
+tmp/a/4888
+tmp/a/4889
+tmp/a/4890
+tmp/a/4891
+tmp/a/4892
+tmp/a/4893
+tmp/a/4894
+tmp/a/4895
+tmp/a/4896
+tmp/a/4897
+tmp/a/4898
+tmp/a/4899
+tmp/a/4900
+tmp/a/4901
+tmp/a/4902
+tmp/a/4903
+tmp/a/4904
+tmp/a/4905
+tmp/a/4906
+tmp/a/4907
+tmp/a/4908
+tmp/a/4909
+tmp/a/4910
+tmp/a/4911
+tmp/a/4912
+tmp/a/4913
+tmp/a/4914
+tmp/a/4915
+tmp/a/4916
+tmp/a/4917
+tmp/a/4918
+tmp/a/4919
+tmp/a/4920
+tmp/a/4921
+tmp/a/4922
+tmp/a/4923
+tmp/a/4924
+tmp/a/4925
+tmp/a/4926
+tmp/a/4927
+tmp/a/4928
+tmp/a/4929
+tmp/a/4930
+tmp/a/4931
+tmp/a/4932
+tmp/a/4933
+tmp/a/4934
+tmp/a/4935
+tmp/a/4936
+tmp/a/4937
+tmp/a/4938
+tmp/a/4939
+tmp/a/4940
+tmp/a/4941
+tmp/a/4942
+tmp/a/4943
+tmp/a/4944
+tmp/a/4945
+tmp/a/4946
+tmp/a/4947
+tmp/a/4948
+tmp/a/4949
+tmp/a/4950
+tmp/a/4951
+tmp/a/4952
+tmp/a/4953
+tmp/a/4954
+tmp/a/4955
+tmp/a/4956
+tmp/a/4957
+tmp/a/4958
+tmp/a/4959
+tmp/a/4960
+tmp/a/4961
+tmp/a/4962
+tmp/a/4963
+tmp/a/4964
+tmp/a/4965
+tmp/a/4966
+tmp/a/4967
+tmp/a/4968
+tmp/a/4969
+tmp/a/4970
+tmp/a/4971
+tmp/a/4972
+tmp/a/4973
+tmp/a/4974
+tmp/a/4975
+tmp/a/4976
+tmp/a/4977
+tmp/a/4978
+tmp/a/4979
+tmp/a/4980
+tmp/a/4981
+tmp/a/4982
+tmp/a/4983
+tmp/a/4984
+tmp/a/4985
+tmp/a/4986
+tmp/a/4987
+tmp/a/4988
+tmp/a/4989
+tmp/a/4990
+tmp/a/4991
+tmp/a/4992
+tmp/a/4993
+tmp/a/4994
+tmp/a/4995
+tmp/a/4996
+tmp/a/4997
+tmp/a/4998
+tmp/a/4999
+tmp/a/5000
+tmp/a/5001
+tmp/a/5002
+tmp/a/5003
+tmp/a/5004
+tmp/a/5005
+tmp/a/5006
+tmp/a/5007
+tmp/a/5008
+tmp/a/5009
+tmp/a/5010
+tmp/a/5011
+tmp/a/5012
+tmp/a/5013
+tmp/a/5014
+tmp/a/5015
+tmp/a/5016
+tmp/a/5017
+tmp/a/5018
+tmp/a/5019
+tmp/a/5020
+tmp/a/5021
+tmp/a/5022
+tmp/a/5023
+tmp/a/5024
+tmp/a/5025
+tmp/a/5026
+tmp/a/5027
+tmp/a/5028
+tmp/a/5029
+tmp/a/5030
+tmp/a/5031
+tmp/a/5032
+tmp/a/5033
+tmp/a/5034
+tmp/a/5035
+tmp/a/5036
+tmp/a/5037
+tmp/a/5038
+tmp/a/5039
+tmp/a/5040
+tmp/a/5041
+tmp/a/5042
+tmp/a/5043
+tmp/a/5044
+tmp/a/5045
+tmp/a/5046
+tmp/a/5047
+tmp/a/5048
+tmp/a/5049
+tmp/a/5050
+tmp/a/5051
+tmp/a/5052
+tmp/a/5053
+tmp/a/5054
+tmp/a/5055
+tmp/a/5056
+tmp/a/5057
+tmp/a/5058
+tmp/a/5059
+tmp/a/5060
+tmp/a/5061
+tmp/a/5062
+tmp/a/5063
+tmp/a/5064
+tmp/a/5065
+tmp/a/5066
+tmp/a/5067
+tmp/a/5068
+tmp/a/5069
+tmp/a/5070
+tmp/a/5071
+tmp/a/5072
+tmp/a/5073
+tmp/a/5074
+tmp/a/5075
+tmp/a/5076
+tmp/a/5077
+tmp/a/5078
+tmp/a/5079
+tmp/a/5080
+tmp/a/5081
+tmp/a/5082
+tmp/a/5083
+tmp/a/5084
+tmp/a/5085
+tmp/a/5086
+tmp/a/5087
+tmp/a/5088
+tmp/a/5089
+tmp/a/5090
+tmp/a/5091
+tmp/a/5092
+tmp/a/5093
+tmp/a/5094
+tmp/a/5095
+tmp/a/5096
+tmp/a/5097
+tmp/a/5098
+tmp/a/5099
+tmp/a/5100
+tmp/a/5101
+tmp/a/5102
+tmp/a/5103
+tmp/a/5104
+tmp/a/5105
+tmp/a/5106
+tmp/a/5107
+tmp/a/5108
+tmp/a/5109
+tmp/a/5110
+tmp/a/5111
+tmp/a/5112
+tmp/a/5113
+tmp/a/5114
+tmp/a/5115
+tmp/a/5116
+tmp/a/5117
+tmp/a/5118
+tmp/a/5119
+tmp/a/5120
+tmp/a/5121
+tmp/a/5122
+tmp/a/5123
+tmp/a/5124
+tmp/a/5125
+tmp/a/5126
+tmp/a/5127
+tmp/a/5128
+tmp/a/5129
+tmp/a/5130
+tmp/a/5131
+tmp/a/5132
+tmp/a/5133
+tmp/a/5134
+tmp/a/5135
+tmp/a/5136
+tmp/a/5137
+tmp/a/5138
+tmp/a/5139
+tmp/a/5140
+tmp/a/5141
+tmp/a/5142
+tmp/a/5143
+tmp/a/5144
+tmp/a/5145
+tmp/a/5146
+tmp/a/5147
+tmp/a/5148
+tmp/a/5149
+tmp/a/5150
+tmp/a/5151
+tmp/a/5152
+tmp/a/5153
+tmp/a/5154
+tmp/a/5155
+tmp/a/5156
+tmp/a/5157
+tmp/a/5158
+tmp/a/5159
+tmp/a/5160
+tmp/a/5161
+tmp/a/5162
+tmp/a/5163
+tmp/a/5164
+tmp/a/5165
+tmp/a/5166
+tmp/a/5167
+tmp/a/5168
+tmp/a/5169
+tmp/a/5170
+tmp/a/5171
+tmp/a/5172
+tmp/a/5173
+tmp/a/5174
+tmp/a/5175
+tmp/a/5176
+tmp/a/5177
+tmp/a/5178
+tmp/a/5179
+tmp/a/5180
+tmp/a/5181
+tmp/a/5182
+tmp/a/5183
+tmp/a/5184
+tmp/a/5185
+tmp/a/5186
+tmp/a/5187
+tmp/a/5188
+tmp/a/5189
+tmp/a/5190
+tmp/a/5191
+tmp/a/5192
+tmp/a/5193
+tmp/a/5194
+tmp/a/5195
+tmp/a/5196
+tmp/a/5197
+tmp/a/5198
+tmp/a/5199
+tmp/a/5200
+tmp/a/5201
+tmp/a/5202
+tmp/a/5203
+tmp/a/5204
+tmp/a/5205
+tmp/a/5206
+tmp/a/5207
+tmp/a/5208
+tmp/a/5209
+tmp/a/5210
+tmp/a/5211
+tmp/a/5212
+tmp/a/5213
+tmp/a/5214
+tmp/a/5215
+tmp/a/5216
+tmp/a/5217
+tmp/a/5218
+tmp/a/5219
+tmp/a/5220
+tmp/a/5221
+tmp/a/5222
+tmp/a/5223
+tmp/a/5224
+tmp/a/5225
+tmp/a/5226
+tmp/a/5227
+tmp/a/5228
+tmp/a/5229
+tmp/a/5230
+tmp/a/5231
+tmp/a/5232
+tmp/a/5233
+tmp/a/5234
+tmp/a/5235
+tmp/a/5236
+tmp/a/5237
+tmp/a/5238
+tmp/a/5239
+tmp/a/5240
+tmp/a/5241
+tmp/a/5242
+tmp/a/5243
+tmp/a/5244
+tmp/a/5245
+tmp/a/5246
+tmp/a/5247
+tmp/a/5248
+tmp/a/5249
+tmp/a/5250
+tmp/a/5251
+tmp/a/5252
+tmp/a/5253
+tmp/a/5254
+tmp/a/5255
+tmp/a/5256
+tmp/a/5257
+tmp/a/5258
+tmp/a/5259
+tmp/a/5260
+tmp/a/5261
+tmp/a/5262
+tmp/a/5263
+tmp/a/5264
+tmp/a/5265
+tmp/a/5266
+tmp/a/5267
+tmp/a/5268
+tmp/a/5269
+tmp/a/5270
+tmp/a/5271
+tmp/a/5272
+tmp/a/5273
+tmp/a/5274
+tmp/a/5275
+tmp/a/5276
+tmp/a/5277
+tmp/a/5278
+tmp/a/5279
+tmp/a/5280
+tmp/a/5281
+tmp/a/5282
+tmp/a/5283
+tmp/a/5284
+tmp/a/5285
+tmp/a/5286
+tmp/a/5287
+tmp/a/5288
+tmp/a/5289
+tmp/a/5290
+tmp/a/5291
+tmp/a/5292
+tmp/a/5293
+tmp/a/5294
+tmp/a/5295
+tmp/a/5296
+tmp/a/5297
+tmp/a/5298
+tmp/a/5299
+tmp/a/5300
+tmp/a/5301
+tmp/a/5302
+tmp/a/5303
+tmp/a/5304
+tmp/a/5305
+tmp/a/5306
+tmp/a/5307
+tmp/a/5308
+tmp/a/5309
+tmp/a/5310
+tmp/a/5311
+tmp/a/5312
+tmp/a/5313
+tmp/a/5314
+tmp/a/5315
+tmp/a/5316
+tmp/a/5317
+tmp/a/5318
+tmp/a/5319
+tmp/a/5320
+tmp/a/5321
+tmp/a/5322
+tmp/a/5323
+tmp/a/5324
+tmp/a/5325
+tmp/a/5326
+tmp/a/5327
+tmp/a/5328
+tmp/a/5329
+tmp/a/5330
+tmp/a/5331
+tmp/a/5332
+tmp/a/5333
+tmp/a/5334
+tmp/a/5335
+tmp/a/5336
+tmp/a/5337
+tmp/a/5338
+tmp/a/5339
+tmp/a/5340
+tmp/a/5341
+tmp/a/5342
+tmp/a/5343
+tmp/a/5344
+tmp/a/5345
+tmp/a/5346
+tmp/a/5347
+tmp/a/5348
+tmp/a/5349
+tmp/a/5350
+tmp/a/5351
+tmp/a/5352
+tmp/a/5353
+tmp/a/5354
+tmp/a/5355
+tmp/a/5356
+tmp/a/5357
+tmp/a/5358
+tmp/a/5359
+tmp/a/5360
+tmp/a/5361
+tmp/a/5362
+tmp/a/5363
+tmp/a/5364
+tmp/a/5365
+tmp/a/5366
+tmp/a/5367
+tmp/a/5368
+tmp/a/5369
+tmp/a/5370
+tmp/a/5371
+tmp/a/5372
+tmp/a/5373
+tmp/a/5374
+tmp/a/5375
+tmp/a/5376
+tmp/a/5377
+tmp/a/5378
+tmp/a/5379
+tmp/a/5380
+tmp/a/5381
+tmp/a/5382
+tmp/a/5383
+tmp/a/5384
+tmp/a/5385
+tmp/a/5386
+tmp/a/5387
+tmp/a/5388
+tmp/a/5389
+tmp/a/5390
+tmp/a/5391
+tmp/a/5392
+tmp/a/5393
+tmp/a/5394
+tmp/a/5395
+tmp/a/5396
+tmp/a/5397
+tmp/a/5398
+tmp/a/5399
+tmp/a/5400
+tmp/a/5401
+tmp/a/5402
+tmp/a/5403
+tmp/a/5404
+tmp/a/5405
+tmp/a/5406
+tmp/a/5407
+tmp/a/5408
+tmp/a/5409
+tmp/a/5410
+tmp/a/5411
+tmp/a/5412
+tmp/a/5413
+tmp/a/5414
+tmp/a/5415
+tmp/a/5416
+tmp/a/5417
+tmp/a/5418
+tmp/a/5419
+tmp/a/5420
+tmp/a/5421
+tmp/a/5422
+tmp/a/5423
+tmp/a/5424
+tmp/a/5425
+tmp/a/5426
+tmp/a/5427
+tmp/a/5428
+tmp/a/5429
+tmp/a/5430
+tmp/a/5431
+tmp/a/5432
+tmp/a/5433
+tmp/a/5434
+tmp/a/5435
+tmp/a/5436
+tmp/a/5437
+tmp/a/5438
+tmp/a/5439
+tmp/a/5440
+tmp/a/5441
+tmp/a/5442
+tmp/a/5443
+tmp/a/5444
+tmp/a/5445
+tmp/a/5446
+tmp/a/5447
+tmp/a/5448
+tmp/a/5449
+tmp/a/5450
+tmp/a/5451
+tmp/a/5452
+tmp/a/5453
+tmp/a/5454
+tmp/a/5455
+tmp/a/5456
+tmp/a/5457
+tmp/a/5458
+tmp/a/5459
+tmp/a/5460
+tmp/a/5461
+tmp/a/5462
+tmp/a/5463
+tmp/a/5464
+tmp/a/5465
+tmp/a/5466
+tmp/a/5467
+tmp/a/5468
+tmp/a/5469
+tmp/a/5470
+tmp/a/5471
+tmp/a/5472
+tmp/a/5473
+tmp/a/5474
+tmp/a/5475
+tmp/a/5476
+tmp/a/5477
+tmp/a/5478
+tmp/a/5479
+tmp/a/5480
+tmp/a/5481
+tmp/a/5482
+tmp/a/5483
+tmp/a/5484
+tmp/a/5485
+tmp/a/5486
+tmp/a/5487
+tmp/a/5488
+tmp/a/5489
+tmp/a/5490
+tmp/a/5491
+tmp/a/5492
+tmp/a/5493
+tmp/a/5494
+tmp/a/5495
+tmp/a/5496
+tmp/a/5497
+tmp/a/5498
+tmp/a/5499
+tmp/a/5500
+tmp/a/5501
+tmp/a/5502
+tmp/a/5503
+tmp/a/5504
+tmp/a/5505
+tmp/a/5506
+tmp/a/5507
+tmp/a/5508
+tmp/a/5509
+tmp/a/5510
+tmp/a/5511
+tmp/a/5512
+tmp/a/5513
+tmp/a/5514
+tmp/a/5515
+tmp/a/5516
+tmp/a/5517
+tmp/a/5518
+tmp/a/5519
+tmp/a/5520
+tmp/a/5521
+tmp/a/5522
+tmp/a/5523
+tmp/a/5524
+tmp/a/5525
+tmp/a/5526
+tmp/a/5527
+tmp/a/5528
+tmp/a/5529
+tmp/a/5530
+tmp/a/5531
+tmp/a/5532
+tmp/a/5533
+tmp/a/5534
+tmp/a/5535
+tmp/a/5536
+tmp/a/5537
+tmp/a/5538
+tmp/a/5539
+tmp/a/5540
+tmp/a/5541
+tmp/a/5542
+tmp/a/5543
+tmp/a/5544
+tmp/a/5545
+tmp/a/5546
+tmp/a/5547
+tmp/a/5548
+tmp/a/5549
+tmp/a/5550
+tmp/a/5551
+tmp/a/5552
+tmp/a/5553
+tmp/a/5554
+tmp/a/5555
+tmp/a/5556
+tmp/a/5557
+tmp/a/5558
+tmp/a/5559
+tmp/a/5560
+tmp/a/5561
+tmp/a/5562
+tmp/a/5563
+tmp/a/5564
+tmp/a/5565
+tmp/a/5566
+tmp/a/5567
+tmp/a/5568
+tmp/a/5569
+tmp/a/5570
+tmp/a/5571
+tmp/a/5572
+tmp/a/5573
+tmp/a/5574
+tmp/a/5575
+tmp/a/5576
+tmp/a/5577
+tmp/a/5578
+tmp/a/5579
+tmp/a/5580
+tmp/a/5581
+tmp/a/5582
+tmp/a/5583
+tmp/a/5584
+tmp/a/5585
+tmp/a/5586
+tmp/a/5587
+tmp/a/5588
+tmp/a/5589
+tmp/a/5590
+tmp/a/5591
+tmp/a/5592
+tmp/a/5593
+tmp/a/5594
+tmp/a/5595
+tmp/a/5596
+tmp/a/5597
+tmp/a/5598
+tmp/a/5599
+tmp/a/5600
+tmp/a/5601
+tmp/a/5602
+tmp/a/5603
+tmp/a/5604
+tmp/a/5605
+tmp/a/5606
+tmp/a/5607
+tmp/a/5608
+tmp/a/5609
+tmp/a/5610
+tmp/a/5611
+tmp/a/5612
+tmp/a/5613
+tmp/a/5614
+tmp/a/5615
+tmp/a/5616
+tmp/a/5617
+tmp/a/5618
+tmp/a/5619
+tmp/a/5620
+tmp/a/5621
+tmp/a/5622
+tmp/a/5623
+tmp/a/5624
+tmp/a/5625
+tmp/a/5626
+tmp/a/5627
+tmp/a/5628
+tmp/a/5629
+tmp/a/5630
+tmp/a/5631
+tmp/a/5632
+tmp/a/5633
+tmp/a/5634
+tmp/a/5635
+tmp/a/5636
+tmp/a/5637
+tmp/a/5638
+tmp/a/5639
+tmp/a/5640
+tmp/a/5641
+tmp/a/5642
+tmp/a/5643
+tmp/a/5644
+tmp/a/5645
+tmp/a/5646
+tmp/a/5647
+tmp/a/5648
+tmp/a/5649
+tmp/a/5650
+tmp/a/5651
+tmp/a/5652
+tmp/a/5653
+tmp/a/5654
+tmp/a/5655
+tmp/a/5656
+tmp/a/5657
+tmp/a/5658
+tmp/a/5659
+tmp/a/5660
+tmp/a/5661
+tmp/a/5662
+tmp/a/5663
+tmp/a/5664
+tmp/a/5665
+tmp/a/5666
+tmp/a/5667
+tmp/a/5668
+tmp/a/5669
+tmp/a/5670
+tmp/a/5671
+tmp/a/5672
+tmp/a/5673
+tmp/a/5674
+tmp/a/5675
+tmp/a/5676
+tmp/a/5677
+tmp/a/5678
+tmp/a/5679
+tmp/a/5680
+tmp/a/5681
+tmp/a/5682
+tmp/a/5683
+tmp/a/5684
+tmp/a/5685
+tmp/a/5686
+tmp/a/5687
+tmp/a/5688
+tmp/a/5689
+tmp/a/5690
+tmp/a/5691
+tmp/a/5692
+tmp/a/5693
+tmp/a/5694
+tmp/a/5695
+tmp/a/5696
+tmp/a/5697
+tmp/a/5698
+tmp/a/5699
+tmp/a/5700
+tmp/a/5701
+tmp/a/5702
+tmp/a/5703
+tmp/a/5704
+tmp/a/5705
+tmp/a/5706
+tmp/a/5707
+tmp/a/5708
+tmp/a/5709
+tmp/a/5710
+tmp/a/5711
+tmp/a/5712
+tmp/a/5713
+tmp/a/5714
+tmp/a/5715
+tmp/a/5716
+tmp/a/5717
+tmp/a/5718
+tmp/a/5719
+tmp/a/5720
+tmp/a/5721
+tmp/a/5722
+tmp/a/5723
+tmp/a/5724
+tmp/a/5725
+tmp/a/5726
+tmp/a/5727
+tmp/a/5728
+tmp/a/5729
+tmp/a/5730
+tmp/a/5731
+tmp/a/5732
+tmp/a/5733
+tmp/a/5734
+tmp/a/5735
+tmp/a/5736
+tmp/a/5737
+tmp/a/5738
+tmp/a/5739
+tmp/a/5740
+tmp/a/5741
+tmp/a/5742
+tmp/a/5743
+tmp/a/5744
+tmp/a/5745
+tmp/a/5746
+tmp/a/5747
+tmp/a/5748
+tmp/a/5749
+tmp/a/5750
+tmp/a/5751
+tmp/a/5752
+tmp/a/5753
+tmp/a/5754
+tmp/a/5755
+tmp/a/5756
+tmp/a/5757
+tmp/a/5758
+tmp/a/5759
+tmp/a/5760
+tmp/a/5761
+tmp/a/5762
+tmp/a/5763
+tmp/a/5764
+tmp/a/5765
+tmp/a/5766
+tmp/a/5767
+tmp/a/5768
+tmp/a/5769
+tmp/a/5770
+tmp/a/5771
+tmp/a/5772
+tmp/a/5773
+tmp/a/5774
+tmp/a/5775
+tmp/a/5776
+tmp/a/5777
+tmp/a/5778
+tmp/a/5779
+tmp/a/5780
+tmp/a/5781
+tmp/a/5782
+tmp/a/5783
+tmp/a/5784
+tmp/a/5785
+tmp/a/5786
+tmp/a/5787
+tmp/a/5788
+tmp/a/5789
+tmp/a/5790
+tmp/a/5791
+tmp/a/5792
+tmp/a/5793
+tmp/a/5794
+tmp/a/5795
+tmp/a/5796
+tmp/a/5797
+tmp/a/5798
+tmp/a/5799
+tmp/a/5800
+tmp/a/5801
+tmp/a/5802
+tmp/a/5803
+tmp/a/5804
+tmp/a/5805
+tmp/a/5806
+tmp/a/5807
+tmp/a/5808
+tmp/a/5809
+tmp/a/5810
+tmp/a/5811
+tmp/a/5812
+tmp/a/5813
+tmp/a/5814
+tmp/a/5815
+tmp/a/5816
+tmp/a/5817
+tmp/a/5818
+tmp/a/5819
+tmp/a/5820
+tmp/a/5821
+tmp/a/5822
+tmp/a/5823
+tmp/a/5824
+tmp/a/5825
+tmp/a/5826
+tmp/a/5827
+tmp/a/5828
+tmp/a/5829
+tmp/a/5830
+tmp/a/5831
+tmp/a/5832
+tmp/a/5833
+tmp/a/5834
+tmp/a/5835
+tmp/a/5836
+tmp/a/5837
+tmp/a/5838
+tmp/a/5839
+tmp/a/5840
+tmp/a/5841
+tmp/a/5842
+tmp/a/5843
+tmp/a/5844
+tmp/a/5845
+tmp/a/5846
+tmp/a/5847
+tmp/a/5848
+tmp/a/5849
+tmp/a/5850
+tmp/a/5851
+tmp/a/5852
+tmp/a/5853
+tmp/a/5854
+tmp/a/5855
+tmp/a/5856
+tmp/a/5857
+tmp/a/5858
+tmp/a/5859
+tmp/a/5860
+tmp/a/5861
+tmp/a/5862
+tmp/a/5863
+tmp/a/5864
+tmp/a/5865
+tmp/a/5866
+tmp/a/5867
+tmp/a/5868
+tmp/a/5869
+tmp/a/5870
+tmp/a/5871
+tmp/a/5872
+tmp/a/5873
+tmp/a/5874
+tmp/a/5875
+tmp/a/5876
+tmp/a/5877
+tmp/a/5878
+tmp/a/5879
+tmp/a/5880
+tmp/a/5881
+tmp/a/5882
+tmp/a/5883
+tmp/a/5884
+tmp/a/5885
+tmp/a/5886
+tmp/a/5887
+tmp/a/5888
+tmp/a/5889
+tmp/a/5890
+tmp/a/5891
+tmp/a/5892
+tmp/a/5893
+tmp/a/5894
+tmp/a/5895
+tmp/a/5896
+tmp/a/5897
+tmp/a/5898
+tmp/a/5899
+tmp/a/5900
+tmp/a/5901
+tmp/a/5902
+tmp/a/5903
+tmp/a/5904
+tmp/a/5905
+tmp/a/5906
+tmp/a/5907
+tmp/a/5908
+tmp/a/5909
+tmp/a/5910
+tmp/a/5911
+tmp/a/5912
+tmp/a/5913
+tmp/a/5914
+tmp/a/5915
+tmp/a/5916
+tmp/a/5917
+tmp/a/5918
+tmp/a/5919
+tmp/a/5920
+tmp/a/5921
+tmp/a/5922
+tmp/a/5923
+tmp/a/5924
+tmp/a/5925
+tmp/a/5926
+tmp/a/5927
+tmp/a/5928
+tmp/a/5929
+tmp/a/5930
+tmp/a/5931
+tmp/a/5932
+tmp/a/5933
+tmp/a/5934
+tmp/a/5935
+tmp/a/5936
+tmp/a/5937
+tmp/a/5938
+tmp/a/5939
+tmp/a/5940
+tmp/a/5941
+tmp/a/5942
+tmp/a/5943
+tmp/a/5944
+tmp/a/5945
+tmp/a/5946
+tmp/a/5947
+tmp/a/5948
+tmp/a/5949
+tmp/a/5950
+tmp/a/5951
+tmp/a/5952
+tmp/a/5953
+tmp/a/5954
+tmp/a/5955
+tmp/a/5956
+tmp/a/5957
+tmp/a/5958
+tmp/a/5959
+tmp/a/5960
+tmp/a/5961
+tmp/a/5962
+tmp/a/5963
+tmp/a/5964
+tmp/a/5965
+tmp/a/5966
+tmp/a/5967
+tmp/a/5968
+tmp/a/5969
+tmp/a/5970
+tmp/a/5971
+tmp/a/5972
+tmp/a/5973
+tmp/a/5974
+tmp/a/5975
+tmp/a/5976
+tmp/a/5977
+tmp/a/5978
+tmp/a/5979
+tmp/a/5980
+tmp/a/5981
+tmp/a/5982
+tmp/a/5983
+tmp/a/5984
+tmp/a/5985
+tmp/a/5986
+tmp/a/5987
+tmp/a/5988
+tmp/a/5989
+tmp/a/5990
+tmp/a/5991
+tmp/a/5992
+tmp/a/5993
+tmp/a/5994
+tmp/a/5995
+tmp/a/5996
+tmp/a/5997
+tmp/a/5998
+tmp/a/5999
+tmp/a/6000
+tmp/a/6001
+tmp/a/6002
+tmp/a/6003
+tmp/a/6004
+tmp/a/6005
+tmp/a/6006
+tmp/a/6007
+tmp/a/6008
+tmp/a/6009
+tmp/a/6010
+tmp/a/6011
+tmp/a/6012
+tmp/a/6013
+tmp/a/6014
+tmp/a/6015
+tmp/a/6016
+tmp/a/6017
+tmp/a/6018
+tmp/a/6019
+tmp/a/6020
+tmp/a/6021
+tmp/a/6022
+tmp/a/6023
+tmp/a/6024
+tmp/a/6025
+tmp/a/6026
+tmp/a/6027
+tmp/a/6028
+tmp/a/6029
+tmp/a/6030
+tmp/a/6031
+tmp/a/6032
+tmp/a/6033
+tmp/a/6034
+tmp/a/6035
+tmp/a/6036
+tmp/a/6037
+tmp/a/6038
+tmp/a/6039
+tmp/a/6040
+tmp/a/6041
+tmp/a/6042
+tmp/a/6043
+tmp/a/6044
+tmp/a/6045
+tmp/a/6046
+tmp/a/6047
+tmp/a/6048
+tmp/a/6049
+tmp/a/6050
+tmp/a/6051
+tmp/a/6052
+tmp/a/6053
+tmp/a/6054
+tmp/a/6055
+tmp/a/6056
+tmp/a/6057
+tmp/a/6058
+tmp/a/6059
+tmp/a/6060
+tmp/a/6061
+tmp/a/6062
+tmp/a/6063
+tmp/a/6064
+tmp/a/6065
+tmp/a/6066
+tmp/a/6067
+tmp/a/6068
+tmp/a/6069
+tmp/a/6070
+tmp/a/6071
+tmp/a/6072
+tmp/a/6073
+tmp/a/6074
+tmp/a/6075
+tmp/a/6076
+tmp/a/6077
+tmp/a/6078
+tmp/a/6079
+tmp/a/6080
+tmp/a/6081
+tmp/a/6082
+tmp/a/6083
+tmp/a/6084
+tmp/a/6085
+tmp/a/6086
+tmp/a/6087
+tmp/a/6088
+tmp/a/6089
+tmp/a/6090
+tmp/a/6091
+tmp/a/6092
+tmp/a/6093
+tmp/a/6094
+tmp/a/6095
+tmp/a/6096
+tmp/a/6097
+tmp/a/6098
+tmp/a/6099
+tmp/a/6100
+tmp/a/6101
+tmp/a/6102
+tmp/a/6103
+tmp/a/6104
+tmp/a/6105
+tmp/a/6106
+tmp/a/6107
+tmp/a/6108
+tmp/a/6109
+tmp/a/6110
+tmp/a/6111
+tmp/a/6112
+tmp/a/6113
+tmp/a/6114
+tmp/a/6115
+tmp/a/6116
+tmp/a/6117
+tmp/a/6118
+tmp/a/6119
+tmp/a/6120
+tmp/a/6121
+tmp/a/6122
+tmp/a/6123
+tmp/a/6124
+tmp/a/6125
+tmp/a/6126
+tmp/a/6127
+tmp/a/6128
+tmp/a/6129
+tmp/a/6130
+tmp/a/6131
+tmp/a/6132
+tmp/a/6133
+tmp/a/6134
+tmp/a/6135
+tmp/a/6136
+tmp/a/6137
+tmp/a/6138
+tmp/a/6139
+tmp/a/6140
+tmp/a/6141
+tmp/a/6142
+tmp/a/6143
+tmp/a/6144
+tmp/a/6145
+tmp/a/6146
+tmp/a/6147
+tmp/a/6148
+tmp/a/6149
+tmp/a/6150
+tmp/a/6151
+tmp/a/6152
+tmp/a/6153
+tmp/a/6154
+tmp/a/6155
+tmp/a/6156
+tmp/a/6157
+tmp/a/6158
+tmp/a/6159
+tmp/a/6160
+tmp/a/6161
+tmp/a/6162
+tmp/a/6163
+tmp/a/6164
+tmp/a/6165
+tmp/a/6166
+tmp/a/6167
+tmp/a/6168
+tmp/a/6169
+tmp/a/6170
+tmp/a/6171
+tmp/a/6172
+tmp/a/6173
+tmp/a/6174
+tmp/a/6175
+tmp/a/6176
+tmp/a/6177
+tmp/a/6178
+tmp/a/6179
+tmp/a/6180
+tmp/a/6181
+tmp/a/6182
+tmp/a/6183
+tmp/a/6184
+tmp/a/6185
+tmp/a/6186
+tmp/a/6187
+tmp/a/6188
+tmp/a/6189
+tmp/a/6190
+tmp/a/6191
+tmp/a/6192
+tmp/a/6193
+tmp/a/6194
+tmp/a/6195
+tmp/a/6196
+tmp/a/6197
+tmp/a/6198
+tmp/a/6199
+tmp/a/6200
+tmp/a/6201
+tmp/a/6202
+tmp/a/6203
+tmp/a/6204
+tmp/a/6205
+tmp/a/6206
+tmp/a/6207
+tmp/a/6208
+tmp/a/6209
+tmp/a/6210
+tmp/a/6211
+tmp/a/6212
+tmp/a/6213
+tmp/a/6214
+tmp/a/6215
+tmp/a/6216
+tmp/a/6217
+tmp/a/6218
+tmp/a/6219
+tmp/a/6220
+tmp/a/6221
+tmp/a/6222
+tmp/a/6223
+tmp/a/6224
+tmp/a/6225
+tmp/a/6226
+tmp/a/6227
+tmp/a/6228
+tmp/a/6229
+tmp/a/6230
+tmp/a/6231
+tmp/a/6232
+tmp/a/6233
+tmp/a/6234
+tmp/a/6235
+tmp/a/6236
+tmp/a/6237
+tmp/a/6238
+tmp/a/6239
+tmp/a/6240
+tmp/a/6241
+tmp/a/6242
+tmp/a/6243
+tmp/a/6244
+tmp/a/6245
+tmp/a/6246
+tmp/a/6247
+tmp/a/6248
+tmp/a/6249
+tmp/a/6250
+tmp/a/6251
+tmp/a/6252
+tmp/a/6253
+tmp/a/6254
+tmp/a/6255
+tmp/a/6256
+tmp/a/6257
+tmp/a/6258
+tmp/a/6259
+tmp/a/6260
+tmp/a/6261
+tmp/a/6262
+tmp/a/6263
+tmp/a/6264
+tmp/a/6265
+tmp/a/6266
+tmp/a/6267
+tmp/a/6268
+tmp/a/6269
+tmp/a/6270
+tmp/a/6271
+tmp/a/6272
+tmp/a/6273
+tmp/a/6274
+tmp/a/6275
+tmp/a/6276
+tmp/a/6277
+tmp/a/6278
+tmp/a/6279
+tmp/a/6280
+tmp/a/6281
+tmp/a/6282
+tmp/a/6283
+tmp/a/6284
+tmp/a/6285
+tmp/a/6286
+tmp/a/6287
+tmp/a/6288
+tmp/a/6289
+tmp/a/6290
+tmp/a/6291
+tmp/a/6292
+tmp/a/6293
+tmp/a/6294
+tmp/a/6295
+tmp/a/6296
+tmp/a/6297
+tmp/a/6298
+tmp/a/6299
+tmp/a/6300
+tmp/a/6301
+tmp/a/6302
+tmp/a/6303
+tmp/a/6304
+tmp/a/6305
+tmp/a/6306
+tmp/a/6307
+tmp/a/6308
+tmp/a/6309
+tmp/a/6310
+tmp/a/6311
+tmp/a/6312
+tmp/a/6313
+tmp/a/6314
+tmp/a/6315
+tmp/a/6316
+tmp/a/6317
+tmp/a/6318
+tmp/a/6319
+tmp/a/6320
+tmp/a/6321
+tmp/a/6322
+tmp/a/6323
+tmp/a/6324
+tmp/a/6325
+tmp/a/6326
+tmp/a/6327
+tmp/a/6328
+tmp/a/6329
+tmp/a/6330
+tmp/a/6331
+tmp/a/6332
+tmp/a/6333
+tmp/a/6334
+tmp/a/6335
+tmp/a/6336
+tmp/a/6337
+tmp/a/6338
+tmp/a/6339
+tmp/a/6340
+tmp/a/6341
+tmp/a/6342
+tmp/a/6343
+tmp/a/6344
+tmp/a/6345
+tmp/a/6346
+tmp/a/6347
+tmp/a/6348
+tmp/a/6349
+tmp/a/6350
+tmp/a/6351
+tmp/a/6352
+tmp/a/6353
+tmp/a/6354
+tmp/a/6355
+tmp/a/6356
+tmp/a/6357
+tmp/a/6358
+tmp/a/6359
+tmp/a/6360
+tmp/a/6361
+tmp/a/6362
+tmp/a/6363
+tmp/a/6364
+tmp/a/6365
+tmp/a/6366
+tmp/a/6367
+tmp/a/6368
+tmp/a/6369
+tmp/a/6370
+tmp/a/6371
+tmp/a/6372
+tmp/a/6373
+tmp/a/6374
+tmp/a/6375
+tmp/a/6376
+tmp/a/6377
+tmp/a/6378
+tmp/a/6379
+tmp/a/6380
+tmp/a/6381
+tmp/a/6382
+tmp/a/6383
+tmp/a/6384
+tmp/a/6385
+tmp/a/6386
+tmp/a/6387
+tmp/a/6388
+tmp/a/6389
+tmp/a/6390
+tmp/a/6391
+tmp/a/6392
+tmp/a/6393
+tmp/a/6394
+tmp/a/6395
+tmp/a/6396
+tmp/a/6397
+tmp/a/6398
+tmp/a/6399
+tmp/a/6400
+tmp/a/6401
+tmp/a/6402
+tmp/a/6403
+tmp/a/6404
+tmp/a/6405
+tmp/a/6406
+tmp/a/6407
+tmp/a/6408
+tmp/a/6409
+tmp/a/6410
+tmp/a/6411
+tmp/a/6412
+tmp/a/6413
+tmp/a/6414
+tmp/a/6415
+tmp/a/6416
+tmp/a/6417
+tmp/a/6418
+tmp/a/6419
+tmp/a/6420
+tmp/a/6421
+tmp/a/6422
+tmp/a/6423
+tmp/a/6424
+tmp/a/6425
+tmp/a/6426
+tmp/a/6427
+tmp/a/6428
+tmp/a/6429
+tmp/a/6430
+tmp/a/6431
+tmp/a/6432
+tmp/a/6433
+tmp/a/6434
+tmp/a/6435
+tmp/a/6436
+tmp/a/6437
+tmp/a/6438
+tmp/a/6439
+tmp/a/6440
+tmp/a/6441
+tmp/a/6442
+tmp/a/6443
+tmp/a/6444
+tmp/a/6445
+tmp/a/6446
+tmp/a/6447
+tmp/a/6448
+tmp/a/6449
+tmp/a/6450
+tmp/a/6451
+tmp/a/6452
+tmp/a/6453
+tmp/a/6454
+tmp/a/6455
+tmp/a/6456
+tmp/a/6457
+tmp/a/6458
+tmp/a/6459
+tmp/a/6460
+tmp/a/6461
+tmp/a/6462
+tmp/a/6463
+tmp/a/6464
+tmp/a/6465
+tmp/a/6466
+tmp/a/6467
+tmp/a/6468
+tmp/a/6469
+tmp/a/6470
+tmp/a/6471
+tmp/a/6472
+tmp/a/6473
+tmp/a/6474
+tmp/a/6475
+tmp/a/6476
+tmp/a/6477
+tmp/a/6478
+tmp/a/6479
+tmp/a/6480
+tmp/a/6481
+tmp/a/6482
+tmp/a/6483
+tmp/a/6484
+tmp/a/6485
+tmp/a/6486
+tmp/a/6487
+tmp/a/6488
+tmp/a/6489
+tmp/a/6490
+tmp/a/6491
+tmp/a/6492
+tmp/a/6493
+tmp/a/6494
+tmp/a/6495
+tmp/a/6496
+tmp/a/6497
+tmp/a/6498
+tmp/a/6499
+tmp/a/6500
+tmp/a/6501
+tmp/a/6502
+tmp/a/6503
+tmp/a/6504
+tmp/a/6505
+tmp/a/6506
+tmp/a/6507
+tmp/a/6508
+tmp/a/6509
+tmp/a/6510
+tmp/a/6511
+tmp/a/6512
+tmp/a/6513
+tmp/a/6514
+tmp/a/6515
+tmp/a/6516
+tmp/a/6517
+tmp/a/6518
+tmp/a/6519
+tmp/a/6520
+tmp/a/6521
+tmp/a/6522
+tmp/a/6523
+tmp/a/6524
+tmp/a/6525
+tmp/a/6526
+tmp/a/6527
+tmp/a/6528
+tmp/a/6529
+tmp/a/6530
+tmp/a/6531
+tmp/a/6532
+tmp/a/6533
+tmp/a/6534
+tmp/a/6535
+tmp/a/6536
+tmp/a/6537
+tmp/a/6538
+tmp/a/6539
+tmp/a/6540
+tmp/a/6541
+tmp/a/6542
+tmp/a/6543
+tmp/a/6544
+tmp/a/6545
+tmp/a/6546
+tmp/a/6547
+tmp/a/6548
+tmp/a/6549
+tmp/a/6550
+tmp/a/6551
+tmp/a/6552
+tmp/a/6553
+tmp/a/6554
+tmp/a/6555
+tmp/a/6556
+tmp/a/6557
+tmp/a/6558
+tmp/a/6559
+tmp/a/6560
+tmp/a/6561
+tmp/a/6562
+tmp/a/6563
+tmp/a/6564
+tmp/a/6565
+tmp/a/6566
+tmp/a/6567
+tmp/a/6568
+tmp/a/6569
+tmp/a/6570
+tmp/a/6571
+tmp/a/6572
+tmp/a/6573
+tmp/a/6574
+tmp/a/6575
+tmp/a/6576
+tmp/a/6577
+tmp/a/6578
+tmp/a/6579
+tmp/a/6580
+tmp/a/6581
+tmp/a/6582
+tmp/a/6583
+tmp/a/6584
+tmp/a/6585
+tmp/a/6586
+tmp/a/6587
+tmp/a/6588
+tmp/a/6589
+tmp/a/6590
+tmp/a/6591
+tmp/a/6592
+tmp/a/6593
+tmp/a/6594
+tmp/a/6595
+tmp/a/6596
+tmp/a/6597
+tmp/a/6598
+tmp/a/6599
+tmp/a/6600
+tmp/a/6601
+tmp/a/6602
+tmp/a/6603
+tmp/a/6604
+tmp/a/6605
+tmp/a/6606
+tmp/a/6607
+tmp/a/6608
+tmp/a/6609
+tmp/a/6610
+tmp/a/6611
+tmp/a/6612
+tmp/a/6613
+tmp/a/6614
+tmp/a/6615
+tmp/a/6616
+tmp/a/6617
+tmp/a/6618
+tmp/a/6619
+tmp/a/6620
+tmp/a/6621
+tmp/a/6622
+tmp/a/6623
+tmp/a/6624
+tmp/a/6625
+tmp/a/6626
+tmp/a/6627
+tmp/a/6628
+tmp/a/6629
+tmp/a/6630
+tmp/a/6631
+tmp/a/6632
+tmp/a/6633
+tmp/a/6634
+tmp/a/6635
+tmp/a/6636
+tmp/a/6637
+tmp/a/6638
+tmp/a/6639
+tmp/a/6640
+tmp/a/6641
+tmp/a/6642
+tmp/a/6643
+tmp/a/6644
+tmp/a/6645
+tmp/a/6646
+tmp/a/6647
+tmp/a/6648
+tmp/a/6649
+tmp/a/6650
+tmp/a/6651
+tmp/a/6652
+tmp/a/6653
+tmp/a/6654
+tmp/a/6655
+tmp/a/6656
+tmp/a/6657
+tmp/a/6658
+tmp/a/6659
+tmp/a/6660
+tmp/a/6661
+tmp/a/6662
+tmp/a/6663
+tmp/a/6664
+tmp/a/6665
+tmp/a/6666
+tmp/a/6667
+tmp/a/6668
+tmp/a/6669
+tmp/a/6670
+tmp/a/6671
+tmp/a/6672
+tmp/a/6673
+tmp/a/6674
+tmp/a/6675
+tmp/a/6676
+tmp/a/6677
+tmp/a/6678
+tmp/a/6679
+tmp/a/6680
+tmp/a/6681
+tmp/a/6682
+tmp/a/6683
+tmp/a/6684
+tmp/a/6685
+tmp/a/6686
+tmp/a/6687
+tmp/a/6688
+tmp/a/6689
+tmp/a/6690
+tmp/a/6691
+tmp/a/6692
+tmp/a/6693
+tmp/a/6694
+tmp/a/6695
+tmp/a/6696
+tmp/a/6697
+tmp/a/6698
+tmp/a/6699
+tmp/a/6700
+tmp/a/6701
+tmp/a/6702
+tmp/a/6703
+tmp/a/6704
+tmp/a/6705
+tmp/a/6706
+tmp/a/6707
+tmp/a/6708
+tmp/a/6709
+tmp/a/6710
+tmp/a/6711
+tmp/a/6712
+tmp/a/6713
+tmp/a/6714
+tmp/a/6715
+tmp/a/6716
+tmp/a/6717
+tmp/a/6718
+tmp/a/6719
+tmp/a/6720
+tmp/a/6721
+tmp/a/6722
+tmp/a/6723
+tmp/a/6724
+tmp/a/6725
+tmp/a/6726
+tmp/a/6727
+tmp/a/6728
+tmp/a/6729
+tmp/a/6730
+tmp/a/6731
+tmp/a/6732
+tmp/a/6733
+tmp/a/6734
+tmp/a/6735
+tmp/a/6736
+tmp/a/6737
+tmp/a/6738
+tmp/a/6739
+tmp/a/6740
+tmp/a/6741
+tmp/a/6742
+tmp/a/6743
+tmp/a/6744
+tmp/a/6745
+tmp/a/6746
+tmp/a/6747
+tmp/a/6748
+tmp/a/6749
+tmp/a/6750
+tmp/a/6751
+tmp/a/6752
+tmp/a/6753
+tmp/a/6754
+tmp/a/6755
+tmp/a/6756
+tmp/a/6757
+tmp/a/6758
+tmp/a/6759
+tmp/a/6760
+tmp/a/6761
+tmp/a/6762
+tmp/a/6763
+tmp/a/6764
+tmp/a/6765
+tmp/a/6766
+tmp/a/6767
+tmp/a/6768
+tmp/a/6769
+tmp/a/6770
+tmp/a/6771
+tmp/a/6772
+tmp/a/6773
+tmp/a/6774
+tmp/a/6775
+tmp/a/6776
+tmp/a/6777
+tmp/a/6778
+tmp/a/6779
+tmp/a/6780
+tmp/a/6781
+tmp/a/6782
+tmp/a/6783
+tmp/a/6784
+tmp/a/6785
+tmp/a/6786
+tmp/a/6787
+tmp/a/6788
+tmp/a/6789
+tmp/a/6790
+tmp/a/6791
+tmp/a/6792
+tmp/a/6793
+tmp/a/6794
+tmp/a/6795
+tmp/a/6796
+tmp/a/6797
+tmp/a/6798
+tmp/a/6799
+tmp/a/6800
+tmp/a/6801
+tmp/a/6802
+tmp/a/6803
+tmp/a/6804
+tmp/a/6805
+tmp/a/6806
+tmp/a/6807
+tmp/a/6808
+tmp/a/6809
+tmp/a/6810
+tmp/a/6811
+tmp/a/6812
+tmp/a/6813
+tmp/a/6814
+tmp/a/6815
+tmp/a/6816
+tmp/a/6817
+tmp/a/6818
+tmp/a/6819
+tmp/a/6820
+tmp/a/6821
+tmp/a/6822
+tmp/a/6823
+tmp/a/6824
+tmp/a/6825
+tmp/a/6826
+tmp/a/6827
+tmp/a/6828
+tmp/a/6829
+tmp/a/6830
+tmp/a/6831
+tmp/a/6832
+tmp/a/6833
+tmp/a/6834
+tmp/a/6835
+tmp/a/6836
+tmp/a/6837
+tmp/a/6838
+tmp/a/6839
+tmp/a/6840
+tmp/a/6841
+tmp/a/6842
+tmp/a/6843
+tmp/a/6844
+tmp/a/6845
+tmp/a/6846
+tmp/a/6847
+tmp/a/6848
+tmp/a/6849
+tmp/a/6850
+tmp/a/6851
+tmp/a/6852
+tmp/a/6853
+tmp/a/6854
+tmp/a/6855
+tmp/a/6856
+tmp/a/6857
+tmp/a/6858
+tmp/a/6859
+tmp/a/6860
+tmp/a/6861
+tmp/a/6862
+tmp/a/6863
+tmp/a/6864
+tmp/a/6865
+tmp/a/6866
+tmp/a/6867
+tmp/a/6868
+tmp/a/6869
+tmp/a/6870
+tmp/a/6871
+tmp/a/6872
+tmp/a/6873
+tmp/a/6874
+tmp/a/6875
+tmp/a/6876
+tmp/a/6877
+tmp/a/6878
+tmp/a/6879
+tmp/a/6880
+tmp/a/6881
+tmp/a/6882
+tmp/a/6883
+tmp/a/6884
+tmp/a/6885
+tmp/a/6886
+tmp/a/6887
+tmp/a/6888
+tmp/a/6889
+tmp/a/6890
+tmp/a/6891
+tmp/a/6892
+tmp/a/6893
+tmp/a/6894
+tmp/a/6895
+tmp/a/6896
+tmp/a/6897
+tmp/a/6898
+tmp/a/6899
+tmp/a/6900
+tmp/a/6901
+tmp/a/6902
+tmp/a/6903
+tmp/a/6904
+tmp/a/6905
+tmp/a/6906
+tmp/a/6907
+tmp/a/6908
+tmp/a/6909
+tmp/a/6910
+tmp/a/6911
+tmp/a/6912
+tmp/a/6913
+tmp/a/6914
+tmp/a/6915
+tmp/a/6916
+tmp/a/6917
+tmp/a/6918
+tmp/a/6919
+tmp/a/6920
+tmp/a/6921
+tmp/a/6922
+tmp/a/6923
+tmp/a/6924
+tmp/a/6925
+tmp/a/6926
+tmp/a/6927
+tmp/a/6928
+tmp/a/6929
+tmp/a/6930
+tmp/a/6931
+tmp/a/6932
+tmp/a/6933
+tmp/a/6934
+tmp/a/6935
+tmp/a/6936
+tmp/a/6937
+tmp/a/6938
+tmp/a/6939
+tmp/a/6940
+tmp/a/6941
+tmp/a/6942
+tmp/a/6943
+tmp/a/6944
+tmp/a/6945
+tmp/a/6946
+tmp/a/6947
+tmp/a/6948
+tmp/a/6949
+tmp/a/6950
+tmp/a/6951
+tmp/a/6952
+tmp/a/6953
+tmp/a/6954
+tmp/a/6955
+tmp/a/6956
+tmp/a/6957
+tmp/a/6958
+tmp/a/6959
+tmp/a/6960
+tmp/a/6961
+tmp/a/6962
+tmp/a/6963
+tmp/a/6964
+tmp/a/6965
+tmp/a/6966
+tmp/a/6967
+tmp/a/6968
+tmp/a/6969
+tmp/a/6970
+tmp/a/6971
+tmp/a/6972
+tmp/a/6973
+tmp/a/6974
+tmp/a/6975
+tmp/a/6976
+tmp/a/6977
+tmp/a/6978
+tmp/a/6979
+tmp/a/6980
+tmp/a/6981
+tmp/a/6982
+tmp/a/6983
+tmp/a/6984
+tmp/a/6985
+tmp/a/6986
+tmp/a/6987
+tmp/a/6988
+tmp/a/6989
+tmp/a/6990
+tmp/a/6991
+tmp/a/6992
+tmp/a/6993
+tmp/a/6994
+tmp/a/6995
+tmp/a/6996
+tmp/a/6997
+tmp/a/6998
+tmp/a/6999
+tmp/a/7000
+tmp/a/7001
+tmp/a/7002
+tmp/a/7003
+tmp/a/7004
+tmp/a/7005
+tmp/a/7006
+tmp/a/7007
+tmp/a/7008
+tmp/a/7009
+tmp/a/7010
+tmp/a/7011
+tmp/a/7012
+tmp/a/7013
+tmp/a/7014
+tmp/a/7015
+tmp/a/7016
+tmp/a/7017
+tmp/a/7018
+tmp/a/7019
+tmp/a/7020
+tmp/a/7021
+tmp/a/7022
+tmp/a/7023
+tmp/a/7024
+tmp/a/7025
+tmp/a/7026
+tmp/a/7027
+tmp/a/7028
+tmp/a/7029
+tmp/a/7030
+tmp/a/7031
+tmp/a/7032
+tmp/a/7033
+tmp/a/7034
+tmp/a/7035
+tmp/a/7036
+tmp/a/7037
+tmp/a/7038
+tmp/a/7039
+tmp/a/7040
+tmp/a/7041
+tmp/a/7042
+tmp/a/7043
+tmp/a/7044
+tmp/a/7045
+tmp/a/7046
+tmp/a/7047
+tmp/a/7048
+tmp/a/7049
+tmp/a/7050
+tmp/a/7051
+tmp/a/7052
+tmp/a/7053
+tmp/a/7054
+tmp/a/7055
+tmp/a/7056
+tmp/a/7057
+tmp/a/7058
+tmp/a/7059
+tmp/a/7060
+tmp/a/7061
+tmp/a/7062
+tmp/a/7063
+tmp/a/7064
+tmp/a/7065
+tmp/a/7066
+tmp/a/7067
+tmp/a/7068
+tmp/a/7069
+tmp/a/7070
+tmp/a/7071
+tmp/a/7072
+tmp/a/7073
+tmp/a/7074
+tmp/a/7075
+tmp/a/7076
+tmp/a/7077
+tmp/a/7078
+tmp/a/7079
+tmp/a/7080
+tmp/a/7081
+tmp/a/7082
+tmp/a/7083
+tmp/a/7084
+tmp/a/7085
+tmp/a/7086
+tmp/a/7087
+tmp/a/7088
+tmp/a/7089
+tmp/a/7090
+tmp/a/7091
+tmp/a/7092
+tmp/a/7093
+tmp/a/7094
+tmp/a/7095
+tmp/a/7096
+tmp/a/7097
+tmp/a/7098
+tmp/a/7099
+tmp/a/7100
+tmp/a/7101
+tmp/a/7102
+tmp/a/7103
+tmp/a/7104
+tmp/a/7105
+tmp/a/7106
+tmp/a/7107
+tmp/a/7108
+tmp/a/7109
+tmp/a/7110
+tmp/a/7111
+tmp/a/7112
+tmp/a/7113
+tmp/a/7114
+tmp/a/7115
+tmp/a/7116
+tmp/a/7117
+tmp/a/7118
+tmp/a/7119
+tmp/a/7120
+tmp/a/7121
+tmp/a/7122
+tmp/a/7123
+tmp/a/7124
+tmp/a/7125
+tmp/a/7126
+tmp/a/7127
+tmp/a/7128
+tmp/a/7129
+tmp/a/7130
+tmp/a/7131
+tmp/a/7132
+tmp/a/7133
+tmp/a/7134
+tmp/a/7135
+tmp/a/7136
+tmp/a/7137
+tmp/a/7138
+tmp/a/7139
+tmp/a/7140
+tmp/a/7141
+tmp/a/7142
+tmp/a/7143
+tmp/a/7144
+tmp/a/7145
+tmp/a/7146
+tmp/a/7147
+tmp/a/7148
+tmp/a/7149
+tmp/a/7150
+tmp/a/7151
+tmp/a/7152
+tmp/a/7153
+tmp/a/7154
+tmp/a/7155
+tmp/a/7156
+tmp/a/7157
+tmp/a/7158
+tmp/a/7159
+tmp/a/7160
+tmp/a/7161
+tmp/a/7162
+tmp/a/7163
+tmp/a/7164
+tmp/a/7165
+tmp/a/7166
+tmp/a/7167
+tmp/a/7168
+tmp/a/7169
+tmp/a/7170
+tmp/a/7171
+tmp/a/7172
+tmp/a/7173
+tmp/a/7174
+tmp/a/7175
+tmp/a/7176
+tmp/a/7177
+tmp/a/7178
+tmp/a/7179
+tmp/a/7180
+tmp/a/7181
+tmp/a/7182
+tmp/a/7183
+tmp/a/7184
+tmp/a/7185
+tmp/a/7186
+tmp/a/7187
+tmp/a/7188
+tmp/a/7189
+tmp/a/7190
+tmp/a/7191
+tmp/a/7192
+tmp/a/7193
+tmp/a/7194
+tmp/a/7195
+tmp/a/7196
+tmp/a/7197
+tmp/a/7198
+tmp/a/7199
+tmp/a/7200
diff --git a/find/testsuite/find.posix/exec-one.exp b/find/testsuite/find.posix/exec-one.exp
new file mode 100644
index 0000000..a4a7ef6
--- /dev/null
+++ b/find/testsuite/find.posix/exec-one.exp
@@ -0,0 +1,5 @@
+# tests for -name
+exec rm -rf tmp
+exec mkdir tmp tmp/fred tmp/jim
+find_start p {tmp -name fred -exec echo \{\} \; }
+exec rm -rf tmp
diff --git a/find/testsuite/find.posix/exec-one.xo b/find/testsuite/find.posix/exec-one.xo
new file mode 100644
index 0000000..8cc8940
--- /dev/null
+++ b/find/testsuite/find.posix/exec-one.xo
@@ -0,0 +1 @@
+tmp/fred
diff --git a/find/testsuite/find.posix/files-not-expressions1.exp b/find/testsuite/find.posix/files-not-expressions1.exp
new file mode 100644
index 0000000..b54ff8c
--- /dev/null
+++ b/find/testsuite/find.posix/files-not-expressions1.exp
@@ -0,0 +1,8 @@
+set files "\(1 "
+
+foreach file $files { touch $file }
+
+# shoud not result in a fatal error.
+find_start p { \(1 }
+
+foreach file $files { file delete -- $file }
diff --git a/find/testsuite/find.posix/files-not-expressions1.xo b/find/testsuite/find.posix/files-not-expressions1.xo
new file mode 100644
index 0000000..000b2a0
--- /dev/null
+++ b/find/testsuite/find.posix/files-not-expressions1.xo
@@ -0,0 +1 @@
+(1
diff --git a/find/testsuite/find.posix/files-not-expressions2.exp b/find/testsuite/find.posix/files-not-expressions2.exp
new file mode 100644
index 0000000..b699a24
--- /dev/null
+++ b/find/testsuite/find.posix/files-not-expressions2.exp
@@ -0,0 +1,8 @@
+set files "!2"
+
+foreach file $files { touch $file }
+
+# shoud not result in a fatal error.
+find_start p { !2 }
+
+foreach file $files { file delete -- $file }
diff --git a/find/testsuite/find.posix/files-not-expressions2.xo b/find/testsuite/find.posix/files-not-expressions2.xo
new file mode 100644
index 0000000..a829de6
--- /dev/null
+++ b/find/testsuite/find.posix/files-not-expressions2.xo
@@ -0,0 +1 @@
+!2
diff --git a/find/testsuite/find.posix/files-not-expressions3.exp b/find/testsuite/find.posix/files-not-expressions3.exp
new file mode 100644
index 0000000..96749e0
--- /dev/null
+++ b/find/testsuite/find.posix/files-not-expressions3.exp
@@ -0,0 +1,8 @@
+set files "\)"
+
+foreach file $files { touch $file }
+
+# shoud not result in a fatal error.
+find_start p { \) }
+
+foreach file $files { file delete -- $file }
diff --git a/find/testsuite/find.posix/files-not-expressions3.xo b/find/testsuite/find.posix/files-not-expressions3.xo
new file mode 100644
index 0000000..bea8cd1
--- /dev/null
+++ b/find/testsuite/find.posix/files-not-expressions3.xo
@@ -0,0 +1 @@
+)
diff --git a/find/testsuite/find.posix/group-empty.exp b/find/testsuite/find.posix/group-empty.exp
new file mode 100644
index 0000000..3e83190
--- /dev/null
+++ b/find/testsuite/find.posix/group-empty.exp
@@ -0,0 +1,2 @@
+# test for diagnosis of the fact that the argument to -group is empty
+find_start f { . -group "" }
diff --git a/find/testsuite/find.posix/group-missing.exp b/find/testsuite/find.posix/group-missing.exp
new file mode 100644
index 0000000..c3e2735
--- /dev/null
+++ b/find/testsuite/find.posix/group-missing.exp
@@ -0,0 +1,5 @@
+# test for diagnosis of the fact that the argument to -group is missing
+exec rm -rf tmp
+exec touch tmp
+find_start f { tmp -group }
+exec rm -rf tmp
diff --git a/find/testsuite/find.posix/grouping.exp b/find/testsuite/find.posix/grouping.exp
new file mode 100644
index 0000000..c5ce2d7
--- /dev/null
+++ b/find/testsuite/find.posix/grouping.exp
@@ -0,0 +1,5 @@
+# tests for !
+exec rm -rf tmp
+exec mkdir tmp tmp/fred tmp/jim
+find_start p {tmp \! \( -name fred -o -name tmp \) -print}
+exec rm -rf tmp
diff --git a/find/testsuite/find.posix/grouping.xo b/find/testsuite/find.posix/grouping.xo
new file mode 100644
index 0000000..a7eac4c
--- /dev/null
+++ b/find/testsuite/find.posix/grouping.xo
@@ -0,0 +1 @@
+tmp/jim \ No newline at end of file
diff --git a/find/testsuite/find.posix/links.exp b/find/testsuite/find.posix/links.exp
new file mode 100644
index 0000000..adb0fae
--- /dev/null
+++ b/find/testsuite/find.posix/links.exp
@@ -0,0 +1,25 @@
+# tests for -links
+exec rm -rf tmp
+exec mkdir tmp
+touch tmp/file1 tmp/file2 tmp/file3
+
+# four links including the original file
+exec ln tmp/file1 tmp/1a
+exec ln tmp/file1 tmp/1b
+exec ln tmp/file1 tmp/1c
+
+# five links including the original file
+exec ln tmp/file2 tmp/2a
+exec ln tmp/file2 tmp/2b
+exec ln tmp/file2 tmp/2c
+exec ln tmp/file2 tmp/2d
+
+# six links including the original file
+exec ln tmp/file3 tmp/3a
+exec ln tmp/file3 tmp/3b
+exec ln tmp/file3 tmp/3c
+exec ln tmp/file3 tmp/3d
+exec ln tmp/file3 tmp/3e
+
+find_start p { tmp/file1 tmp/file2 tmp/file3 -type f ( ( -links -5 -exec echo under5 \{\} \; ) -o ( -links 5 -exec echo exactly5 \{\} \; ) -o ( -links +5 -exec echo over5 \{\} \; ) ) }
+exec rm -rf tmp
diff --git a/find/testsuite/find.posix/links.xo b/find/testsuite/find.posix/links.xo
new file mode 100644
index 0000000..311447f
--- /dev/null
+++ b/find/testsuite/find.posix/links.xo
@@ -0,0 +1,3 @@
+exactly5 tmp/file2
+over5 tmp/file3
+under5 tmp/file1
diff --git a/find/testsuite/find.posix/mtime0.exp b/find/testsuite/find.posix/mtime0.exp
new file mode 100644
index 0000000..23237a1
--- /dev/null
+++ b/find/testsuite/find.posix/mtime0.exp
@@ -0,0 +1,10 @@
+## Test for find . -mtime 0
+## This detects Savannah bug #22056, -Xtime tests are off by one second
+
+exec rm -rf tmp
+exec mkdir tmp
+# Touch the file in the setup phase, to make sure its mtime is as
+# recent as possible.
+proc prep {} { exec touch tmp/x }
+find_start p { tmp -type f -mtime 0 } "" "" prep
+exec rm -rf tmp
diff --git a/find/testsuite/find.posix/mtime0.xo b/find/testsuite/find.posix/mtime0.xo
new file mode 100644
index 0000000..74c14ef
--- /dev/null
+++ b/find/testsuite/find.posix/mtime0.xo
@@ -0,0 +1 @@
+tmp/x
diff --git a/find/testsuite/find.posix/name-missing.exp b/find/testsuite/find.posix/name-missing.exp
new file mode 100644
index 0000000..da8ae5a
--- /dev/null
+++ b/find/testsuite/find.posix/name-missing.exp
@@ -0,0 +1,5 @@
+# test for diagnosis of the fact that the argument to -name is missing
+exec rm -rf tmp
+exec touch tmp
+find_start f { tmp -name }
+exec rm -rf tmp
diff --git a/find/testsuite/find.posix/name.exp b/find/testsuite/find.posix/name.exp
new file mode 100644
index 0000000..65c6f5f
--- /dev/null
+++ b/find/testsuite/find.posix/name.exp
@@ -0,0 +1,5 @@
+# tests for -name
+exec rm -rf tmp
+exec mkdir tmp tmp/fred tmp/jim
+find_start p {tmp -name fred -print}
+exec rm -rf tmp
diff --git a/find/testsuite/find.posix/name.xo b/find/testsuite/find.posix/name.xo
new file mode 100644
index 0000000..8cc8940
--- /dev/null
+++ b/find/testsuite/find.posix/name.xo
@@ -0,0 +1 @@
+tmp/fred
diff --git a/find/testsuite/find.posix/nameslash.exp b/find/testsuite/find.posix/nameslash.exp
new file mode 100644
index 0000000..a8b91ab
--- /dev/null
+++ b/find/testsuite/find.posix/nameslash.exp
@@ -0,0 +1,7 @@
+# tests for -name and trailing slashes.
+# See http://www.opengroup.org/austin/interps/uploads/40/14959/AI-186.txt
+# This is a test for Savannah bug #20970.
+exec rm -rf tmp
+exec mkdir tmp tmp/foo tmp/bar
+find_start p {tmp/foo/// tmp/bar/// -name foo -o -name 'bar?*'}
+exec rm -rf tmp
diff --git a/find/testsuite/find.posix/nameslash.xo b/find/testsuite/find.posix/nameslash.xo
new file mode 100644
index 0000000..e94ef73
--- /dev/null
+++ b/find/testsuite/find.posix/nameslash.xo
@@ -0,0 +1 @@
+tmp/foo///
diff --git a/find/testsuite/find.posix/parent.exp b/find/testsuite/find.posix/parent.exp
new file mode 100644
index 0000000..1cdca3b
--- /dev/null
+++ b/find/testsuite/find.posix/parent.exp
@@ -0,0 +1,7 @@
+# test for handling of unreadable parent directory
+exec rm -rf tmp
+exec mkdir tmp tmp/dir
+exec chmod a-rw tmp
+find_start p {tmp/dir}
+exec chmod u+rw tmp
+exec rm -rf tmp
diff --git a/find/testsuite/find.posix/parent.xo b/find/testsuite/find.posix/parent.xo
new file mode 100644
index 0000000..2dc4706
--- /dev/null
+++ b/find/testsuite/find.posix/parent.xo
@@ -0,0 +1 @@
+tmp/dir
diff --git a/find/testsuite/find.posix/perm-X.exp b/find/testsuite/find.posix/perm-X.exp
new file mode 100644
index 0000000..28e78ad
--- /dev/null
+++ b/find/testsuite/find.posix/perm-X.exp
@@ -0,0 +1,12 @@
+# tests for -perm with X
+exec rm -rf tmp
+exec mkdir tmp
+exec chmod 755 tmp
+exec true > tmp/empty
+exec true > tmp/empty-xxx
+exec chmod 711 tmp/empty-xxx
+exec mkdir tmp/sub
+exec chmod 300 tmp/sub
+find_start p { tmp \( ! -name sub -o -prune \) -perm -u+w,a+X -print }
+exec chmod 700 tmp/sub
+exec rm -rf tmp
diff --git a/find/testsuite/find.posix/perm-X.xo b/find/testsuite/find.posix/perm-X.xo
new file mode 100644
index 0000000..2af57aa
--- /dev/null
+++ b/find/testsuite/find.posix/perm-X.xo
@@ -0,0 +1,3 @@
+tmp
+tmp/empty
+tmp/empty-xxx
diff --git a/find/testsuite/find.posix/perm-vanilla.exp b/find/testsuite/find.posix/perm-vanilla.exp
new file mode 100644
index 0000000..d4b9f78
--- /dev/null
+++ b/find/testsuite/find.posix/perm-vanilla.exp
@@ -0,0 +1,18 @@
+# tests for -perm
+exec rm -rf tmp
+exec mkdir tmp
+
+## set up a selection of test files
+foreach perm { 400 555 700 } {
+ touch "tmp/$perm"
+ exec chmod $perm "tmp/$perm"
+}
+exec ls -l tmp
+
+#
+# The -o operator normally has a short-circuit effect,
+# so we have to use "-exec false \;" to make sure that
+# all the parenthesised expression actually fail.
+#
+find_start p {tmp/400 tmp/555 tmp/700 \( -perm 400 -exec echo p400 \{\} \; -exec false \; \) -o \( -perm -400 -exec echo p-400 \{\} \; -exec false \; \) }
+# exec rm -rf tmp tmp2
diff --git a/find/testsuite/find.posix/perm-vanilla.xo b/find/testsuite/find.posix/perm-vanilla.xo
new file mode 100644
index 0000000..6724004
--- /dev/null
+++ b/find/testsuite/find.posix/perm-vanilla.xo
@@ -0,0 +1,4 @@
+p400 tmp/400
+p-400 tmp/400
+p-400 tmp/555
+p-400 tmp/700
diff --git a/find/testsuite/find.posix/posixnot.exp b/find/testsuite/find.posix/posixnot.exp
new file mode 100644
index 0000000..859309d
--- /dev/null
+++ b/find/testsuite/find.posix/posixnot.exp
@@ -0,0 +1,5 @@
+# tests for !
+exec rm -rf tmp
+exec mkdir tmp tmp/fred tmp/jim
+find_start p {tmp \! -name fred -print}
+exec rm -rf tmp
diff --git a/find/testsuite/find.posix/posixnot.xo b/find/testsuite/find.posix/posixnot.xo
new file mode 100644
index 0000000..776fed4
--- /dev/null
+++ b/find/testsuite/find.posix/posixnot.xo
@@ -0,0 +1,2 @@
+tmp
+tmp/jim \ No newline at end of file
diff --git a/find/testsuite/find.posix/prune-result.exp b/find/testsuite/find.posix/prune-result.exp
new file mode 100644
index 0000000..f770bfe
--- /dev/null
+++ b/find/testsuite/find.posix/prune-result.exp
@@ -0,0 +1,7 @@
+# test for return value of -prune. It should always return true,
+# even if -depth is in effect
+exec rm -rf tmp
+exec mkdir tmp tmp/a
+touch tmp/a/f
+find_start p {tmp -depth -name a -prune -o -print }
+exec rm -rf tmp
diff --git a/find/testsuite/find.posix/prune-result.xo b/find/testsuite/find.posix/prune-result.xo
new file mode 100644
index 0000000..11f0bbe
--- /dev/null
+++ b/find/testsuite/find.posix/prune-result.xo
@@ -0,0 +1,2 @@
+tmp
+tmp/a/f
diff --git a/find/testsuite/find.posix/prune-stat.exp b/find/testsuite/find.posix/prune-stat.exp
new file mode 100644
index 0000000..b418d78
--- /dev/null
+++ b/find/testsuite/find.posix/prune-stat.exp
@@ -0,0 +1,7 @@
+# tests that -prune gets stat information
+exec rm -rf tmp
+exec mkdir tmp tmp/a
+exec touch tmp/b
+exec mkdir tmp/c
+find_start p {tmp -name b -prune -o -print }
+exec rm -rf tmp
diff --git a/find/testsuite/find.posix/prune-stat.xo b/find/testsuite/find.posix/prune-stat.xo
new file mode 100644
index 0000000..471c9c4
--- /dev/null
+++ b/find/testsuite/find.posix/prune-stat.xo
@@ -0,0 +1,3 @@
+tmp
+tmp/a
+tmp/c
diff --git a/find/testsuite/find.posix/prune.exp b/find/testsuite/find.posix/prune.exp
new file mode 100644
index 0000000..10c1bb0
--- /dev/null
+++ b/find/testsuite/find.posix/prune.exp
@@ -0,0 +1,5 @@
+# tests for -name
+exec rm -rf tmp
+exec mkdir tmp tmp/fred tmp/jim tmp/jim/1 tmp/shiela
+find_start p {tmp -name jim -prune -o -print }
+#exec rm -rf tmp
diff --git a/find/testsuite/find.posix/prune.xo b/find/testsuite/find.posix/prune.xo
new file mode 100644
index 0000000..afe68f8
--- /dev/null
+++ b/find/testsuite/find.posix/prune.xo
@@ -0,0 +1,3 @@
+tmp
+tmp/fred
+tmp/shiela
diff --git a/find/testsuite/find.posix/size-invalid.exp b/find/testsuite/find.posix/size-invalid.exp
new file mode 100644
index 0000000..4989438
--- /dev/null
+++ b/find/testsuite/find.posix/size-invalid.exp
@@ -0,0 +1,7 @@
+# test for diagnosis of the fact that the argument to -size is invalid
+exec rm -rf tmp
+exec touch tmp
+foreach size { w b c k m G "" +-1 +-1G 1.2k } {
+ find_start f " tmp -size $size "
+}
+exec rm -rf tmp
diff --git a/find/testsuite/find.posix/size-missing.exp b/find/testsuite/find.posix/size-missing.exp
new file mode 100644
index 0000000..74ad151
--- /dev/null
+++ b/find/testsuite/find.posix/size-missing.exp
@@ -0,0 +1,5 @@
+# test for diagnosis of the fact that the argument to -size is missing
+exec rm -rf tmp
+exec touch tmp
+find_start f { tmp -size }
+exec rm -rf tmp
diff --git a/find/testsuite/find.posix/sizes.exp b/find/testsuite/find.posix/sizes.exp
new file mode 100644
index 0000000..272498e
--- /dev/null
+++ b/find/testsuite/find.posix/sizes.exp
@@ -0,0 +1,15 @@
+# tests for -size
+exec rm -rf tmp
+exec mkdir tmp
+exec true > tmp/0-bytes
+exec dd if=/dev/zero bs=1 count=511 of=tmp/511-bytes > /dev/null 2>/dev/null
+exec dd if=/dev/zero bs=1 count=512 of=tmp/512-bytes > /dev/null 2>/dev/null
+exec dd if=/dev/zero bs=1 count=513 of=tmp/513-bytes > /dev/null 2>/dev/null
+exec dd if=/dev/zero bs=1 count=1024 of=tmp/1024-bytes > /dev/null 2>/dev/null
+find_start p {tmp -mindepth 1 ( -size -1 -printf "A size -1: %s %p\n" ) , ( -size 1 -printf "B size 1: %s %p\n" ) , ( -size +1 -printf "C size +1: %s %p\n" ) , ( -size -2 -printf "G size -2: %s %p\n" ) , ( -size 2 -printf "H size 2: %s %p\n" ) , ( -size +2 -printf "I size +2: %s %p\n" ) }
+# ( -size =1 -printf "E size =1: %s %p\n" )
+# ( -size >1 -printf "F size >1: %s %p\n" ) ,
+# ( -size <2 -printf "J size <2: %s %p\n" ) ,
+# ( -size =2 -printf "K size =2: %s %p\n" ) ,
+# ( -size >2 -printf "L size >2: %s %p\n" )
+exec rm -rf tmp
diff --git a/find/testsuite/find.posix/sizes.xo b/find/testsuite/find.posix/sizes.xo
new file mode 100644
index 0000000..f89a10c
--- /dev/null
+++ b/find/testsuite/find.posix/sizes.xo
@@ -0,0 +1,10 @@
+A size -1: 0 tmp/0-bytes
+B size 1: 511 tmp/511-bytes
+B size 1: 512 tmp/512-bytes
+C size +1: 513 tmp/513-bytes
+C size +1: 1024 tmp/1024-bytes
+H size 2: 513 tmp/513-bytes
+H size 2: 1024 tmp/1024-bytes
+G size -2: 0 tmp/0-bytes
+G size -2: 511 tmp/511-bytes
+G size -2: 512 tmp/512-bytes
diff --git a/find/testsuite/find.posix/sizetype.exp b/find/testsuite/find.posix/sizetype.exp
new file mode 100644
index 0000000..b9dedf3
--- /dev/null
+++ b/find/testsuite/find.posix/sizetype.exp
@@ -0,0 +1,6 @@
+# tests for -size -type
+exec rm -rf tmp
+exec mkdir tmp
+exec true > tmp/empty
+find_start p {tmp -size 0c -type f }
+exec rm -rf tmp
diff --git a/find/testsuite/find.posix/sizetype.xo b/find/testsuite/find.posix/sizetype.xo
new file mode 100644
index 0000000..445f1d4
--- /dev/null
+++ b/find/testsuite/find.posix/sizetype.xo
@@ -0,0 +1 @@
+tmp/empty
diff --git a/find/testsuite/find.posix/sv-bug-11175.exp b/find/testsuite/find.posix/sv-bug-11175.exp
new file mode 100644
index 0000000..06dd160
--- /dev/null
+++ b/find/testsuite/find.posix/sv-bug-11175.exp
@@ -0,0 +1,10 @@
+# tests for Savannah bug 11175 (should not check perms of pruned dir)
+exec rm -rf tmp
+exec mkdir tmp
+exec mkdir tmp/noxdir
+exec chmod 700 tmp
+exec chmod 600 tmp/noxdir
+#find_start p {tmp/noxdir -prune -type d -print}
+find_start p {tmp -name noxdir -prune -type d -print}
+exec chmod 700 tmp/noxdir
+exec rm -rf tmp
diff --git a/find/testsuite/find.posix/sv-bug-11175.xo b/find/testsuite/find.posix/sv-bug-11175.xo
new file mode 100644
index 0000000..cd9c95f
--- /dev/null
+++ b/find/testsuite/find.posix/sv-bug-11175.xo
@@ -0,0 +1 @@
+tmp/noxdir
diff --git a/find/testsuite/find.posix/sv-bug-12181.exp b/find/testsuite/find.posix/sv-bug-12181.exp
new file mode 100644
index 0000000..8f1d339
--- /dev/null
+++ b/find/testsuite/find.posix/sv-bug-12181.exp
@@ -0,0 +1,6 @@
+# tests for Savannah bug 12181 (find -H symlink should work)
+exec rm -rf tmp
+exec mkdir tmp
+exec ln -s tmp link
+find_start p { -H link}
+exec rm -rf tmp link
diff --git a/find/testsuite/find.posix/sv-bug-12181.xo b/find/testsuite/find.posix/sv-bug-12181.xo
new file mode 100644
index 0000000..2b2328d
--- /dev/null
+++ b/find/testsuite/find.posix/sv-bug-12181.xo
@@ -0,0 +1 @@
+link
diff --git a/find/testsuite/find.posix/sv-bug-15235.exp b/find/testsuite/find.posix/sv-bug-15235.exp
new file mode 100644
index 0000000..9342e49
--- /dev/null
+++ b/find/testsuite/find.posix/sv-bug-15235.exp
@@ -0,0 +1,6 @@
+# tests for directory parsing
+exec rm -rf \(1 \!2 \, \)
+exec mkdir \(1 \!2 \, \)
+touch \(1/a \!2/b \,/c \)/d
+find_start p {\(1 \!2 \, \)}
+exec rm -rf \(1 \!2 \, \)
diff --git a/find/testsuite/find.posix/sv-bug-15235.xo b/find/testsuite/find.posix/sv-bug-15235.xo
new file mode 100644
index 0000000..2852b81
--- /dev/null
+++ b/find/testsuite/find.posix/sv-bug-15235.xo
@@ -0,0 +1,8 @@
+(1
+(1/a
+!2
+!2/b
+,
+,/c
+)
+)/d
diff --git a/find/testsuite/find.posix/sv-bug-19605.exp b/find/testsuite/find.posix/sv-bug-19605.exp
new file mode 100644
index 0000000..05b8841
--- /dev/null
+++ b/find/testsuite/find.posix/sv-bug-19605.exp
@@ -0,0 +1,7 @@
+# tests for Savannah bug 19605 (Inability of ftsfind to detect symlink loop)
+exec rm -rf tmp
+exec mkdir tmp
+exec ln -s a tmp/b
+exec ln -s b tmp/a
+find_start f {-L tmp -false -print}
+exec rm -rf tmp
diff --git a/find/testsuite/find.posix/sv-bug-19613.exp b/find/testsuite/find.posix/sv-bug-19613.exp
new file mode 100644
index 0000000..44423ef
--- /dev/null
+++ b/find/testsuite/find.posix/sv-bug-19613.exp
@@ -0,0 +1,14 @@
+# tests for Savannah bug 19613 ("find -L -type f" fails on symlink loops)
+exec rm -rf tmp
+exec mkdir tmp tmp/subdir
+exec ln -s a tmp/subdir/b
+exec ln -s b tmp/subdir/a
+
+# We want to distinguish between the correct behaviour (error message
+# and return 1 because of the loop) and the failure case (assertion
+# failure in 4.3.3). To do that we just check that the "tmp/vanilla"
+# file is also found.
+
+touch tmp/vanilla
+find_start f { -L tmp -depth -type f}
+exec rm -rf tmp
diff --git a/find/testsuite/find.posix/sv-bug-19613.xo b/find/testsuite/find.posix/sv-bug-19613.xo
new file mode 100644
index 0000000..5618aba
--- /dev/null
+++ b/find/testsuite/find.posix/sv-bug-19613.xo
@@ -0,0 +1 @@
+tmp/vanilla
diff --git a/find/testsuite/find.posix/sv-bug-19617.exp b/find/testsuite/find.posix/sv-bug-19617.exp
new file mode 100644
index 0000000..fc4caca
--- /dev/null
+++ b/find/testsuite/find.posix/sv-bug-19617.exp
@@ -0,0 +1,7 @@
+# tests for Savannah bug 19617 (Inability of ftsfind to detect nonexistent command line args)
+exec rm -rf tmp
+exec mkdir tmp
+find_start f {-P tmp/nosuchfile -print}
+find_start f {-H tmp/nosuchfile -print}
+find_start f {-L tmp/nosuchfile -print}
+exec rm -rf tmp
diff --git a/find/testsuite/find.posix/sv-bug-25359.exp b/find/testsuite/find.posix/sv-bug-25359.exp
new file mode 100644
index 0000000..6bfb715
--- /dev/null
+++ b/find/testsuite/find.posix/sv-bug-25359.exp
@@ -0,0 +1,10 @@
+# Test for Savannah bug 25359
+# (ftsfind -H thinks that non-argument symlinks are files)
+# Affecting findutils
+# from acb82fe44369c108b43ec3e805aa94bf28352d0a
+# to 0b1acd3358466b02f32baf9423665113dc933492
+exec rm -rf tmp
+exec mkdir tmp
+exec ln -s / tmp/symlink
+find_start p {-H tmp -type l -print}
+exec rm -rf tmp
diff --git a/find/testsuite/find.posix/sv-bug-25359.xo b/find/testsuite/find.posix/sv-bug-25359.xo
new file mode 100644
index 0000000..8ec2030
--- /dev/null
+++ b/find/testsuite/find.posix/sv-bug-25359.xo
@@ -0,0 +1 @@
+tmp/symlink
diff --git a/find/testsuite/find.posix/sv-bug-27563-exec.exp b/find/testsuite/find.posix/sv-bug-27563-exec.exp
new file mode 100644
index 0000000..d18b0c1
--- /dev/null
+++ b/find/testsuite/find.posix/sv-bug-27563-exec.exp
@@ -0,0 +1,6 @@
+# tests for Savannah bug 27563 (result of find -L -exec ls {} \;)
+exec rm -rf tmp
+exec mkdir tmp
+exec touch tmp/yyyy
+find_start p {-L tmp -name yyyy -exec ls \{\} \; }
+exec rm -rf tmp
diff --git a/find/testsuite/find.posix/sv-bug-27563-exec.xo b/find/testsuite/find.posix/sv-bug-27563-exec.xo
new file mode 100644
index 0000000..cd491dd
--- /dev/null
+++ b/find/testsuite/find.posix/sv-bug-27563-exec.xo
@@ -0,0 +1 @@
+tmp/yyyy
diff --git a/find/testsuite/find.posix/sv-bug-30777.exp b/find/testsuite/find.posix/sv-bug-30777.exp
new file mode 100644
index 0000000..811f727
--- /dev/null
+++ b/find/testsuite/find.posix/sv-bug-30777.exp
@@ -0,0 +1,6 @@
+# tests for Savannah bug 30777 (we accept find -exec ls BLAH{} \+ but the result lacks BLAH)
+# The correct behaviour is to reject this.
+exec rm -rf tmp
+exec mkdir tmp
+find_start f {tmp -exec ls FOO{} \+ }
+exec rm -rf tmp
diff --git a/find/testsuite/find.posix/typearg.exp b/find/testsuite/find.posix/typearg.exp
new file mode 100644
index 0000000..ea6a933
--- /dev/null
+++ b/find/testsuite/find.posix/typearg.exp
@@ -0,0 +1,4 @@
+# tests for arguments to -type
+foreach type { Z ZZ } {
+ find_start f ". -type $type"
+}
diff --git a/find/testsuite/find.posix/typesize.exp b/find/testsuite/find.posix/typesize.exp
new file mode 100644
index 0000000..cf91c00
--- /dev/null
+++ b/find/testsuite/find.posix/typesize.exp
@@ -0,0 +1,6 @@
+# tests for -type -size
+exec rm -rf tmp
+exec mkdir tmp
+exec true > tmp/empty
+find_start p {tmp -type f -size 0c }
+exec rm -rf tmp
diff --git a/find/testsuite/find.posix/typesize.xo b/find/testsuite/find.posix/typesize.xo
new file mode 100644
index 0000000..445f1d4
--- /dev/null
+++ b/find/testsuite/find.posix/typesize.xo
@@ -0,0 +1 @@
+tmp/empty
diff --git a/find/testsuite/find.posix/user-empty.exp b/find/testsuite/find.posix/user-empty.exp
new file mode 100644
index 0000000..95a6772
--- /dev/null
+++ b/find/testsuite/find.posix/user-empty.exp
@@ -0,0 +1,2 @@
+# test for diagnosis of the fact that the argument to -user is empty
+find_start f { . -user "" }
diff --git a/find/testsuite/find.posix/user-missing.exp b/find/testsuite/find.posix/user-missing.exp
new file mode 100644
index 0000000..e1007fc
--- /dev/null
+++ b/find/testsuite/find.posix/user-missing.exp
@@ -0,0 +1,2 @@
+# test for diagnosis of the fact that the argument to -user is missing
+find_start f { tmp -user }
diff --git a/find/testsuite/sv-34079.sh b/find/testsuite/sv-34079.sh
new file mode 100755
index 0000000..8abbc26
--- /dev/null
+++ b/find/testsuite/sv-34079.sh
@@ -0,0 +1,78 @@
+#! /bin/sh
+# Copyright (C) 2011 Free Software Foundation, Inc.
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+
+# This test verifies that find does not have excessive memory consumption
+# even for large directories. It's not executed by default; it will only
+# run if the environment variable RUN_VERY_EXPENSIVE_TESTS is set.
+
+testname="$(basename $0)"
+
+. "${srcdir}"/binary_locations.sh
+
+make_test_data() {
+ d="$1"
+ (
+ cd "$1" && echo "Creating test data in $(pwd -P)" >&2 || exit 1
+ max=400
+ for i in $(seq 0 400)
+ do
+ printf "\r%03d/%03d" $i $max >&2
+ for j in $(seq 0 10000)
+ do
+ printf "%03d_%04d " $i $j
+ done
+ done | xargs sh -c 'touch "$@" || exit 255' fnord || exit 1
+ printf "\rTest files created.\n" >&2
+ )
+}
+
+
+if [ -n "${RUN_VERY_EXPENSIVE_TESTS}" ]; then
+ if outdir=$(mktemp -d); then
+ # Create some test files.
+ bad=""
+ printf "Generating test data in %s (this may take some time...):\n" \
+ "${outdir}" >&2
+ if make_test_data "${outdir}"; then
+ # We don't check oldfind, as it uses savedir, meaning that
+ # it stores all the directory entries. Hence the excessive
+ # memory consumption bug applies to oldfind even though it is
+ # not using fts.
+ for exe in "${ftsfind}" "${oldfind}"; do
+ echo "Checking memory consumption of ${exe}..." >&2
+ if ( ulimit -v 50000 && ${exe} "${outdir}" >/dev/null; ); then
+ echo "Memory consumption of ${exe} is reasonable" >&2
+ else
+ bad="${bad}${bad:+\n}Memory consumption of ${exe} is too high"
+ fi
+ done
+ else
+ bad="failed to set up the test in ${outdir}"
+ fi
+ rm -rf "${outdir}" || exit 1
+ if [ -n "${bad}" ]; then
+ echo "${bad}" >&2
+ exit 1
+ fi
+ else
+ echo "FAIL: could not create a test output file." >&2
+ exit 1
+ fi
+else
+ echo "${testname} was not run because" '${RUN_VERY_EXPENSIVE_TESTS}' \
+ "is unset."
+fi
diff --git a/find/testsuite/sv-34976-execdir-fd-leak.sh b/find/testsuite/sv-34976-execdir-fd-leak.sh
new file mode 100755
index 0000000..c57a04c
--- /dev/null
+++ b/find/testsuite/sv-34976-execdir-fd-leak.sh
@@ -0,0 +1,80 @@
+#! /bin/sh
+# Copyright (C) 2013 Free Software Foundation, Inc.
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+
+# This test verifies that find does not leak a file descriptor for the working
+# directory specified by the -execdir option [Savannah bug #34976].
+
+testname="$(basename $0)"
+
+. "${srcdir}"/binary_locations.sh
+
+# seq is not required by POSIX, so we have manual lists of number here instead.
+three_to_thirty_five="3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35"
+three_to_hundred="3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100"
+
+# Test if restricting the number of file descriptors via ulimit -n works.
+# We always try to open 33 files (but the ulimit -n value changes).
+test_ulimit() {
+ l="$1" # limit to use
+ (
+ ulimit -n "$l" || exit 1
+ for i in ${three_to_thirty_five} ; do
+ printf "exec %d> /dev/null || exit 1\n" $i
+ done | sh -x ;
+ ) 2>/dev/null
+}
+# Opening 33 files with a limit of 50 should work.
+test_ulimit 40 || { echo "SKIP: ulimit does not work (case 1)" >&2; exit 0 ; }
+# Opening 33 files with a limit of 20 should fail.
+test_ulimit 20 && { echo "SKIP: ulimit does not work (case 2)" >&2; exit 0 ; }
+
+die() {
+ echo "$@" >&2
+ exit 1
+}
+
+# Create test files, each 98 in the directories ".", "one" and "two".
+make_test_data() {
+ d="$1"
+ (
+ cd "$1" || exit 1
+ mkdir one two || exit 1
+ for i in ${three_to_hundred} ; do
+ printf "./%03d one/%03d two/%03d " $i $i $i
+ done \
+ | xargs touch || exit 1
+ ) \
+ || die "failed to set up the test in ${outdir}"
+}
+
+outdir="$(mktemp -d)" || die "FAIL: could not create a test files."
+
+# Create some test files.
+make_test_data "${outdir}" || die "FAIL: failed to set up the test in ${outdir}"
+
+fail=0
+for exe in "${ftsfind}" "${oldfind}"; do
+ ( ulimit -n 30 && \
+ ${exe} "${outdir}" -type f -execdir cat '{}' \; >/dev/null; ) \
+ || { \
+ echo "Option -execdir of ${exe} leaks file descriptors" >&2 ; \
+ fail=1 ; \
+ }
+done
+
+rm -rf "${outdir}" || exit 1
+exit $fail
diff --git a/find/testsuite/sv-bug-32043.sh b/find/testsuite/sv-bug-32043.sh
new file mode 100755
index 0000000..09a7d08
--- /dev/null
+++ b/find/testsuite/sv-bug-32043.sh
@@ -0,0 +1,48 @@
+#! /bin/sh
+# Copyright (C) 2011-2015 Free Software Foundation, Inc.
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+testname="$(basename $0)"
+
+parent="$(cd .. && pwd)"
+if [ -f "${parent}/ftsfind" ]; then
+ ftsfind="${parent}/ftsfind"
+ oldfind="${parent}/find"
+elif [ -f "${parent}/oldfind" ]; then
+ ftsfind="${parent}/find"
+ oldfind="${parent}/oldfind"
+else
+ echo "Cannot find the executables to test." >&2
+ exit 1
+fi
+if tstdir=$(mktemp -d); then
+ touch "$tstdir/["
+ expected="$tstdir/["
+ for executable in "$oldfind" "$ftsfind"; do
+ if result=$("$executable" "$tstdir" -name '[' -print); then
+ if ! [ "$result" = "$expected" ]; then
+ echo "FAIL: $testname with $executable returned '$result' but '$expected' was expected" >&2
+ exit 1
+ fi
+ else
+ echo "FAIL: $executable returned $?" >&2
+ exit 1
+ fi
+ done
+ rm -rf "$tstdir"
+else
+ echo "FAIL: could not create a test directory." >&2
+ exit 1
+fi
diff --git a/find/testsuite/test_escape_c.sh b/find/testsuite/test_escape_c.sh
new file mode 100755
index 0000000..9794a86
--- /dev/null
+++ b/find/testsuite/test_escape_c.sh
@@ -0,0 +1,43 @@
+#! /bin/sh
+# Copyright (C) 2011-2015 Free Software Foundation, Inc.
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+
+testname="$(basename $0)"
+
+. "${srcdir}"/binary_locations.sh
+
+goldenfile="${srcdir}/test_escapechars.golden"
+expected='hello^.^world'
+
+for executable in "$oldfind" "$ftsfind"
+do
+ if result="$($executable . -maxdepth 0 \
+ -printf 'hello^\cthere' \
+ -exec printf %s {} \; \
+ -printf '^world\n' )"; then
+ if [ "${result}" != "${expected}" ]; then
+ exec >&2
+ echo "$executable produced incorrect output:"
+ echo "${result}"
+ echo "Expected output was:"
+ echo "${expected}"
+ exit 1
+ fi
+ else
+ echo "$executable returned $?" >&2
+ exit 1
+ fi
+done
diff --git a/find/testsuite/test_escapechars.golden b/find/testsuite/test_escapechars.golden
new file mode 100644
index 0000000..c5cd8ed
--- /dev/null
+++ b/find/testsuite/test_escapechars.golden
@@ -0,0 +1,13 @@
+OCTAL1: 
+OCTAL2: 
+OCTAL3: 
+OCTAL4: 4
+OCTAL8: 8
+BEL: 
+CR:
+FF:
+TAB:
+VTAB:
+BS: 
+BACKSLASH: \
+UNKNOWN: \z
diff --git a/find/testsuite/test_escapechars.sh b/find/testsuite/test_escapechars.sh
new file mode 100755
index 0000000..2ece9c7
--- /dev/null
+++ b/find/testsuite/test_escapechars.sh
@@ -0,0 +1,59 @@
+#! /bin/sh
+# Copyright (C) 2011-2015 Free Software Foundation, Inc.
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+testname="$(basename $0)"
+
+. "${srcdir}"/binary_locations.sh
+
+goldenfile="${srcdir}/test_escapechars.golden"
+
+if outfile=$(mktemp); then
+ for executable in "$oldfind" "$ftsfind"
+ do
+ if "$executable" . -maxdepth 0 \
+ -printf 'OCTAL1: \1\n' \
+ -printf 'OCTAL2: \02\n' \
+ -printf 'OCTAL3: \003\n' \
+ -printf 'OCTAL4: \0044\n' \
+ -printf 'OCTAL8: \0028\n' \
+ -printf 'BEL: \a\n' \
+ -printf 'CR: \r\n' \
+ -printf 'FF: \f\n' \
+ -printf 'TAB: \t\n' \
+ -printf 'VTAB: \v\n' \
+ -printf 'BS: \b\n' \
+ -printf 'BACKSLASH: \\\n' \
+ -printf 'UNKNOWN: \z\n' \
+ >| "${outfile}" 2>/dev/null; then
+ if cmp "${outfile}" "${goldenfile}"; then
+ rm "${outfile}"
+ else
+ exec >&2
+ echo "FAIL: $executable produced incorrect output:"
+ od -c "${outfile}"
+ echo "Expected output was:"
+ od -c "${goldenfile}"
+ exit 1
+ fi
+ else
+ echo "FAIL: $executable returned $?" >&2
+ exit 1
+ fi
+ done
+else
+ echo "FAIL: could not create a test output file." >&2
+ exit 1
+fi
diff --git a/find/testsuite/test_inode.sh b/find/testsuite/test_inode.sh
new file mode 100755
index 0000000..9c3cb88
--- /dev/null
+++ b/find/testsuite/test_inode.sh
@@ -0,0 +1,62 @@
+#! /bin/sh
+# Copyright (C) 2011-2015 Free Software Foundation, Inc.
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+# Essentially this test verifies that ls -i and find -printf %i produce
+# the same output.
+
+testname="$(basename $0)"
+
+. "${srcdir}"/binary_locations.sh
+
+make_canonical() {
+ sed -e 's/ /_/g'
+}
+
+test_percent_i() {
+ if "${executable}" "${tmpfile}" -printf '%i_%p\n' |
+ make_canonical >| "${outfile}"; then
+ cmp "${outfile}" "${goldfile}" || {
+ exec >&2
+ cat <<EOF
+${executable} ${printf_format} produced incorrect output.
+Actual output:
+$(cat ${outfile})
+Expected output:
+$(cat ${goldfile})
+EOF
+ rm -f "${outfile}" "${goldfile}" "${tmpfile}"
+ exit 1
+ }
+ fi
+}
+
+
+
+if tmpfile=$(mktemp); then
+ if goldfile=$(mktemp); then
+ ls -i "${tmpfile}" | make_canonical >| "${goldfile}"
+
+ if outfile=$(mktemp); then
+ for executable in "${oldfind}" "${ftsfind}"
+ do
+ test_percent_i
+ done
+ rm -f "${outfile}"
+ fi
+ rm -f "${goldfile}"
+ fi
+ rm -f "${tmpfile}"
+fi
diff --git a/find/tree.c b/find/tree.c
new file mode 100644
index 0000000..026dead
--- /dev/null
+++ b/find/tree.c
@@ -0,0 +1,1747 @@
+/* tree.c -- helper functions to build and evaluate the expression tree.
+ Copyright (C) 1990, 1991, 1992, 1993, 1994, 2000, 2003, 2004, 2005,
+ 2006, 2007, 2010, 2011 Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/* config.h must always come first. */
+#include <config.h>
+
+/* system headers. */
+#include <assert.h>
+#include <stdlib.h>
+
+/* gnulib headers. */
+#include "error.h"
+#include "fnmatch.h"
+#include "gettext.h"
+#include "xalloc.h"
+
+/* find headers. */
+#include "defs.h"
+
+#if ENABLE_NLS
+# include <libintl.h>
+# define _(Text) gettext (Text)
+#else
+# define _(Text) Text
+#endif
+#ifdef gettext_noop
+# define N_(String) gettext_noop (String)
+#else
+/* See locate.c for explanation as to why not use (String) */
+# define N_(String) String
+#endif
+
+
+
+/* All predicates for each path to process. */
+static struct predicate *predicates = NULL;
+
+/* The root of the evaluation tree. */
+static struct predicate *eval_tree = NULL;
+
+/* The last predicate allocated. */
+static struct predicate *last_pred = NULL;
+
+/* The starting points. */
+static char **start_points;
+static size_t num_start_points = 0;
+
+
+
+static struct predicate *scan_rest (struct predicate **input,
+ struct predicate *head,
+ short int prev_prec);
+static void merge_pred (struct predicate *beg_list, struct predicate *end_list, struct predicate **last_p);
+static struct predicate *set_new_parent (struct predicate *curr, enum predicate_precedence high_prec, struct predicate **prevp);
+static const char *cost_name (enum EvaluationCost cost);
+
+
+/* Return true if the indicated path name is a start
+ point or not. If no start points were given on the
+ command line, we return true for ".".
+*/
+bool
+matches_start_point (const char *glob, bool foldcase)
+{
+ int fnmatch_flags = 0;
+ if (foldcase)
+ fnmatch_flags |= FNM_CASEFOLD;
+
+ if (num_start_points)
+ {
+ size_t i;
+ for (i=0; i<num_start_points; i++)
+ {
+ if (fnmatch (glob, start_points[i], fnmatch_flags) == 0)
+ return true;
+ }
+ return false;
+ }
+ else
+ {
+ return fnmatch (glob, ".", fnmatch_flags) == 0;
+ }
+}
+
+
+/* Return a pointer to a tree that represents the
+ expression prior to non-unary operator *INPUT.
+ Set *INPUT to point at the next input predicate node.
+
+ Only accepts the following:
+
+ <primary>
+ expression [operators of higher precedence]
+ <uni_op><primary>
+ (arbitrary expression)
+ <uni_op>(arbitrary expression)
+
+ In other words, you cannot start out with a bi_op or close_paren.
+
+ If the following operator (if any) is of a higher precedence than
+ PREV_PREC, the expression just nabbed is part of a following
+ expression, which really is the expression that should be handed to
+ our caller, so get_expr recurses. */
+
+static struct predicate *
+get_expr (struct predicate **input,
+ short int prev_prec,
+ const struct predicate* prev_pred)
+{
+ struct predicate *next = NULL;
+ struct predicate *this_pred = (*input);
+
+ if (*input == NULL)
+ error (EXIT_FAILURE, 0, _("invalid expression"));
+
+ switch ((*input)->p_type)
+ {
+ case NO_TYPE:
+ error (EXIT_FAILURE, 0, _("invalid expression"));
+ break;
+
+ case BI_OP:
+ /* e.g. "find . -a" */
+ error (EXIT_FAILURE, 0,
+ _("invalid expression; you have used a binary operator '%s' with nothing before it."),
+ this_pred->p_name);
+ break;
+
+ case CLOSE_PAREN:
+ if ((UNI_OP == prev_pred->p_type
+ || BI_OP == prev_pred->p_type)
+ && !this_pred->artificial)
+ {
+ /* e.g. "find \( -not \)" or "find \( -true -a \" */
+ error (EXIT_FAILURE, 0,
+ _("expected an expression between '%s' and ')'"),
+ prev_pred->p_name);
+ }
+ else if ( (*input)->artificial )
+ {
+ /* We have reached the end of the user-supplied predicates
+ * unexpectedly.
+ */
+ /* e.g. "find . -true -a" */
+ error (EXIT_FAILURE, 0,
+ _("expected an expression after '%s'"), prev_pred->p_name);
+ }
+ else
+ {
+ error (EXIT_FAILURE, 0,
+ _("invalid expression; you have too many ')'"));
+ }
+ break;
+
+ case PRIMARY_TYPE:
+ next = *input;
+ *input = (*input)->pred_next;
+ break;
+
+ case UNI_OP:
+ next = *input;
+ *input = (*input)->pred_next;
+ next->pred_right = get_expr (input, NEGATE_PREC, next);
+ break;
+
+ case OPEN_PAREN:
+ if ( (NULL == (*input)->pred_next) || (*input)->pred_next->artificial )
+ {
+ /* user typed something like "find . (", and so the ) we are
+ * looking at is from the artificial "( ) -print" that we
+ * add.
+ */
+ error (EXIT_FAILURE, 0,
+ _("invalid expression; expected to find a ')' but didn't see one. Perhaps you need an extra predicate after '%s'"),
+ this_pred->p_name);
+ }
+ prev_pred = (*input);
+ *input = (*input)->pred_next;
+ if ( (*input)->p_type == CLOSE_PAREN )
+ {
+ error (EXIT_FAILURE, 0,
+ _("invalid expression; empty parentheses are not allowed."));
+ }
+ next = get_expr (input, NO_PREC, prev_pred);
+ if ((*input == NULL)
+ || ((*input)->p_type != CLOSE_PAREN))
+ error (EXIT_FAILURE, 0,
+ _("invalid expression; I was expecting to find a ')' somewhere but did not see one."));
+
+ *input = (*input)->pred_next; /* move over close */
+ break;
+
+ default:
+ error (EXIT_FAILURE, 0, _("oops -- invalid expression type!"));
+ break;
+ }
+
+ /* We now have the first expression and are positioned to check
+ out the next operator. If NULL, all done. Otherwise, if
+ PREV_PREC < the current node precedence, we must continue;
+ the expression we just nabbed is more tightly bound to the
+ following expression than to the previous one. */
+ if (*input == NULL)
+ return (next);
+ if ((int) (*input)->p_prec > (int) prev_prec)
+ {
+ next = scan_rest (input, next, prev_prec);
+ if (next == NULL)
+ error (EXIT_FAILURE, 0, _("invalid expression"));
+ }
+ return (next);
+}
+
+/* Scan across the remainder of a predicate input list starting
+ at *INPUT, building the rest of the expression tree to return.
+ Stop at the first close parenthesis or the end of the input list.
+ Assumes that get_expr has been called to nab the first element
+ of the expression tree.
+
+ *INPUT points to the current input predicate list element.
+ It is updated as we move along the list to point to the
+ terminating input element.
+ HEAD points to the predicate element that was obtained
+ by the call to get_expr.
+ PREV_PREC is the precedence of the previous predicate element. */
+
+static struct predicate *
+scan_rest (struct predicate **input,
+ struct predicate *head,
+ short int prev_prec)
+{
+ struct predicate *tree; /* The new tree we are building. */
+
+ if ((*input == NULL) || ((*input)->p_type == CLOSE_PAREN))
+ return (NULL);
+ tree = head;
+ while ((*input != NULL) && ((int) (*input)->p_prec > (int) prev_prec))
+ {
+ switch ((*input)->p_type)
+ {
+ case NO_TYPE:
+ case PRIMARY_TYPE:
+ case UNI_OP:
+ case OPEN_PAREN:
+ /* I'm not sure how we get here, so it is not obvious what
+ * sort of mistakes might give rise to this condition.
+ */
+ error (EXIT_FAILURE, 0, _("invalid expression"));
+ break;
+
+ case BI_OP:
+ {
+ struct predicate *prev = (*input);
+ (*input)->pred_left = tree;
+ tree = *input;
+ *input = (*input)->pred_next;
+ tree->pred_right = get_expr (input, tree->p_prec, prev);
+ break;
+ }
+
+ case CLOSE_PAREN:
+ return tree;
+
+ default:
+ error (EXIT_FAILURE, 0,
+ _("oops -- invalid expression type (%d)!"),
+ (int)(*input)->p_type);
+ break;
+ }
+ }
+ return tree;
+}
+
+/* Returns true if the specified predicate is reorderable. */
+static bool
+predicate_is_cost_free (const struct predicate *p)
+{
+ if (pred_is(p, pred_name) ||
+ pred_is(p, pred_path) ||
+ pred_is(p, pred_iname) ||
+ pred_is(p, pred_ipath))
+ {
+ /* Traditionally (at least 4.1.7 through 4.2.x) GNU find always
+ * optimised these cases.
+ */
+ return true;
+ }
+ else if (options.optimisation_level > 0)
+ {
+ if (pred_is(p, pred_and) ||
+ pred_is(p, pred_negate) ||
+ pred_is(p, pred_comma) ||
+ pred_is(p, pred_or))
+ return false;
+ else
+ return NeedsNothing == p->p_cost;
+ }
+ else
+ {
+ return false;
+ }
+}
+
+/* Prints a predicate */
+void print_predicate (FILE *fp, const struct predicate *p)
+{
+ if (p->arg_text)
+ {
+ fprintf (fp, "%s %s", p->p_name, p->arg_text);
+ }
+ else
+ {
+ fprintf (fp, "%s", p->p_name);
+ }
+}
+
+
+struct predlist
+{
+ struct predicate *head;
+ struct predicate *tail;
+};
+
+static void
+predlist_init (struct predlist *p)
+{
+ p->head = p->tail = NULL;
+}
+
+static void
+predlist_insert (struct predlist *list,
+ struct predicate *curr,
+ struct predicate **pprev)
+{
+ struct predicate **insertpos = &(list->head);
+
+ *pprev = curr->pred_left;
+ curr->pred_left = (*insertpos);
+ (*insertpos) = curr;
+ if (NULL == list->tail)
+ list->tail = list->head;
+}
+
+static int
+pred_cost_compare (const struct predicate *p1, const struct predicate *p2, bool wantfailure)
+{
+ if (p1->p_cost == p2->p_cost)
+ {
+ if (p1->est_success_rate == p2->est_success_rate)
+ return 0;
+ else if (wantfailure)
+ return p1->est_success_rate < p2->est_success_rate ? -1 : 1;
+ else
+ return p1->est_success_rate < p2->est_success_rate ? 1 : -1;
+ }
+ else
+ {
+ return p1->p_cost < p2->p_cost ? -1 : 1;
+ }
+}
+
+
+static void
+predlist_merge_sort (struct predlist *list,
+ struct predicate **last)
+{
+ struct predlist new_list;
+ struct predicate *p, *q;
+
+ if (NULL == list->head)
+ return; /* nothing to do */
+
+ if (options.debug_options & DebugTreeOpt)
+ {
+ fprintf (stderr, "%s:\n", "predlist before merge sort");
+ print_tree (stderr, list->head, 2);
+ }
+
+ calculate_derived_rates (list->head);
+ predlist_init (&new_list);
+ while (list->head)
+ {
+ /* remove head of source list */
+ q = list->head;
+ list->head = list->head->pred_left;
+ q->pred_left = NULL;
+
+ /* insert it into the new list */
+ for (p=new_list.head; p; p=p->pred_left)
+ {
+ /* If these operations are OR operations, we want to get a
+ * successful test as soon as possible, to take advantage of
+ * the short-circuit evaluation. If they're AND, we want to
+ * get an unsuccessful result early for the same reason.
+ * Therefore we invert the sense of the comparison for the
+ * OR case. We only want to invert the sense of the success
+ * rate comparison, not the operation cost comparison. Hence we
+ * pass a flag into pred_cost_compare().
+ */
+ const bool wantfailure = (OR_PREC != p->p_prec);
+ if (pred_cost_compare (p->pred_right, q->pred_right, wantfailure) >= 0)
+ break;
+ }
+ if (p)
+ {
+ /* insert into existing list */
+ q->pred_left = p->pred_left;
+ if (NULL == q->pred_left)
+ new_list.tail = q;
+ p->pred_left = q;
+ }
+ else
+ {
+ q->pred_left = new_list.head; /* prepend */
+ new_list.head = q;
+ if (NULL == new_list.tail)
+ new_list.tail = q; /* first item in new list */
+ }
+ }
+ if (options.debug_options & DebugTreeOpt)
+ {
+ fprintf (stderr, "%s:\n", "predlist after merge sort");
+ print_tree (stderr, new_list.head, 2);
+ }
+
+ calculate_derived_rates(new_list.head);
+ merge_pred (new_list.head, new_list.tail, last);
+ predlist_init (list);
+}
+
+static void
+merge_lists (struct predlist lists[], int nlists,
+ struct predlist *name_list,
+ struct predlist *regex_list,
+ struct predicate **last)
+{
+ int i;
+ static void (*mergefn)(struct predlist *, struct predicate**);
+
+ mergefn = predlist_merge_sort;
+
+ mergefn (name_list, last);
+ mergefn (regex_list, last);
+
+ for (i=0; i<nlists; i++)
+ mergefn (&lists[i], last);
+}
+
+
+
+static bool
+subtree_has_side_effects (const struct predicate *p)
+{
+ if (p)
+ {
+ return p->side_effects
+ || subtree_has_side_effects (p->pred_left)
+ || subtree_has_side_effects (p->pred_right);
+ }
+ else
+ {
+
+ return false;
+ }
+}
+
+static int
+worst_cost (const struct predicate *p)
+{
+ if (p)
+ {
+ unsigned int cost_r, cost_l, worst;
+ cost_l = worst_cost (p->pred_left);
+ cost_r = worst_cost (p->pred_right);
+ worst = (cost_l > cost_r) ? cost_l : cost_r;
+ if (worst < p->p_cost)
+ worst = p->p_cost;
+ return worst;
+ }
+ else
+ {
+ return 0;
+ }
+}
+
+
+
+static void
+perform_arm_swap (struct predicate *p)
+{
+ struct predicate *tmp = p->pred_left->pred_right;
+ p->pred_left->pred_right = p->pred_right;
+ p->pred_right = tmp;
+}
+
+/* Consider swapping p->pred_left->pred_right with p->pred_right,
+ * if that yields a faster evaluation. Normally the left predicate is
+ * evaluated first.
+ *
+ * If the operation is an OR, we want the left predicate to be the one that
+ * succeeds most often. If it is an AND, we want it to be the predicate that
+ * fails most often.
+ *
+ * We don't consider swapping arms of an operator where their cost is
+ * different or where they have side effects.
+ *
+ * A viable test case for this is
+ * ./find -D opt -O3 . \! -type f -o -type d
+ * Here, the ! -type f should be evaluated first,
+ * as we assume that 95% of inodes are vanilla files.
+ */
+static bool
+consider_arm_swap (struct predicate *p)
+{
+ int left_cost, right_cost;
+ const char *reason = NULL;
+ struct predicate **pl, **pr;
+
+ if (BI_OP != p->p_type)
+ reason = "Not a binary operation";
+
+ if (!reason)
+ {
+ if (NULL == p->pred_left || NULL == p->pred_right)
+ reason = "Doesn't have two arms";
+ }
+
+
+ if (!reason)
+ {
+ if (NULL == p->pred_left->pred_right)
+ reason = "Left arm has no child on RHS";
+ }
+ pr = &p->pred_right;
+ pl = &p->pred_left->pred_right;
+
+ if (!reason)
+ {
+ if (subtree_has_side_effects (*pl))
+ reason = "Left subtree has side-effects";
+ }
+ if (!reason)
+ {
+ if (subtree_has_side_effects (*pr))
+ reason = "Right subtree has side-effects";
+ }
+
+ if (!reason)
+ {
+ left_cost = worst_cost (*pl);
+ right_cost = worst_cost (*pr);
+
+ if (left_cost < right_cost)
+ {
+ reason = "efficient as-is";
+ }
+ }
+ if (!reason)
+ {
+ bool want_swap;
+
+ if (left_cost == right_cost)
+ {
+ /* it's a candidate */
+ float succ_rate_l = (*pl)->est_success_rate;
+ float succ_rate_r = (*pr)->est_success_rate;
+
+ if (options.debug_options & DebugTreeOpt)
+ {
+ fprintf (stderr, "Success rates: l=%f, r=%f\n", succ_rate_l, succ_rate_r);
+ }
+
+ if (pred_is (p, pred_or))
+ {
+ want_swap = succ_rate_r < succ_rate_l;
+ if (!want_swap)
+ reason = "Operation is OR; right success rate >= left";
+ }
+ else if (pred_is (p, pred_and))
+ {
+ want_swap = succ_rate_r > succ_rate_l;
+ if (!want_swap)
+ reason = "Operation is AND; right success rate <= left";
+ }
+ else
+ {
+ want_swap = false;
+ reason = "Not 'AND' or 'OR'";
+ }
+ }
+ else
+ {
+ want_swap = true;
+ }
+
+ if (want_swap)
+ {
+ if (options.debug_options & DebugTreeOpt)
+ {
+ fprintf (stderr, "Performing arm swap on:\n");
+ print_tree (stderr, p, 0);
+ }
+ perform_arm_swap (p);
+ return true;
+ }
+ }
+
+
+ if (options.debug_options & DebugTreeOpt)
+ {
+ fprintf (stderr, "Not an arm swap candidate (%s):\n", reason);
+ print_tree (stderr, p, 0);
+ }
+ return false;
+}
+
+static bool
+do_arm_swaps (struct predicate *p)
+{
+ if (p)
+ {
+ bool swapped;
+ do
+ {
+ swapped = false;
+ if (consider_arm_swap (p)
+ || do_arm_swaps (p->pred_left)
+ || do_arm_swaps (p->pred_right))
+ {
+ swapped = true;
+ }
+ } while (swapped);
+ return swapped;
+ }
+ else
+ {
+ return false;
+ }
+}
+
+
+
+/* Optimize the ordering of the predicates in the tree. Rearrange
+ them to minimize work. Strategies:
+ * Evaluate predicates that don't need inode information first;
+ the predicates are divided into 1 or more groups separated by
+ predicates (if any) which have "side effects", such as printing.
+ The grouping implements the partial ordering on predicates which
+ those with side effects impose.
+
+ * Place -name, -iname, -path, -ipath, -regex and -iregex at the front
+ of a group, with -name, -iname, -path and -ipath ahead of
+ -regex and -iregex. Predicates which are moved to the front
+ of a group by definition do not have side effects. Both
+ -regex and -iregex both use pred_regex.
+
+ If higher optimisation levels have been selected, reordering also
+ occurs according to the p_cost member of each predicate (which
+ reflects the performance cost of the test). The ordering also
+ bears in mind whether these operations are more likely to succeed
+ or fail. When evauating a chain of OR conditions, we prefer
+ tests likely to succeed at the front of the list. For AND, we
+ prefer tests likely to fail at the front of the list.
+
+ This routine "normalizes" the predicate tree by ensuring that all
+ expression predicates have 'AND' (or 'OR' or 'COMMA') parent
+ nodes which are linked along the left edge of the expression
+ tree. This makes manipulation of subtrees easier.
+
+ EVAL_TREEP points to the root pointer of the predicate tree
+ to be rearranged. opt_expr may return a new root pointer there.
+ Return true if the tree contains side effects, false if not. */
+
+static bool
+opt_expr (struct predicate **eval_treep)
+{
+ struct predlist regex_list={NULL,NULL}, name_list={NULL,NULL};
+ struct predlist cbo_list[NumEvaluationCosts];
+ int i;
+ struct predicate *curr;
+ struct predicate **prevp; /* Address of `curr' node. */
+ struct predicate **last_sidep; /* Last predicate with side effects. */
+ PRED_FUNC pred_func;
+ enum predicate_type p_type;
+ bool has_side_effects = false; /* Return value. */
+ enum predicate_precedence prev_prec, /* precedence of last BI_OP in branch */
+ biop_prec; /* topmost BI_OP precedence in branch */
+
+ if (eval_treep == NULL || *eval_treep == NULL)
+ return (false);
+
+ for (i=0; i<NumEvaluationCosts; i++)
+ predlist_init (&cbo_list[i]);
+
+ /* Set up to normalize tree as a left-linked list of ANDs or ORs.
+ Set `curr' to the leftmost node, `prevp' to its address, and
+ `pred_func' to the predicate type of its parent. */
+ prevp = eval_treep;
+ prev_prec = AND_PREC;
+ curr = *prevp;
+ while (curr->pred_left != NULL)
+ {
+ prevp = &curr->pred_left;
+ prev_prec = curr->p_prec; /* must be a BI_OP */
+ curr = curr->pred_left;
+ }
+
+ /* Link in the appropriate BI_OP for the last expression, if needed. */
+ if (curr->p_type != BI_OP)
+ set_new_parent (curr, prev_prec, prevp);
+
+ if (options.debug_options & (DebugExpressionTree|DebugTreeOpt))
+ {
+ /* Normalized tree. */
+ fprintf (stderr, "Normalized Eval Tree:\n");
+ print_tree (stderr, *eval_treep, 0);
+ }
+
+ /* Rearrange the predicates. */
+ prevp = eval_treep;
+ biop_prec = NO_PREC; /* not COMMA_PREC */
+ if ((*prevp) && (*prevp)->p_type == BI_OP)
+ biop_prec = (*prevp)->p_prec;
+ while ((curr = *prevp) != NULL)
+ {
+ /* If there is a BI_OP of different precedence from the first
+ in the pred_left chain, create a new parent of the
+ original precedence, link the new parent to the left of the
+ previous and link CURR to the right of the new parent.
+ This preserves the precedence of expressions in the tree
+ in case we rearrange them. */
+ if (curr->p_type == BI_OP)
+ {
+ if (curr->p_prec != biop_prec)
+ curr = set_new_parent (curr, biop_prec, prevp);
+ }
+
+ /* See which predicate type we have. */
+ p_type = curr->pred_right->p_type;
+ pred_func = curr->pred_right->pred_func;
+
+
+ switch (p_type)
+ {
+ case NO_TYPE:
+ case PRIMARY_TYPE:
+ /* Don't rearrange the arguments of the comma operator, it is
+ not commutative. */
+ if (biop_prec == COMMA_PREC)
+ break;
+
+ /* If this predicate has no side effects, consider reordering it. */
+ if (!curr->pred_right->side_effects)
+ {
+ bool reorder;
+
+ /* If it's one of our special primaries, move it to the
+ front of the list for that primary. */
+ if (predicate_is_cost_free (curr->pred_right))
+ {
+ if (options.debug_options & DebugTreeOpt)
+ {
+ fprintf (stderr, "-O%d: promoting cheap predicate ",
+ (int)options.optimisation_level);
+ print_predicate (stderr, curr->pred_right);
+ fprintf (stderr, " into name_list\n");
+ }
+ predlist_insert (&name_list, curr, prevp);
+ continue;
+ }
+
+ if (pred_func == pred_regex)
+ {
+ predlist_insert (&regex_list, curr, prevp);
+ continue;
+ }
+
+ reorder = ((options.optimisation_level > 1)
+ && (NeedsType == curr->pred_right->p_cost
+ || NeedsInodeNumber == curr->pred_right->p_cost)
+ && !curr->pred_right->need_stat) ||
+ (options.optimisation_level > 2);
+
+ if (reorder)
+ {
+ if (options.debug_options & DebugTreeOpt)
+ {
+ fprintf (stderr, "-O%d: categorising predicate ",
+ (int)options.optimisation_level);
+ print_predicate (stderr, curr->pred_right);
+ fprintf (stderr, " by cost (%s)\n",
+ cost_name(curr->pred_right->p_cost));
+ }
+ predlist_insert (&cbo_list[curr->pred_right->p_cost], curr, prevp);
+ continue;
+ }
+ }
+
+ break;
+
+ case UNI_OP:
+ /* For NOT, check the expression trees below the NOT. */
+ curr->pred_right->side_effects
+ = opt_expr (&curr->pred_right->pred_right);
+ break;
+
+ case BI_OP:
+ /* For nested 'AND' or 'OR', recurse (AND/OR form layers on
+ the left of the tree), and continue scanning this level
+ of 'AND' or 'OR'. */
+ curr->pred_right->side_effects = opt_expr (&curr->pred_right);
+ break;
+
+ /* At this point, get_expr and scan_rest have already removed
+ all of the user's parentheses. */
+
+ default:
+ error (EXIT_FAILURE, 0, _("oops -- invalid expression type!"));
+ break;
+ }
+
+ if (curr->pred_right->side_effects == true)
+ {
+ last_sidep = prevp;
+
+ /* Incorporate lists and reset list pointers for this group. */
+ merge_lists (cbo_list, NumEvaluationCosts, &name_list, &regex_list, last_sidep);
+ has_side_effects = true;
+ }
+
+ prevp = &curr->pred_left;
+ }
+
+ /* Do final list merges. */
+ last_sidep = prevp;
+ merge_lists (cbo_list, NumEvaluationCosts, &name_list, &regex_list, last_sidep);
+ return has_side_effects;
+}
+
+static float
+constrain_rate (float rate)
+{
+ if (rate > 1.0f)
+ return 1.0;
+ else if (rate < 0.0)
+ return 0.0;
+ else
+ return rate;
+}
+
+/* Link in a new parent BI_OP node for CURR, at *PREVP, with precedence
+ HIGH_PREC. */
+
+static struct predicate *
+set_new_parent (struct predicate *curr, enum predicate_precedence high_prec, struct predicate **prevp)
+{
+ struct predicate *new_parent;
+
+ new_parent = xmalloc (sizeof (struct predicate));
+ new_parent->p_type = BI_OP;
+ new_parent->p_prec = high_prec;
+ new_parent->need_stat = false;
+ new_parent->need_type = false;
+ new_parent->need_inum = false;
+ new_parent->p_cost = NeedsNothing;
+ new_parent->arg_text = NULL;
+
+ switch (high_prec)
+ {
+ case COMMA_PREC:
+ new_parent->pred_func = pred_comma;
+ new_parent->p_name = ",";
+ new_parent->est_success_rate = 1.0;
+ break;
+ case OR_PREC:
+ new_parent->pred_func = pred_or;
+ new_parent->p_name = "-o";
+ new_parent->est_success_rate = constrain_rate (curr->est_success_rate);
+ break;
+ case AND_PREC:
+ new_parent->pred_func = pred_and;
+ new_parent->p_name = "-a";
+ new_parent->est_success_rate = constrain_rate (curr->est_success_rate);
+ break;
+ default:
+ ; /* empty */
+ }
+
+ new_parent->side_effects = false;
+ new_parent->no_default_print = false;
+ new_parent->args.str = NULL;
+ new_parent->pred_next = NULL;
+
+ /* Link in new_parent.
+ Pushes rest of left branch down 1 level to new_parent->pred_right. */
+ new_parent->pred_left = NULL;
+ new_parent->pred_right = curr;
+ *prevp = new_parent;
+
+ return new_parent;
+}
+
+/* Merge the predicate list that starts at BEG_LIST and ends at END_LIST
+ into the tree at LAST_P. */
+
+static void
+merge_pred (struct predicate *beg_list, struct predicate *end_list, struct predicate **last_p)
+{
+ end_list->pred_left = *last_p;
+ *last_p = beg_list;
+}
+
+/* Find the first node in expression tree TREE that requires
+ a stat call and mark the operator above it as needing a stat
+ before calling the node. Since the expression precedences
+ are represented in the tree, some preds that need stat may not
+ get executed (because the expression value is determined earlier.)
+ So every expression needing stat must be marked as such, not just
+ the earliest, to be sure to obtain the stat. This still guarantees
+ that a stat is made as late as possible. Return true if the top node
+ in TREE requires a stat, false if not. */
+
+
+struct pred_cost_lookup
+{
+ PRED_FUNC fn;
+ enum EvaluationCost cost;
+};
+static struct pred_cost_lookup costlookup[] =
+ {
+ { pred_amin , NeedsStatInfo },
+ { pred_and , NeedsNothing, },
+ { pred_anewer , NeedsStatInfo, },
+ { pred_atime , NeedsStatInfo, },
+ { pred_closeparen, NeedsNothing },
+ { pred_cmin , NeedsStatInfo, },
+ { pred_cnewer , NeedsStatInfo, },
+ { pred_comma , NeedsNothing, },
+ { pred_context , NeedsAccessInfo },
+ { pred_ctime , NeedsStatInfo, },
+ { pred_delete , NeedsSyncDiskHit },
+ { pred_empty , NeedsStatInfo },
+ { pred_exec , NeedsEventualExec },
+ { pred_execdir , NeedsEventualExec },
+ { pred_executable, NeedsAccessInfo },
+ { pred_false , NeedsNothing },
+ { pred_fprint , NeedsNothing },
+ { pred_fprint0 , NeedsNothing },
+ { pred_fprintf , NeedsNothing },
+ { pred_fstype , NeedsStatInfo }, /* true for amortised cost */
+ { pred_gid , NeedsStatInfo },
+ { pred_group , NeedsStatInfo },
+ { pred_ilname , NeedsLinkName },
+ { pred_iname , NeedsNothing },
+ { pred_inum , NeedsInodeNumber },
+ { pred_ipath , NeedsNothing },
+ { pred_links , NeedsStatInfo },
+ { pred_lname , NeedsLinkName },
+ { pred_ls , NeedsStatInfo },
+ { pred_fls , NeedsStatInfo },
+ { pred_mmin , NeedsStatInfo },
+ { pred_mtime , NeedsStatInfo },
+ { pred_name , NeedsNothing },
+ { pred_negate , NeedsNothing, },
+ { pred_newer , NeedsStatInfo, },
+ { pred_newerXY , NeedsStatInfo, },
+ { pred_nogroup , NeedsStatInfo }, /* true for amortised cost if caching is on */
+ { pred_nouser , NeedsStatInfo }, /* true for amortised cost if caching is on */
+ { pred_ok , NeedsUserInteraction },
+ { pred_okdir , NeedsUserInteraction },
+ { pred_openparen , NeedsNothing },
+ { pred_or , NeedsNothing, },
+ { pred_path , NeedsNothing },
+ { pred_perm , NeedsStatInfo },
+ { pred_print , NeedsNothing },
+ { pred_print0 , NeedsNothing },
+ { pred_prune , NeedsNothing },
+ { pred_quit , NeedsNothing },
+ { pred_readable , NeedsAccessInfo },
+ { pred_regex , NeedsNothing },
+ { pred_samefile , NeedsStatInfo },
+ { pred_size , NeedsStatInfo },
+ { pred_true , NeedsNothing },
+ { pred_type , NeedsType },
+ { pred_uid , NeedsStatInfo },
+ { pred_used , NeedsStatInfo },
+ { pred_user , NeedsStatInfo },
+ { pred_writable , NeedsAccessInfo },
+ { pred_xtype , NeedsType } /* roughly correct unless most files are symlinks */
+ };
+static int pred_table_sorted = 0;
+
+static bool
+check_sorted (void *base, size_t members, size_t membersize,
+ int (*cmpfn)(const void*, const void*))
+{
+ const char *p = base;
+ size_t i;
+ for (i=1u; i<members; ++i)
+ {
+ int result = cmpfn (p+i*membersize, p+(i-1)*membersize);
+ if (result < 0)
+ return false;
+ result = cmpfn (p+(i-1)*membersize, p+i*membersize);
+ assert (result <= 0);
+ }
+ return true;
+}
+
+
+static int
+cost_table_comparison (const void *p1, const void *p2)
+{
+ /* We have to compare the function pointers with memcmp(),
+ * because ISO C does not allow magnitude comparison of
+ * function pointers (just equality testing).
+ */
+ const struct pred_cost_lookup *pc1 = p1;
+ const struct pred_cost_lookup *pc2 = p2;
+ union {
+ PRED_FUNC pfn;
+ char mem[sizeof (PRED_FUNC)];
+ } u1, u2;
+
+ u1.pfn = pc1->fn;
+ u2.pfn = pc2->fn;
+ return memcmp (u1.mem, u2.mem, sizeof(u1.pfn));
+}
+
+static enum EvaluationCost
+get_pred_cost (const struct predicate *p)
+{
+ enum EvaluationCost data_requirement_cost = NeedsNothing;
+ enum EvaluationCost inherent_cost = NeedsUnknown;
+
+ if (p->need_stat)
+ {
+ data_requirement_cost = NeedsStatInfo;
+ }
+ else if (p->need_inum)
+ {
+ data_requirement_cost = NeedsInodeNumber;
+ }
+ else if (p->need_type)
+ {
+ data_requirement_cost = NeedsType;
+ }
+ else
+ {
+ data_requirement_cost = NeedsNothing;
+ }
+
+ if (pred_is (p, pred_exec) || pred_is(p, pred_execdir))
+ {
+ if (p->args.exec_vec.multiple)
+ inherent_cost = NeedsEventualExec;
+ else
+ inherent_cost = NeedsImmediateExec;
+ }
+ else if (pred_is (p, pred_fprintf))
+ {
+ /* the parser calculated the cost for us. */
+ inherent_cost = p->p_cost;
+ }
+ else
+ {
+ struct pred_cost_lookup key;
+ void *entry;
+
+ if (!pred_table_sorted)
+ {
+ qsort (costlookup,
+ sizeof(costlookup)/sizeof(costlookup[0]),
+ sizeof(costlookup[0]),
+ cost_table_comparison);
+
+ if (!check_sorted (costlookup,
+ sizeof(costlookup)/sizeof(costlookup[0]),
+ sizeof(costlookup[0]),
+ cost_table_comparison))
+ {
+ error (EXIT_FAILURE, 0,
+ "failed to sort the costlookup array");
+ }
+ pred_table_sorted = 1;
+ }
+ key.fn = p->pred_func;
+ entry = bsearch (&key, costlookup,
+ sizeof(costlookup)/sizeof(costlookup[0]),
+ sizeof(costlookup[0]),
+ cost_table_comparison);
+ if (entry)
+ {
+ inherent_cost = ((const struct pred_cost_lookup*)entry)->cost;
+ }
+ else
+ {
+ /* This message indicates a bug. If we issue the message, we
+ actually have two bugs: if find emits a diagnostic, its result
+ should be nonzero. However, not having an entry for a predicate
+ will not affect the output (just the performance) so I think it
+ would be confusing to exit with a nonzero status.
+ */
+ error (0, 0,
+ _("warning: there is no entry in the predicate evaluation "
+ "cost table for predicate %s; please report this as a bug"),
+ p->p_name);
+ inherent_cost = NeedsUnknown;
+ }
+ }
+
+ if (inherent_cost > data_requirement_cost)
+ return inherent_cost;
+ else
+ return data_requirement_cost;
+}
+
+static void
+estimate_costs (struct predicate *tree)
+{
+ if (tree)
+ {
+ estimate_costs (tree->pred_right);
+ estimate_costs (tree->pred_left);
+
+ tree->p_cost = get_pred_cost(tree);
+ }
+}
+
+struct predicate*
+get_eval_tree (void)
+{
+ return eval_tree;
+}
+
+static float
+getrate (const struct predicate *p)
+{
+ if (p)
+ return p->est_success_rate;
+ else
+ return 1.0f;
+}
+
+
+float
+calculate_derived_rates (struct predicate *p)
+{
+ assert (NULL != p);
+
+ if (p->pred_right)
+ calculate_derived_rates (p->pred_right);
+ if (p->pred_left)
+ calculate_derived_rates (p->pred_left);
+
+ assert (p->p_type != CLOSE_PAREN);
+ assert (p->p_type != OPEN_PAREN);
+
+ switch (p->p_type)
+ {
+ case NO_TYPE:
+ assert (NULL == p->pred_right);
+ assert (NULL == p->pred_left);
+ return p->est_success_rate;
+
+ case PRIMARY_TYPE:
+ assert (NULL == p->pred_right);
+ assert (NULL == p->pred_left);
+ return p->est_success_rate;
+
+ case UNI_OP:
+ /* Unary operators must have exactly one operand */
+ assert (pred_is (p, pred_negate));
+ assert (NULL == p->pred_left);
+ p->est_success_rate = (1.0 - p->pred_right->est_success_rate);
+ return p->est_success_rate;
+
+ case BI_OP:
+ {
+ float rate;
+ /* Binary operators must have two operands */
+ if (pred_is (p, pred_and))
+ {
+ rate = getrate (p->pred_right) * getrate(p->pred_left);
+ }
+ else if (pred_is (p, pred_comma))
+ {
+ rate = 1.0f;
+ }
+ else if (pred_is (p, pred_or))
+ {
+ rate = getrate (p->pred_right) + getrate(p->pred_left);
+ }
+ else
+ {
+ /* only and, or and comma are BI_OP. */
+ assert (0);
+ abort ();
+ }
+ p->est_success_rate = constrain_rate (rate);
+ }
+ return p->est_success_rate;
+
+ case OPEN_PAREN:
+ case CLOSE_PAREN:
+ p->est_success_rate = 1.0;
+ return p->est_success_rate;
+ }
+ assert (0);
+ abort ();
+}
+
+/* opt_expr() rearranges predicates such that each left subtree is
+ * rooted at a logical predicate (e.g. '-a' or '-o').
+ * check_normalization() asserts that this property still holds.
+ *
+ */
+static void
+check_normalization (struct predicate *p, bool at_root)
+{
+ if (at_root)
+ {
+ assert (BI_OP == p->p_type);
+ }
+
+ if (p->pred_left)
+ {
+ assert (BI_OP == p->pred_left->p_type);
+ check_normalization(p->pred_left, false);
+ }
+ if (p->pred_right)
+ {
+ check_normalization (p->pred_right, false);
+ }
+}
+
+struct predicate*
+build_expression_tree (int argc, char *argv[], int end_of_leading_options)
+{
+ const struct parser_table *parse_entry; /* Pointer to the parsing table entry for this expression. */
+ char *predicate_name; /* Name of predicate being parsed. */
+ struct predicate *cur_pred;
+ const struct parser_table *entry_close, *entry_print, *entry_open;
+ int i, oldi;
+
+ predicates = NULL;
+
+ /* Find where in ARGV the predicates begin by skipping the list of
+ * start points. As a side effect, also figure out which is the
+ * first and last start point.
+ */
+ start_points = argv + end_of_leading_options;
+ for (i = end_of_leading_options; i < argc && !looks_like_expression(argv[i], true); i++)
+ {
+ ++num_start_points;
+ }
+
+ /* Enclose the expression in `( ... )' so a default -print will
+ apply to the whole expression. */
+ entry_open = find_parser ("(");
+ entry_close = find_parser (")");
+ entry_print = find_parser ("print");
+ assert (entry_open != NULL);
+ assert (entry_close != NULL);
+ assert (entry_print != NULL);
+
+ parse_openparen (entry_open, argv, &argc);
+ last_pred->p_name = "(";
+ predicates->artificial = true;
+ parse_begin_user_args (argv, argc, last_pred, predicates);
+ pred_sanity_check (last_pred);
+
+ /* Build the input order list. */
+ while (i < argc )
+ {
+ state.already_issued_stat_error_msg = false;
+ if (!looks_like_expression (argv[i], false))
+ {
+ error (0, 0, _("paths must precede expression: %s"), argv[i]);
+ usage (stderr, 1, NULL);
+ }
+
+ predicate_name = argv[i];
+ parse_entry = find_parser (predicate_name);
+ if (parse_entry == NULL)
+ {
+ /* Command line option not recognized */
+ error (EXIT_FAILURE, 0, _("unknown predicate `%s'"), predicate_name);
+ }
+
+ /* We have recognised a test of the form -foo. Eat that,
+ * unless it is a predicate like -newerXY.
+ */
+ if (parse_entry->type != ARG_SPECIAL_PARSE)
+ {
+ i++;
+ }
+ oldi = i;
+ if (!(*(parse_entry->parser_func)) (parse_entry, argv, &i))
+ {
+ if (argv[i])
+ {
+ if ( (ARG_SPECIAL_PARSE == parse_entry->type) && (i == oldi) )
+ {
+ /* The special parse function spat out the
+ * predicate. It must be invalid, or not tasty.
+ */
+ error (EXIT_FAILURE, 0, _("invalid predicate `%s'"),
+ predicate_name);
+ }
+ else
+ {
+ error (EXIT_FAILURE, 0, _("invalid argument `%s' to `%s'"),
+ argv[i], predicate_name);
+ }
+ }
+ else
+ {
+ /* Command line option requires an argument */
+ error (EXIT_FAILURE, 0,
+ _("missing argument to `%s'"), predicate_name);
+ }
+ }
+ else
+ {
+ last_pred->p_name = predicate_name;
+
+ /* If the parser consumed an argument, save it. */
+ if (i != oldi)
+ last_pred->arg_text = argv[oldi];
+ else
+ last_pred->arg_text = NULL;
+ }
+ pred_sanity_check(last_pred);
+ pred_sanity_check(predicates); /* XXX: expensive */
+ }
+ parse_end_user_args (argv, argc, last_pred, predicates);
+ if (predicates->pred_next == NULL)
+ {
+ /* No predicates that do something other than set a global variable
+ were given; remove the unneeded initial `(' and add `-print'. */
+ cur_pred = predicates;
+ predicates = last_pred = predicates->pred_next;
+ free (cur_pred);
+ parse_print (entry_print, argv, &argc);
+ last_pred->p_name = "-print";
+ pred_sanity_check(last_pred);
+ pred_sanity_check(predicates); /* XXX: expensive */
+ }
+ else if (!default_prints (predicates->pred_next))
+ {
+ /* One or more predicates that produce output were given;
+ remove the unneeded initial `('. */
+ cur_pred = predicates;
+ predicates = predicates->pred_next;
+ pred_sanity_check (predicates); /* XXX: expensive */
+ free (cur_pred);
+ }
+ else
+ {
+ /* `( user-supplied-expression ) -print'. */
+ parse_closeparen (entry_close, argv, &argc);
+ last_pred->p_name = ")";
+ last_pred->artificial = true;
+ pred_sanity_check (last_pred);
+ parse_print (entry_print, argv, &argc);
+ last_pred->p_name = "-print";
+ last_pred->artificial = true;
+ pred_sanity_check (last_pred);
+ pred_sanity_check (predicates); /* XXX: expensive */
+ }
+
+ if (options.debug_options & (DebugExpressionTree|DebugTreeOpt))
+ {
+ fprintf (stderr, "Predicate List:\n");
+ print_list (stderr, predicates);
+ }
+
+ /* do a sanity check */
+ check_option_combinations (predicates);
+ pred_sanity_check (predicates);
+
+ /* Done parsing the predicates. Build the evaluation tree. */
+ cur_pred = predicates;
+ eval_tree = get_expr (&cur_pred, NO_PREC, NULL);
+ calculate_derived_rates (eval_tree);
+
+ /* Check if we have any left-over predicates (this fixes
+ * Debian bug #185202).
+ */
+ if (cur_pred != NULL)
+ {
+ /* cur_pred->p_name is often NULL here */
+ if (pred_is (cur_pred, pred_closeparen))
+ {
+ /* e.g. "find \( -true \) \)" */
+ error (EXIT_FAILURE, 0, _("you have too many ')'"));
+ }
+ else
+ {
+ if (cur_pred->p_name)
+ error (EXIT_FAILURE, 0,
+ _("unexpected extra predicate '%s'"), cur_pred->p_name);
+ else
+ error (EXIT_FAILURE, 0, _("unexpected extra predicate"));
+ }
+ }
+
+ if (options.debug_options & (DebugExpressionTree|DebugTreeOpt))
+ {
+ fprintf (stderr, "Eval Tree:\n");
+ print_tree (stderr, eval_tree, 0);
+ }
+
+ estimate_costs (eval_tree);
+
+ /* Rearrange the eval tree in optimal-predicate order. */
+ opt_expr (&eval_tree);
+
+ /* Check that the tree is in normalised order (opt_expr does this) */
+ check_normalization (eval_tree, true);
+
+ do_arm_swaps (eval_tree);
+
+ /* Check that the tree is still in normalised order */
+ check_normalization (eval_tree, true);
+
+ if (options.debug_options & (DebugExpressionTree|DebugTreeOpt))
+ {
+ fprintf (stderr, "Optimized Eval Tree:\n");
+ print_tree (stderr, eval_tree, 0);
+ fprintf (stderr, "Optimized command line:\n");
+ print_optlist (stderr, eval_tree);
+ fprintf (stderr, "\n");
+ }
+
+ return eval_tree;
+}
+
+/* Initialize the performance data for a predicate.
+ */
+static void
+init_pred_perf (struct predicate *pred)
+{
+ struct predicate_performance_info *p = &pred->perf;
+ p->visits = p->successes = 0;
+}
+
+
+struct predicate *
+get_new_pred_noarg (const struct parser_table *entry)
+{
+ struct predicate *p = get_new_pred (entry);
+ if (p)
+ {
+ p->arg_text = NULL;
+ }
+ return p;
+}
+
+
+/* Return a pointer to a new predicate structure, which has been
+ linked in as the last one in the predicates list.
+
+ Set `predicates' to point to the start of the predicates list.
+ Set `last_pred' to point to the new last predicate in the list.
+
+ Set all cells in the new structure to the default values. */
+
+struct predicate *
+get_new_pred (const struct parser_table *entry)
+{
+ register struct predicate *new_pred;
+ (void) entry;
+
+ /* Options should not be turned into predicates. */
+ assert (entry->type != ARG_OPTION);
+ assert (entry->type != ARG_POSITIONAL_OPTION);
+
+ if (predicates == NULL)
+ {
+ predicates = (struct predicate *)
+ xmalloc (sizeof (struct predicate));
+ last_pred = predicates;
+ }
+ else
+ {
+ new_pred = xmalloc (sizeof (struct predicate));
+ last_pred->pred_next = new_pred;
+ last_pred = new_pred;
+ }
+ last_pred->parser_entry = entry;
+ last_pred->pred_func = NULL;
+ last_pred->p_name = NULL;
+ last_pred->p_type = NO_TYPE;
+ last_pred->p_prec = NO_PREC;
+ last_pred->side_effects = false;
+ last_pred->no_default_print = false;
+ last_pred->need_stat = true;
+ last_pred->need_type = true;
+ last_pred->need_inum = false;
+ last_pred->p_cost = NeedsUnknown;
+ last_pred->arg_text = "ThisShouldBeSetToSomethingElse";
+ last_pred->args.str = NULL;
+ last_pred->args.scontext = NULL;
+ last_pred->pred_next = NULL;
+ last_pred->pred_left = NULL;
+ last_pred->pred_right = NULL;
+ last_pred->literal_control_chars = options.literal_control_chars;
+ last_pred->artificial = false;
+ last_pred->est_success_rate = 1.0;
+ init_pred_perf (last_pred);
+ return last_pred;
+}
+
+/* Return a pointer to a new predicate, with operator check.
+ Like get_new_pred, but it checks to make sure that the previous
+ predicate is an operator. If it isn't, the AND operator is inserted. */
+
+struct predicate *
+get_new_pred_chk_op (const struct parser_table *entry,
+ const char *arg)
+{
+ struct predicate *new_pred;
+ static const struct parser_table *entry_and = NULL;
+
+ /* Locate the entry in the parser table for the "and" operator */
+ if (NULL == entry_and)
+ entry_and = find_parser ("and");
+
+ /* Check that it's actually there. If not, that is a bug.*/
+ assert (entry_and != NULL);
+
+ if (last_pred)
+ switch (last_pred->p_type)
+ {
+ case NO_TYPE:
+ error (EXIT_FAILURE, 0, _("oops -- invalid default insertion of and!"));
+ break;
+
+ case PRIMARY_TYPE:
+ case CLOSE_PAREN:
+ /* We need to interpose the and operator. */
+ new_pred = get_new_pred_noarg (entry_and);
+ new_pred->pred_func = pred_and;
+ new_pred->p_name = "-a";
+ new_pred->p_type = BI_OP;
+ new_pred->p_prec = AND_PREC;
+ new_pred->need_stat = false;
+ new_pred->need_type = false;
+ new_pred->need_inum = false;
+ new_pred->arg_text = NULL;
+ new_pred->args.str = NULL;
+ new_pred->side_effects = false;
+ new_pred->no_default_print = false;
+ break;
+
+ default:
+ break;
+ }
+
+ new_pred = get_new_pred (entry);
+ new_pred->arg_text = arg;
+ new_pred->parser_entry = entry;
+ return new_pred;
+}
+
+struct cost_assoc
+{
+ enum EvaluationCost cost;
+ const char *name;
+};
+struct cost_assoc cost_table[] =
+ {
+ { NeedsNothing, "Nothing" },
+ { NeedsInodeNumber, "InodeNumber" },
+ { NeedsType, "Type" },
+ { NeedsStatInfo, "StatInfo" },
+ { NeedsLinkName, "LinkName" },
+ { NeedsAccessInfo, "AccessInfo" },
+ { NeedsSyncDiskHit, "SyncDiskHit" },
+ { NeedsEventualExec, "EventualExec" },
+ { NeedsImmediateExec, "ImmediateExec" },
+ { NeedsUserInteraction, "UserInteraction" },
+ { NeedsUnknown, "Unknown" }
+ };
+
+struct prec_assoc
+{
+ short prec;
+ const char *prec_name;
+};
+
+static struct prec_assoc prec_table[] =
+{
+ {NO_PREC, "no"},
+ {COMMA_PREC, "comma"},
+ {OR_PREC, "or"},
+ {AND_PREC, "and"},
+ {NEGATE_PREC, "negate"},
+ {MAX_PREC, "max"},
+ {-1, "unknown "}
+};
+
+struct op_assoc
+{
+ short type;
+ const char *type_name;
+};
+
+static struct op_assoc type_table[] =
+{
+ {NO_TYPE, "no"},
+ {PRIMARY_TYPE, "primary"},
+ {UNI_OP, "uni_op"},
+ {BI_OP, "bi_op"},
+ {OPEN_PAREN, "open_paren "},
+ {CLOSE_PAREN, "close_paren "},
+ {-1, "unknown"}
+};
+
+static const char *
+cost_name (enum EvaluationCost cost)
+{
+ unsigned int i;
+ unsigned int n = sizeof (cost_table)/sizeof(cost_table[0]);
+
+ for (i = 0; i<n; ++i)
+ if (cost_table[i].cost == cost)
+ return cost_table[i].name;
+ return "unknown";
+}
+
+
+static const char *
+type_name (short type)
+{
+ int i;
+
+ for (i = 0; type_table[i].type != (short) -1; i++)
+ if (type_table[i].type == type)
+ break;
+ return type_table[i].type_name;
+}
+
+static const char *
+prec_name (short prec)
+{
+ int i;
+
+ for (i = 0; prec_table[i].prec != (short) -1; i++)
+ if (prec_table[i].prec == prec)
+ break;
+ return prec_table[i].prec_name;
+}
+
+
+/* Walk the expression tree NODE to stdout.
+ INDENT is the number of levels to indent the left margin. */
+
+void
+print_tree (FILE *fp, struct predicate *node, int indent)
+{
+ int i;
+
+ if (node == NULL)
+ return;
+ for (i = 0; i < indent; i++)
+ fprintf (fp, " ");
+ fprintf (fp, "pred=[");
+ print_predicate (fp, node);
+ fprintf (fp, "] type=%s prec=%s",
+ type_name (node->p_type), prec_name (node->p_prec));
+ fprintf (fp, " cost=%s rate=%#03.2g %sside effects ",
+ cost_name (node->p_cost),
+ node->est_success_rate,
+ (node->side_effects ? "" : "no "));
+
+ if (node->need_stat || node->need_type || node->need_inum)
+ {
+ int comma = 0;
+
+ fprintf (fp, "Needs ");
+ if (node->need_stat)
+ {
+ fprintf (fp, "stat");
+ comma = 1;
+ }
+ if (node->need_inum)
+ {
+ fprintf (fp, "%sinode", comma ? "," : "");
+ comma = 1;
+ }
+ if (node->need_type)
+ {
+ fprintf (fp, "%stype", comma ? "," : "");
+ }
+ }
+ fprintf (fp, "\n");
+
+
+ for (i = 0; i < indent; i++)
+ fprintf (fp, " ");
+ if (NULL == node->pred_left && NULL == node->pred_right)
+ {
+ fprintf (fp, "no children.\n");
+ }
+ else
+ {
+ if (node->pred_left)
+ {
+ fprintf (fp, "left:\n");
+ print_tree (fp, node->pred_left, indent + 1);
+ }
+ else
+ {
+ fprintf (fp, "no left.\n");
+ }
+
+ for (i = 0; i < indent; i++)
+ fprintf (fp, " ");
+ if (node->pred_right)
+ {
+ fprintf (fp, "right:\n");
+ print_tree (fp, node->pred_right, indent + 1);
+ }
+ else
+ {
+ fprintf (fp, "no right.\n");
+ }
+ }
+}
diff --git a/find/util.c b/find/util.c
new file mode 100644
index 0000000..5ffe140
--- /dev/null
+++ b/find/util.c
@@ -0,0 +1,1173 @@
+/* util.c -- functions for initializing new tree elements, and other things.
+ Copyright (C) 1990, 1991, 1992, 1993, 1994, 2000, 2003, 2004, 2005,
+ 2008, 2009, 2010, 2011 Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/* config.h must always come first. */
+#include <config.h>
+
+/* system headers. */
+#include <assert.h>
+#include <ctype.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <limits.h>
+#include <string.h>
+#include <sys/stat.h> /* for fstatat() */
+#include <sys/time.h>
+#include <sys/utsname.h>
+
+/* gnulib headers. */
+#include "error.h"
+#include "fdleak.h"
+#include "gettext.h"
+#include "progname.h"
+#include "quotearg.h"
+#include "save-cwd.h"
+#include "timespec.h"
+#include "xalloc.h"
+
+/* find headers. */
+#include "defs.h"
+#include "dircallback.h"
+
+
+#if ENABLE_NLS
+# include <libintl.h>
+# define _(Text) gettext (Text)
+#else
+# define _(Text) Text
+#endif
+#ifdef gettext_noop
+# define N_(String) gettext_noop (String)
+#else
+/* See locate.c for explanation as to why not use (String) */
+# define N_(String) String
+#endif
+
+
+struct debug_option_assoc
+{
+ char *name;
+ int val;
+ char *docstring;
+};
+static struct debug_option_assoc debugassoc[] =
+ {
+ { "help", DebugHelp, "Explain the various -D options" },
+ { "tree", DebugExpressionTree, "Display the expression tree" },
+ { "search",DebugSearch, "Navigate the directory tree verbosely" },
+ { "stat", DebugStat, "Trace calls to stat(2) and lstat(2)" },
+ { "rates", DebugSuccessRates, "Indicate how often each predicate succeeded" },
+ { "opt", DebugExpressionTree|DebugTreeOpt, "Show diagnostic information relating to optimisation" },
+ { "exec", DebugExec, "Show diagnostic information relating to -exec, -execdir, -ok and -okdir" }
+ };
+#define N_DEBUGASSOC (sizeof(debugassoc)/sizeof(debugassoc[0]))
+
+
+
+
+/* Add a primary of predicate type PRED_FUNC (described by ENTRY) to the predicate input list.
+
+ Return a pointer to the predicate node just inserted.
+
+ Fills in the following cells of the new predicate node:
+
+ pred_func PRED_FUNC
+ args(.str) NULL
+ p_type PRIMARY_TYPE
+ p_prec NO_PREC
+
+ Other cells that need to be filled in are defaulted by
+ get_new_pred_chk_op, which is used to insure that the prior node is
+ either not there at all (we are the very first node) or is an
+ operator. */
+
+struct predicate *
+insert_primary_withpred (const struct parser_table *entry,
+ PRED_FUNC pred_func,
+ const char *arg)
+{
+ struct predicate *new_pred;
+
+ new_pred = get_new_pred_chk_op (entry, arg);
+ new_pred->pred_func = pred_func;
+ new_pred->p_name = entry->parser_name;
+ new_pred->args.str = NULL;
+ new_pred->p_type = PRIMARY_TYPE;
+ new_pred->p_prec = NO_PREC;
+ return new_pred;
+}
+
+/* Add a primary described by ENTRY to the predicate input list.
+
+ Return a pointer to the predicate node just inserted.
+
+ Fills in the following cells of the new predicate node:
+
+ pred_func PRED_FUNC
+ args(.str) NULL
+ p_type PRIMARY_TYPE
+ p_prec NO_PREC
+
+ Other cells that need to be filled in are defaulted by
+ get_new_pred_chk_op, which is used to insure that the prior node is
+ either not there at all (we are the very first node) or is an
+ operator. */
+struct predicate *
+insert_primary (const struct parser_table *entry, const char *arg)
+{
+ assert (entry->pred_func != NULL);
+ return insert_primary_withpred (entry, entry->pred_func, arg);
+}
+
+struct predicate *
+insert_primary_noarg (const struct parser_table *entry)
+{
+ return insert_primary (entry, NULL);
+}
+
+
+
+static void
+show_valid_debug_options (FILE *fp, int full)
+{
+ size_t i;
+ if (full)
+ {
+ fprintf (fp, "Valid arguments for -D:\n");
+ for (i=0; i<N_DEBUGASSOC; ++i)
+ {
+ fprintf (fp, "%-10s %s\n",
+ debugassoc[i].name,
+ debugassoc[i].docstring);
+ }
+ }
+ else
+ {
+ for (i=0; i<N_DEBUGASSOC; ++i)
+ {
+ fprintf (fp, "%s%s", (i>0 ? "|" : ""), debugassoc[i].name);
+ }
+ }
+}
+
+void
+usage (FILE *fp, int status, char *msg)
+{
+ if (msg)
+ fprintf (fp, "%s: %s\n", program_name, msg);
+
+ fprintf (fp, _("Usage: %s [-H] [-L] [-P] [-Olevel] [-D "), program_name);
+ show_valid_debug_options (fp, 0);
+ fprintf (fp, _("] [path...] [expression]\n"));
+ if (0 != status)
+ exit (status);
+}
+
+void
+set_stat_placeholders (struct stat *p)
+{
+#if HAVE_STRUCT_STAT_ST_BIRTHTIME
+ p->st_birthtime = 0;
+#endif
+#if HAVE_STRUCT_STAT_ST_BIRTHTIMENSEC
+ p->st_birthtimensec = 0;
+#endif
+#if HAVE_STRUCT_STAT_ST_BIRTHTIMESPEC_TV_NSEC
+ p->st_birthtimespec.tv_nsec = -1;
+#endif
+#if HAVE_STRUCT_STAT_ST_BIRTHTIMESPEC_TV_SEC
+ p->st_birthtimespec.tv_sec = 0;
+#else
+ /* Avoid pointless compiler warning about unused parameters if none of these
+ macros are set to nonzero values. */
+ (void) p;
+#endif
+}
+
+
+/* Get the stat information for a file, if it is
+ * not already known. Returns 0 on success.
+ */
+int
+get_statinfo (const char *pathname, const char *name, struct stat *p)
+{
+ /* Set markers in fields so we have a good idea if the implementation
+ * didn't bother to set them (e.g., NetBSD st_birthtimespec for MS-DOS
+ * files)
+ */
+ if (!state.have_stat)
+ {
+ set_stat_placeholders (p);
+ if (0 == (*options.xstat) (name, p))
+ {
+ if (00000 == p->st_mode)
+ {
+ /* Savannah bug #16378. */
+ error (0, 0, _("WARNING: file %s appears to have mode 0000"),
+ quotearg_n_style (0, options.err_quoting_style, name));
+ error_severity (1);
+ }
+ }
+ else
+ {
+ if (!options.ignore_readdir_race || (errno != ENOENT) )
+ {
+ nonfatal_target_file_error (errno, pathname);
+ }
+ return -1;
+ }
+ }
+ state.have_stat = true;
+ state.have_type = true;
+ state.type = p->st_mode;
+
+ return 0;
+}
+
+/* Get the stat/type/inode information for a file, if it is not
+ * already known. Returns 0 on success (or if we did nothing).
+ */
+int
+get_info (const char *pathname,
+ struct stat *p,
+ struct predicate *pred_ptr)
+{
+ bool todo = false;
+
+ /* If we need the full stat info, or we need the type info but don't
+ * already have it, stat the file now.
+ */
+ if (pred_ptr->need_stat)
+ {
+ todo = true; /* need full stat info */
+ }
+ else if (pred_ptr->need_type && !state.have_type)
+ {
+ todo = true; /* need to stat to get the type */
+ }
+ else if (pred_ptr->need_inum)
+ {
+ if (!p->st_ino)
+ {
+ todo = true; /* need to stat to get the inode number */
+ }
+ else if ((!state.have_type) || S_ISDIR(p->st_mode))
+ {
+ /* For now we decide not to trust struct dirent.d_ino for
+ * directory entries that are subdirectories, in case this
+ * subdirectory is a mount point. We also need to call a
+ * stat function if we don't have st_ino (i.e. it is zero).
+ */
+ todo = true;
+ }
+ }
+ if (todo)
+ {
+ int result = get_statinfo (pathname, state.rel_pathname, p);
+ if (result != 0)
+ {
+ return -1; /* failure. */
+ }
+ else
+ {
+ /* Verify some postconditions. We can't check st_mode for
+ non-zero-ness because of Savannah bug #16378 (which is
+ that broken NFS servers can return st_mode==0). */
+ if (pred_ptr->need_type)
+ {
+ assert (state.have_type);
+ }
+ if (pred_ptr->need_inum)
+ {
+ assert (p->st_ino);
+ }
+ return 0; /* success. */
+ }
+ }
+ else
+ {
+ return 0; /* success; nothing to do. */
+ }
+}
+
+/* Determine if we can use O_NOFOLLOW.
+ */
+#if defined O_NOFOLLOW
+bool
+check_nofollow (void)
+{
+ struct utsname uts;
+ float release;
+
+ if (0 == O_NOFOLLOW)
+ {
+ return false;
+ }
+
+ if (0 == uname (&uts))
+ {
+ /* POSIX requires that atof ignores "unrecognised suffixes"; we specifically
+ * want that behaviour. */
+ double (*conversion)(const char*) = atof; /* avoid sc_prohibit_atoi_atof check. */
+ release = conversion (uts.release);
+
+ if (0 == strcmp ("Linux", uts.sysname))
+ {
+ /* Linux kernels 2.1.126 and earlier ignore the O_NOFOLLOW flag. */
+ return release >= 2.2; /* close enough */
+ }
+ else if (0 == strcmp ("FreeBSD", uts.sysname))
+ {
+ /* FreeBSD 3.0-CURRENT and later support it */
+ return release >= 3.1;
+ }
+ }
+
+ /* Well, O_NOFOLLOW was defined, so we'll try to use it. */
+ return true;
+}
+#endif
+
+
+static int
+exec_cb (void *context)
+{
+ struct exec_val *execp = context;
+ bc_do_exec (&execp->ctl, &execp->state);
+ return 0;
+}
+
+static void
+do_exec (struct exec_val *execp)
+{
+ run_in_dir (execp->wd_for_exec, exec_cb, execp);
+ if (execp->wd_for_exec != initial_wd)
+ {
+ free_cwd (execp->wd_for_exec);
+ free (execp->wd_for_exec);
+ execp->wd_for_exec = NULL;
+ }
+}
+
+
+/* Examine the predicate list for instances of -execdir or -okdir
+ * which have been terminated with '+' (build argument list) rather
+ * than ';' (singles only). If there are any, run them (this will
+ * have no effect if there are no arguments waiting).
+ */
+static void
+do_complete_pending_execdirs (struct predicate *p)
+{
+ if (NULL == p)
+ return;
+
+ assert (state.execdirs_outstanding);
+
+ do_complete_pending_execdirs (p->pred_left);
+
+ if (pred_is (p, pred_execdir) || pred_is(p, pred_okdir))
+ {
+ /* It's an exec-family predicate. p->args.exec_val is valid. */
+ if (p->args.exec_vec.multiple)
+ {
+ struct exec_val *execp = &p->args.exec_vec;
+
+ /* This one was terminated by '+' and so might have some
+ * left... Run it if necessary.
+ */
+ if (execp->state.todo)
+ {
+ /* There are not-yet-executed arguments. */
+ do_exec (execp);
+ }
+ }
+ }
+
+ do_complete_pending_execdirs (p->pred_right);
+}
+
+void
+complete_pending_execdirs (void)
+{
+ if (state.execdirs_outstanding)
+ {
+ do_complete_pending_execdirs (get_eval_tree());
+ state.execdirs_outstanding = false;
+ }
+}
+
+
+
+/* Examine the predicate list for instances of -exec which have been
+ * terminated with '+' (build argument list) rather than ';' (singles
+ * only). If there are any, run them (this will have no effect if
+ * there are no arguments waiting).
+ */
+void
+complete_pending_execs (struct predicate *p)
+{
+ if (NULL == p)
+ return;
+
+ complete_pending_execs (p->pred_left);
+
+ /* It's an exec-family predicate then p->args.exec_val is valid
+ * and we can check it.
+ */
+ /* XXX: what about pred_ok() ? */
+ if (pred_is (p, pred_exec) && p->args.exec_vec.multiple)
+ {
+ struct exec_val *execp = &p->args.exec_vec;
+
+ /* This one was terminated by '+' and so might have some
+ * left... Run it if necessary. Set state.exit_status if
+ * there are any problems.
+ */
+ if (execp->state.todo)
+ {
+ /* There are not-yet-executed arguments. */
+ bc_do_exec (&execp->ctl, &execp->state);
+ }
+ }
+
+ complete_pending_execs (p->pred_right);
+}
+
+void
+record_initial_cwd (void)
+{
+ initial_wd = xmalloc (sizeof (*initial_wd));
+ if (0 != save_cwd (initial_wd))
+ {
+ error (EXIT_FAILURE, errno,
+ _("Failed to save initial working directory%s%s"),
+ (initial_wd->desc < 0 && initial_wd->name) ? ": " : "",
+ (initial_wd->desc < 0 && initial_wd->name) ? initial_wd->name : "");
+ }
+}
+
+static void
+cleanup_initial_cwd (void)
+{
+ if (0 == restore_cwd (initial_wd))
+ {
+ free_cwd (initial_wd);
+ free (initial_wd);
+ initial_wd = NULL;
+ }
+ else
+ {
+ /* since we may already be in atexit, die with _exit(). */
+ error (0, errno,
+ _("Failed to restore initial working directory%s%s"),
+ (initial_wd->desc < 0 && initial_wd->name) ? ": " : "",
+ (initial_wd->desc < 0 && initial_wd->name) ? initial_wd->name : "");
+ _exit (EXIT_FAILURE);
+ }
+}
+
+
+static void
+traverse_tree (struct predicate *tree,
+ void (*callback)(struct predicate*))
+{
+ if (tree->pred_left)
+ traverse_tree (tree->pred_left, callback);
+
+ callback (tree);
+
+ if (tree->pred_right)
+ traverse_tree (tree->pred_right, callback);
+}
+
+/* After sharefile_destroy is called, our output file
+ * pointers will be dangling (fclose will already have
+ * been called on them). NULL these out.
+ */
+static void
+undangle_file_pointers (struct predicate *p)
+{
+ if (pred_is (p, pred_fprint)
+ || pred_is (p, pred_fprintf)
+ || pred_is (p, pred_fls)
+ || pred_is (p, pred_fprint0))
+ {
+ /* The file was already fclose()d by sharefile_destroy. */
+ p->args.printf_vec.stream = NULL;
+ }
+}
+
+/* Return nonzero if file descriptor leak-checking is enabled.
+ */
+bool
+fd_leak_check_is_enabled (void)
+{
+ if (getenv ("GNU_FINDUTILS_FD_LEAK_CHECK"))
+ return true;
+ else
+ return false;
+
+}
+
+/* Complete any outstanding commands.
+ * Flush and close any open files.
+ */
+void
+cleanup (void)
+{
+ struct predicate *eval_tree = get_eval_tree ();
+ if (eval_tree)
+ {
+ traverse_tree (eval_tree, complete_pending_execs);
+ complete_pending_execdirs ();
+ }
+
+ /* Close ouptut files and NULL out references to them. */
+ sharefile_destroy (state.shared_files);
+ if (eval_tree)
+ traverse_tree (eval_tree, undangle_file_pointers);
+
+ cleanup_initial_cwd ();
+
+ if (fd_leak_check_is_enabled ())
+ {
+ complain_about_leaky_fds ();
+ forget_non_cloexec_fds ();
+ }
+
+ if (fflush (stdout) == EOF)
+ nonfatal_nontarget_file_error (errno, "standard output");
+}
+
+
+static int
+fallback_stat (const char *name, struct stat *p, int prev_rv)
+{
+ /* Our original stat() call failed. Perhaps we can't follow a
+ * symbolic link. If that might be the problem, lstat() the link.
+ * Otherwise, admit defeat.
+ */
+ switch (errno)
+ {
+ case ENOENT:
+ case ENOTDIR:
+ if (options.debug_options & DebugStat)
+ fprintf(stderr, "fallback_stat(): stat(%s) failed; falling back on lstat()\n", name);
+ return fstatat(state.cwd_dir_fd, name, p, AT_SYMLINK_NOFOLLOW);
+
+ case EACCES:
+ case EIO:
+ case ELOOP:
+ case ENAMETOOLONG:
+#ifdef EOVERFLOW
+ case EOVERFLOW: /* EOVERFLOW is not #defined on UNICOS. */
+#endif
+ default:
+ return prev_rv;
+ }
+}
+
+
+/* optionh_stat() implements the stat operation when the -H option is
+ * in effect.
+ *
+ * If the item to be examined is a command-line argument, we follow
+ * symbolic links. If the stat() call fails on the command-line item,
+ * we fall back on the properties of the symbolic link.
+ *
+ * If the item to be examined is not a command-line argument, we
+ * examine the link itself.
+ */
+int
+optionh_stat (const char *name, struct stat *p)
+{
+ if (AT_FDCWD != state.cwd_dir_fd)
+ assert (state.cwd_dir_fd >= 0);
+ set_stat_placeholders (p);
+ if (0 == state.curdepth)
+ {
+ /* This file is from the command line; deference the link (if it
+ * is a link).
+ */
+ int rv;
+ rv = fstatat (state.cwd_dir_fd, name, p, 0);
+ if (0 == rv)
+ return 0; /* success */
+ else
+ return fallback_stat (name, p, rv);
+ }
+ else
+ {
+ /* Not a file on the command line; do not dereference the link.
+ */
+ return fstatat (state.cwd_dir_fd, name, p, AT_SYMLINK_NOFOLLOW);
+ }
+}
+
+/* optionl_stat() implements the stat operation when the -L option is
+ * in effect. That option makes us examine the thing the symbolic
+ * link points to, not the symbolic link itself.
+ */
+int
+optionl_stat(const char *name, struct stat *p)
+{
+ int rv;
+ if (AT_FDCWD != state.cwd_dir_fd)
+ assert (state.cwd_dir_fd >= 0);
+
+ set_stat_placeholders (p);
+ rv = fstatat (state.cwd_dir_fd, name, p, 0);
+ if (0 == rv)
+ return 0; /* normal case. */
+ else
+ return fallback_stat (name, p, rv);
+}
+
+/* optionp_stat() implements the stat operation when the -P option is
+ * in effect (this is also the default). That option makes us examine
+ * the symbolic link itself, not the thing it points to.
+ */
+int
+optionp_stat (const char *name, struct stat *p)
+{
+ assert ((state.cwd_dir_fd >= 0) || (state.cwd_dir_fd==AT_FDCWD));
+ set_stat_placeholders (p);
+ return fstatat (state.cwd_dir_fd, name, p, AT_SYMLINK_NOFOLLOW);
+}
+
+
+static uintmax_t stat_count = 0u;
+
+int
+debug_stat (const char *file, struct stat *bufp)
+{
+ ++stat_count;
+ fprintf (stderr, "debug_stat (%s)\n", file);
+
+ switch (options.symlink_handling)
+ {
+ case SYMLINK_ALWAYS_DEREF:
+ return optionl_stat (file, bufp);
+ case SYMLINK_DEREF_ARGSONLY:
+ return optionh_stat (file, bufp);
+ case SYMLINK_NEVER_DEREF:
+ return optionp_stat (file, bufp);
+ }
+ /*NOTREACHED*/
+ assert (0);
+ return -1;
+}
+
+
+bool
+following_links(void)
+{
+ switch (options.symlink_handling)
+ {
+ case SYMLINK_ALWAYS_DEREF:
+ return true;
+ case SYMLINK_DEREF_ARGSONLY:
+ return (state.curdepth == 0);
+ case SYMLINK_NEVER_DEREF:
+ default:
+ return false;
+ }
+}
+
+
+/* Take a "mode" indicator and fill in the files of 'state'.
+ */
+bool
+digest_mode (mode_t *mode,
+ const char *pathname,
+ const char *name,
+ struct stat *pstat,
+ bool leaf)
+{
+ /* If we know the type of the directory entry, and it is not a
+ * symbolic link, we may be able to avoid a stat() or lstat() call.
+ */
+ if (*mode)
+ {
+ if (S_ISLNK(*mode) && following_links())
+ {
+ /* mode is wrong because we should have followed the symlink. */
+ if (get_statinfo (pathname, name, pstat) != 0)
+ return false;
+ *mode = state.type = pstat->st_mode;
+ state.have_type = true;
+ }
+ else
+ {
+ state.have_type = true;
+ pstat->st_mode = state.type = *mode;
+ }
+ }
+ else
+ {
+ /* Mode is not yet known; may have to stat the file unless we
+ * can deduce that it is not a directory (which is all we need to
+ * know at this stage)
+ */
+ if (leaf)
+ {
+ state.have_stat = false;
+ state.have_type = false;
+ state.type = 0;
+ }
+ else
+ {
+ if (get_statinfo (pathname, name, pstat) != 0)
+ return false;
+
+ /* If -L is in effect and we are dealing with a symlink,
+ * st_mode is the mode of the pointed-to file, while mode is
+ * the mode of the directory entry (S_IFLNK). Hence now
+ * that we have the stat information, override "mode".
+ */
+ state.type = *mode = pstat->st_mode;
+ state.have_type = true;
+ }
+ }
+
+ /* success. */
+ return true;
+}
+
+
+/* Return true if there are no predicates with no_default_print in
+ predicate list PRED, false if there are any.
+ Returns true if default print should be performed */
+
+bool
+default_prints (struct predicate *pred)
+{
+ while (pred != NULL)
+ {
+ if (pred->no_default_print)
+ return (false);
+ pred = pred->pred_next;
+ }
+ return (true);
+}
+
+bool
+looks_like_expression (const char *arg, bool leading)
+{
+ switch (arg[0])
+ {
+ case '-':
+ if (arg[1]) /* "-foo" is an expression. */
+ return true;
+ else
+ return false; /* Just "-" is a filename. */
+ break;
+
+ case ')':
+ case ',':
+ if (arg[1])
+ return false; /* )x and ,z are not expressions */
+ else
+ return !leading; /* A leading ) or , is not either */
+
+ /* ( and ! are part of an expression, but (2 and !foo are
+ * filenames.
+ */
+ case '!':
+ case '(':
+ if (arg[1])
+ return false;
+ else
+ return true;
+
+ default:
+ return false;
+ }
+}
+
+static void
+process_debug_options (char *arg)
+{
+ const char *p;
+ char *token_context = NULL;
+ const char delimiters[] = ",";
+ bool empty = true;
+ size_t i;
+
+ p = strtok_r (arg, delimiters, &token_context);
+ while (p)
+ {
+ empty = false;
+
+ for (i=0; i<N_DEBUGASSOC; ++i)
+ {
+ if (0 == strcmp (debugassoc[i].name, p))
+ {
+ options.debug_options |= debugassoc[i].val;
+ break;
+ }
+ }
+ if (i >= N_DEBUGASSOC)
+ {
+ error (0, 0, _("Ignoring unrecognised debug flag %s"),
+ quotearg_n_style (0, options.err_quoting_style, arg));
+ }
+ p = strtok_r (NULL, delimiters, &token_context);
+ }
+ if (empty)
+ {
+ error(EXIT_FAILURE, 0, _("Empty argument to the -D option."));
+ }
+ else if (options.debug_options & DebugHelp)
+ {
+ show_valid_debug_options (stdout, 1);
+ exit (EXIT_SUCCESS);
+ }
+}
+
+
+static void
+process_optimisation_option (const char *arg)
+{
+ if (0 == arg[0])
+ {
+ error (EXIT_FAILURE, 0,
+ _("The -O option must be immediately followed by a decimal integer"));
+ }
+ else
+ {
+ unsigned long opt_level;
+ char *end;
+
+ if (!isdigit ( (unsigned char) arg[0] ))
+ {
+ error (EXIT_FAILURE, 0,
+ _("Please specify a decimal number immediately after -O"));
+ }
+ else
+ {
+ int prev_errno = errno;
+ errno = 0;
+
+ opt_level = strtoul (arg, &end, 10);
+ if ( (0==opt_level) && (end==arg) )
+ {
+ error (EXIT_FAILURE, 0,
+ _("Please specify a decimal number immediately after -O"));
+ }
+ else if (*end)
+ {
+ /* unwanted trailing characters. */
+ error (EXIT_FAILURE, 0, _("Invalid optimisation level %s"), arg);
+ }
+ else if ( (ULONG_MAX==opt_level) && errno)
+ {
+ error (EXIT_FAILURE, errno,
+ _("Invalid optimisation level %s"), arg);
+ }
+ else if (opt_level > USHRT_MAX)
+ {
+ /* tricky to test, as on some platforms USHORT_MAX and ULONG_MAX
+ * can have the same value, though this is unusual.
+ */
+ error (EXIT_FAILURE, 0,
+ _("Optimisation level %lu is too high. "
+ "If you want to find files very quickly, "
+ "consider using GNU locate."),
+ opt_level);
+ }
+ else
+ {
+ options.optimisation_level = opt_level;
+ errno = prev_errno;
+ }
+ }
+ }
+}
+
+int
+process_leading_options (int argc, char *argv[])
+{
+ int i, end_of_leading_options;
+
+ for (i=1; (end_of_leading_options = i) < argc; ++i)
+ {
+ if (0 == strcmp ("-H", argv[i]))
+ {
+ /* Meaning: dereference symbolic links on command line, but nowhere else. */
+ set_follow_state (SYMLINK_DEREF_ARGSONLY);
+ }
+ else if (0 == strcmp ("-L", argv[i]))
+ {
+ /* Meaning: dereference all symbolic links. */
+ set_follow_state (SYMLINK_ALWAYS_DEREF);
+ }
+ else if (0 == strcmp ("-P", argv[i]))
+ {
+ /* Meaning: never dereference symbolic links (default). */
+ set_follow_state (SYMLINK_NEVER_DEREF);
+ }
+ else if (0 == strcmp ("--", argv[i]))
+ {
+ /* -- signifies the end of options. */
+ end_of_leading_options = i+1; /* Next time start with the next option */
+ break;
+ }
+ else if (0 == strcmp ("-D", argv[i]))
+ {
+ process_debug_options (argv[i+1]);
+ ++i; /* skip the argument too. */
+ }
+ else if (0 == strncmp ("-O", argv[i], 2))
+ {
+ process_optimisation_option (argv[i]+2);
+ }
+ else
+ {
+ /* Hmm, must be one of
+ * (a) A path name
+ * (b) A predicate
+ */
+ end_of_leading_options = i; /* Next time start with this option */
+ break;
+ }
+ }
+ return end_of_leading_options;
+}
+
+static struct timespec
+now(void)
+{
+ struct timespec retval;
+ struct timeval tv;
+ time_t t;
+
+ if (0 == gettimeofday (&tv, NULL))
+ {
+ retval.tv_sec = tv.tv_sec;
+ retval.tv_nsec = tv.tv_usec * 1000; /* convert unit from microseconds to nanoseconds */
+ return retval;
+ }
+ t = time (NULL);
+ assert (t != (time_t)-1);
+ retval.tv_sec = t;
+ retval.tv_nsec = 0;
+ return retval;
+}
+
+void
+set_option_defaults (struct options *p)
+{
+ if (getenv ("POSIXLY_CORRECT"))
+ p->posixly_correct = true;
+ else
+ p->posixly_correct = false;
+
+ /* We call check_nofollow() before setlocale() because the numbers
+ * for which we check (in the results of uname) definitiely have "."
+ * as the decimal point indicator even under locales for which that
+ * is not normally true. Hence atof would do the wrong thing
+ * if we call it after setlocale().
+ */
+#ifdef O_NOFOLLOW
+ p->open_nofollow_available = check_nofollow ();
+#else
+ p->open_nofollow_available = false;
+#endif
+
+ p->regex_options = RE_SYNTAX_EMACS;
+
+ if (isatty (0))
+ {
+ p->warnings = true;
+ p->literal_control_chars = false;
+ }
+ else
+ {
+ p->warnings = false;
+ p->literal_control_chars = false; /* may change */
+ }
+ if (p->posixly_correct)
+ {
+ p->warnings = false;
+ }
+
+ p->do_dir_first = true;
+ p->explicit_depth = false;
+ p->maxdepth = p->mindepth = -1;
+
+ p->start_time = now ();
+ p->cur_day_start.tv_sec = p->start_time.tv_sec - DAYSECS;
+ p->cur_day_start.tv_nsec = p->start_time.tv_nsec;
+
+ p->full_days = false;
+ p->stay_on_filesystem = false;
+ p->ignore_readdir_race = false;
+
+ if (p->posixly_correct)
+ p->output_block_size = 512;
+ else
+ p->output_block_size = 1024;
+
+ p->debug_options = 0uL;
+ p->optimisation_level = 2;
+
+ if (getenv ("FIND_BLOCK_SIZE"))
+ {
+ error (EXIT_FAILURE, 0,
+ _("The environment variable FIND_BLOCK_SIZE is not supported, the only thing that affects the block size is the POSIXLY_CORRECT environment variable"));
+ }
+
+#if LEAF_OPTIMISATION
+ /* The leaf optimisation is enabled. */
+ p->no_leaf_check = false;
+#else
+ /* The leaf optimisation is disabled. */
+ p->no_leaf_check = true;
+#endif
+
+ set_follow_state (SYMLINK_NEVER_DEREF); /* The default is equivalent to -P. */
+
+ p->err_quoting_style = locale_quoting_style;
+}
+
+
+/* apply_predicate
+ *
+ */
+bool
+apply_predicate(const char *pathname, struct stat *stat_buf, struct predicate *p)
+{
+ ++p->perf.visits;
+
+ if (p->need_stat || p->need_type || p->need_inum)
+ {
+ /* We may need a stat here. */
+ if (get_info(pathname, stat_buf, p) != 0)
+ return false;
+ }
+ if ((p->pred_func)(pathname, stat_buf, p))
+ {
+ ++(p->perf.successes);
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+}
+
+
+/* is_exec_in_local_dir
+ *
+ */
+bool
+is_exec_in_local_dir (const PRED_FUNC pred_func)
+{
+ return pred_execdir == pred_func || pred_okdir == pred_func;
+}
+
+/* safely_quote_err_filename
+ *
+ */
+const char *
+safely_quote_err_filename (int n, char const *arg)
+{
+ return quotearg_n_style (n, options.err_quoting_style, arg);
+}
+
+/* We have encountered an error which should affect the exit status.
+ * This is normally used to change the exit status from 0 to 1.
+ * However, if the exit status is already 2 for example, we don't want to
+ * reduce it to 1.
+ */
+void
+error_severity (int level)
+{
+ if (state.exit_status < level)
+ state.exit_status = level;
+}
+
+
+/* report_file_err
+ */
+static void
+report_file_err(int exitval, int errno_value,
+ bool is_target_file, const char *name)
+{
+ /* It is important that the errno value is passed in as a function
+ * argument before we call safely_quote_err_filename(), because otherwise
+ * we might find that safely_quote_err_filename() changes errno.
+ */
+ if (!is_target_file || !state.already_issued_stat_error_msg)
+ {
+ error (exitval, errno_value, "%s", safely_quote_err_filename (0, name));
+ error_severity (1);
+ }
+ if (is_target_file)
+ {
+ state.already_issued_stat_error_msg = true;
+ }
+}
+
+/* nonfatal_target_file_error
+ */
+void
+nonfatal_target_file_error (int errno_value, const char *name)
+{
+ report_file_err (0, errno_value, true, name);
+}
+
+/* fatal_target_file_error
+ *
+ * Report an error on a target file (i.e. a file we are searching).
+ * Such errors are only reported once per searched file.
+ *
+ */
+void
+fatal_target_file_error(int errno_value, const char *name)
+{
+ report_file_err (1, errno_value, true, name);
+ /*NOTREACHED*/
+ abort ();
+}
+
+/* nonfatal_nontarget_file_error
+ *
+ */
+void
+nonfatal_nontarget_file_error (int errno_value, const char *name)
+{
+ report_file_err (0, errno_value, false, name);
+}
+
+/* fatal_nontarget_file_error
+ *
+ */
+void
+fatal_nontarget_file_error(int errno_value, const char *name)
+{
+ /* We're going to exit fatally, so make sure we always isssue the error
+ * message, even if it will be duplicate. Motivation: otherwise it may
+ * not be clear what went wrong.
+ */
+ state.already_issued_stat_error_msg = false;
+ report_file_err (1, errno_value, false, name);
+ /*NOTREACHED*/
+ abort ();
+}