diff options
author | Lorry Tar Creator <lorry-tar-importer@lorry> | 2015-12-28 21:37:38 +0000 |
---|---|---|
committer | Lorry Tar Creator <lorry-tar-importer@lorry> | 2015-12-28 21:37:38 +0000 |
commit | d7fdaf4d3a9795a294e93cad6f7d8238ba3754a6 (patch) | |
tree | 9bff05ea75330b7d8e2ade183cdcd1e4282f27d9 /find | |
download | findutils-tarball-master.tar.gz |
findutils-4.6.0HEADfindutils-4.6.0master
Diffstat (limited to 'find')
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='[0;31m'; \ + grn='[0;32m'; \ + lgn='[1;32m'; \ + blu='[1;34m'; \ + mgn='[0;35m'; \ + brg='[1m'; \ + std='[m'; \ + 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 Binary files differnew file mode 100644 index 0000000..60688dd --- /dev/null +++ b/find/testsuite/find.gnu/fprint0_stdout.xo 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 Binary files differnew file mode 100644 index 0000000..b947b3b --- /dev/null +++ b/find/testsuite/find.gnu/print0.xo 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 (®ex_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, ®ex_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, ®ex_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 (); +} |