From bbe35a6e1b54ef5cd7c1c471886c30ba85c0804e Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sat, 27 Apr 2024 19:47:50 +0200 Subject: Adding upstream version 1.21. Signed-off-by: Daniel Baumann --- src/Makefile.am | 110 ++ src/Makefile.in | 2804 ++++++++++++++++++++++++++ src/build_info.c | 101 + src/build_info.c.in | 18 + src/config.h.in | 2685 +++++++++++++++++++++++++ src/connect.c | 1084 ++++++++++ src/connect.h | 89 + src/convert.c | 1230 ++++++++++++ src/convert.h | 115 ++ src/cookies.c | 1539 +++++++++++++++ src/cookies.h | 47 + src/css-tokens.h | 65 + src/css-url.c | 236 +++ src/css-url.h | 37 + src/css.c | 3932 ++++++++++++++++++++++++++++++++++++ src/css.l | 167 ++ src/css_.c | 3933 ++++++++++++++++++++++++++++++++++++ src/exits.c | 93 + src/exits.h | 48 + src/ftp-basic.c | 1342 +++++++++++++ src/ftp-ls.c | 1175 +++++++++++ src/ftp-opie.c | 2220 +++++++++++++++++++++ src/ftp.c | 2898 +++++++++++++++++++++++++++ src/ftp.h | 184 ++ src/gnutls.c | 1116 +++++++++++ src/hash.c | 813 ++++++++ src/hash.h | 66 + src/host.c | 1082 ++++++++++ src/host.h | 107 + src/hsts.c | 829 ++++++++ src/hsts.h | 53 + src/html-parse.c | 1221 ++++++++++++ src/html-parse.h | 71 + src/html-url.c | 977 +++++++++ src/html-url.h | 58 + src/http-ntlm.c | 618 ++++++ src/http-ntlm.h | 53 + src/http.c | 5495 +++++++++++++++++++++++++++++++++++++++++++++++++++ src/http.h | 51 + src/init.c | 2135 ++++++++++++++++++++ src/init.h | 48 + src/iri.c | 449 +++++ src/iri.h | 75 + src/log.c | 995 ++++++++++ src/log.h | 60 + src/main.c | 2306 +++++++++++++++++++++ src/metalink.c | 1599 +++++++++++++++ src/metalink.h | 75 + src/mswindows.c | 652 ++++++ src/mswindows.h | 78 + src/netrc.c | 569 ++++++ src/netrc.h | 39 + src/openssl.c | 1260 ++++++++++++ src/options.h | 351 ++++ src/progress.c | 1462 ++++++++++++++ src/progress.h | 45 + src/ptimer.c | 413 ++++ src/ptimer.h | 46 + src/recur.c | 919 +++++++++ src/recur.h | 49 + src/res.c | 650 ++++++ src/res.h | 50 + src/retr.c | 1561 +++++++++++++++ src/retr.h | 81 + src/spider.c | 101 + src/spider.h | 39 + src/ssl.h | 40 + src/sysdep.h | 59 + src/url.c | 2540 ++++++++++++++++++++++++ src/url.h | 136 ++ src/utils.c | 2993 ++++++++++++++++++++++++++++ src/utils.h | 179 ++ src/version.h | 41 + src/warc.c | 1662 ++++++++++++++++ src/warc.h | 27 + src/wget.h | 333 ++++ src/xattr.c | 95 + src/xattr.h | 46 + 78 files changed, 63020 insertions(+) create mode 100644 src/Makefile.am create mode 100644 src/Makefile.in create mode 100644 src/build_info.c create mode 100644 src/build_info.c.in create mode 100644 src/config.h.in create mode 100644 src/connect.c create mode 100644 src/connect.h create mode 100644 src/convert.c create mode 100644 src/convert.h create mode 100644 src/cookies.c create mode 100644 src/cookies.h create mode 100644 src/css-tokens.h create mode 100644 src/css-url.c create mode 100644 src/css-url.h create mode 100644 src/css.c create mode 100644 src/css.l create mode 100644 src/css_.c create mode 100644 src/exits.c create mode 100644 src/exits.h create mode 100644 src/ftp-basic.c create mode 100644 src/ftp-ls.c create mode 100644 src/ftp-opie.c create mode 100644 src/ftp.c create mode 100644 src/ftp.h create mode 100644 src/gnutls.c create mode 100644 src/hash.c create mode 100644 src/hash.h create mode 100644 src/host.c create mode 100644 src/host.h create mode 100644 src/hsts.c create mode 100644 src/hsts.h create mode 100644 src/html-parse.c create mode 100644 src/html-parse.h create mode 100644 src/html-url.c create mode 100644 src/html-url.h create mode 100644 src/http-ntlm.c create mode 100644 src/http-ntlm.h create mode 100644 src/http.c create mode 100644 src/http.h create mode 100644 src/init.c create mode 100644 src/init.h create mode 100644 src/iri.c create mode 100644 src/iri.h create mode 100644 src/log.c create mode 100644 src/log.h create mode 100644 src/main.c create mode 100644 src/metalink.c create mode 100644 src/metalink.h create mode 100644 src/mswindows.c create mode 100644 src/mswindows.h create mode 100644 src/netrc.c create mode 100644 src/netrc.h create mode 100644 src/openssl.c create mode 100644 src/options.h create mode 100644 src/progress.c create mode 100644 src/progress.h create mode 100644 src/ptimer.c create mode 100644 src/ptimer.h create mode 100644 src/recur.c create mode 100644 src/recur.h create mode 100644 src/res.c create mode 100644 src/res.h create mode 100644 src/retr.c create mode 100644 src/retr.h create mode 100644 src/spider.c create mode 100644 src/spider.h create mode 100644 src/ssl.h create mode 100644 src/sysdep.h create mode 100644 src/url.c create mode 100644 src/url.h create mode 100644 src/utils.c create mode 100644 src/utils.h create mode 100644 src/version.h create mode 100644 src/warc.c create mode 100644 src/warc.h create mode 100644 src/wget.h create mode 100644 src/xattr.c create mode 100644 src/xattr.h (limited to 'src') diff --git a/src/Makefile.am b/src/Makefile.am new file mode 100644 index 0000000..322a3db --- /dev/null +++ b/src/Makefile.am @@ -0,0 +1,110 @@ +# Makefile for `wget' utility +# Copyright (C) 1995-2011, 2015, 2018-2020 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 Wget. If not, see . + +# Additional permission under GNU GPL version 3 section 7 + +# If you modify this program, or any covered work, by linking or +# combining it with the OpenSSL project's OpenSSL library (or a +# modified version of that library), containing parts covered by the +# terms of the OpenSSL or SSLeay licenses, the Free Software Foundation +# grants you additional permission to convey the resulting work. +# Corresponding Source for a non-source form of such a combination +# shall include the source code for the parts of OpenSSL used as well +# as that of the covered work. + +# +# Version: @VERSION@ +# + +if IRI_IS_ENABLED +IRI_OBJ = iri.c +endif + +if METALINK_IS_ENABLED +METALINK_OBJ = metalink.c +endif + +if WITH_XATTR +XATTR_OBJ = xattr.c +endif + +# The following line is losing on some versions of make! +DEFS = @DEFS@ -DSYSTEM_WGETRC=\"$(sysconfdir)/wgetrc\" -DLOCALEDIR=\"$(localedir)\" + +EXTRA_DIST = css.l css.c css_.c build_info.c.in build_info.c + +bin_PROGRAMS = wget +wget_SOURCES = connect.c convert.c cookies.c ftp.c \ + css_.c css-url.c \ + ftp-basic.c ftp-ls.c hash.c host.c hsts.c html-parse.c html-url.c \ + http.c init.c log.c main.c netrc.c progress.c ptimer.c \ + recur.c res.c retr.c spider.c url.c warc.c $(XATTR_OBJ) \ + utils.c exits.c build_info.c $(IRI_OBJ) $(METALINK_OBJ) \ + css-url.h css-tokens.h connect.h convert.h cookies.h \ + ftp.h hash.h host.h hsts.h html-parse.h html-url.h \ + http.h http-ntlm.h init.h log.h mswindows.h netrc.h \ + options.h progress.h ptimer.h recur.h res.h retr.h \ + spider.h ssl.h sysdep.h url.h warc.h utils.h wget.h iri.h \ + exits.h version.h metalink.h xattr.h +nodist_wget_SOURCES = version.c +EXTRA_wget_SOURCES = iri.c +LDADD = $(CODE_COVERAGE_LIBS) $(LIBOBJS) ../lib/libgnu.a $(GETADDRINFO_LIB) $(HOSTENT_LIB)\ + $(INET_NTOP_LIB) $(LIBSOCKET) $(LIB_CLOCK_GETTIME) $(LIB_CRYPTO)\ + $(LIB_NANOSLEEP) $(LIB_POSIX_SPAWN) $(LIB_SELECT) $(LIBICONV) $(LIBINTL)\ + $(LIBTHREAD) $(LIBUNISTRING) $(SERVENT_LIB) +AM_CPPFLAGS = -I$(top_builddir)/lib -I$(top_srcdir)/lib $(CODE_COVERAGE_CPPFLAGS) +AM_CFLAGS = $(WERROR_CFLAGS) $(WARN_CFLAGS) $(CODE_COVERAGE_CFLAGS) + +../lib/libgnu.a: + cd ../lib && $(MAKE) $(AM_MAKEFLAGS) + +build_info.c: $(srcdir)/Makefile.am $(srcdir)/build_info.c.in + if test -n "$(VPATH)"; then cp "$(srcdir)/build_info.c.in" .; fi + $(PERL) "$(top_srcdir)/build-aux/build_info.pl" \ + "$(top_builddir)/src/build_info.c" + if test -n "$(VPATH)"; then rm -f build_info.c.in; fi + +ESCAPEQUOTE = sed -e 's/[\\"]/\\&/g' -e 's/\\"/"/' -e 's/\\";$$/";/' +version.c: $(wget_SOURCES) ../lib/libgnu.a + echo '/* version.c */' > $@ + echo '/* Autogenerated by Makefile - DO NOT EDIT */' >> $@ + echo '' >> $@ + echo '#include "version.h"' >> $@ + echo 'const char *version_string = "@VERSION@";' >> $@ + echo 'const char *compilation_string = "'$(COMPILE)'";' \ + | $(ESCAPEQUOTE) >> $@ + echo 'const char *link_string = "'$(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(AM_LDFLAGS) $(LDFLAGS) $(LIBS) $(wget_LDADD)'";' \ + | $(ESCAPEQUOTE) >> $@ + +css.c: $(srcdir)/css.l + $(LEX) $(LFLAGS) -o$@ $^ + +css_.c: css.c + echo '#include "wget.h"' > $@ + cat css.c >> $@ + +distclean-local: + rm -f css.c css_.c + +check_LIBRARIES = libunittest.a +libunittest_a_SOURCES = $(wget_SOURCES) build_info.c +nodist_libunittest_a_SOURCES = version.c +libunittest_a_CPPFLAGS = -DTESTING "-I$(top_builddir)/lib" "-I$(top_srcdir)/lib" $(CODE_COVERAGE_CPPLAGS) +libunittest_a_LIBADD = $(LIBOBJS) + +CLEANFILES = *~ *.bak core core.[0-9]* build_info.c version.c diff --git a/src/Makefile.in b/src/Makefile.in new file mode 100644 index 0000000..3e7c745 --- /dev/null +++ b/src/Makefile.in @@ -0,0 +1,2804 @@ +# Makefile.in generated by automake 1.16.2 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2020 Free Software Foundation, Inc. + +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +# Makefile for `wget' utility +# Copyright (C) 1995-2011, 2015, 2018-2020 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 Wget. If not, see . + +# Additional permission under GNU GPL version 3 section 7 + +# If you modify this program, or any covered work, by linking or +# combining it with the OpenSSL project's OpenSSL library (or a +# modified version of that library), containing parts covered by the +# terms of the OpenSSL or SSLeay licenses, the Free Software Foundation +# grants you additional permission to convey the resulting work. +# Corresponding Source for a non-source form of such a combination +# shall include the source code for the parts of OpenSSL used as well +# as that of the covered work. + +# +# Version: @VERSION@ +# + +VPATH = @srcdir@ +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +bin_PROGRAMS = wget$(EXEEXT) +subdir = src +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/00gnulib.m4 \ + $(top_srcdir)/m4/__inline.m4 \ + $(top_srcdir)/m4/absolute-header.m4 $(top_srcdir)/m4/access.m4 \ + $(top_srcdir)/m4/af_alg.m4 $(top_srcdir)/m4/alloca.m4 \ + $(top_srcdir)/m4/arpa_inet_h.m4 \ + $(top_srcdir)/m4/asm-underscore.m4 $(top_srcdir)/m4/base32.m4 \ + $(top_srcdir)/m4/btowc.m4 $(top_srcdir)/m4/builtin-expect.m4 \ + $(top_srcdir)/m4/byteswap.m4 $(top_srcdir)/m4/canonicalize.m4 \ + $(top_srcdir)/m4/chdir-long.m4 $(top_srcdir)/m4/clock_time.m4 \ + $(top_srcdir)/m4/close.m4 $(top_srcdir)/m4/closedir.m4 \ + $(top_srcdir)/m4/codeset.m4 $(top_srcdir)/m4/ctype.m4 \ + $(top_srcdir)/m4/d-ino.m4 $(top_srcdir)/m4/dirent_h.m4 \ + $(top_srcdir)/m4/dirfd.m4 \ + $(top_srcdir)/m4/double-slash-root.m4 $(top_srcdir)/m4/dup.m4 \ + $(top_srcdir)/m4/dup2.m4 $(top_srcdir)/m4/eaccess.m4 \ + $(top_srcdir)/m4/eealloc.m4 $(top_srcdir)/m4/environ.m4 \ + $(top_srcdir)/m4/errno_h.m4 $(top_srcdir)/m4/error.m4 \ + $(top_srcdir)/m4/exponentd.m4 $(top_srcdir)/m4/extensions.m4 \ + $(top_srcdir)/m4/extern-inline.m4 \ + $(top_srcdir)/m4/fatal-signal.m4 $(top_srcdir)/m4/fchdir.m4 \ + $(top_srcdir)/m4/fcntl-o.m4 $(top_srcdir)/m4/fcntl.m4 \ + $(top_srcdir)/m4/fcntl_h.m4 $(top_srcdir)/m4/fdopendir.m4 \ + $(top_srcdir)/m4/fflush.m4 $(top_srcdir)/m4/filenamecat.m4 \ + $(top_srcdir)/m4/findprog-in.m4 $(top_srcdir)/m4/flexmember.m4 \ + $(top_srcdir)/m4/float_h.m4 $(top_srcdir)/m4/flock.m4 \ + $(top_srcdir)/m4/fnmatch.m4 $(top_srcdir)/m4/fnmatch_h.m4 \ + $(top_srcdir)/m4/fopen.m4 $(top_srcdir)/m4/fpurge.m4 \ + $(top_srcdir)/m4/freading.m4 $(top_srcdir)/m4/free.m4 \ + $(top_srcdir)/m4/fseek.m4 $(top_srcdir)/m4/fseeko.m4 \ + $(top_srcdir)/m4/fstat.m4 $(top_srcdir)/m4/fstatat.m4 \ + $(top_srcdir)/m4/ftell.m4 $(top_srcdir)/m4/ftello.m4 \ + $(top_srcdir)/m4/futimens.m4 $(top_srcdir)/m4/getaddrinfo.m4 \ + $(top_srcdir)/m4/getcwd-abort-bug.m4 \ + $(top_srcdir)/m4/getcwd-path-max.m4 $(top_srcdir)/m4/getcwd.m4 \ + $(top_srcdir)/m4/getdelim.m4 $(top_srcdir)/m4/getdtablesize.m4 \ + $(top_srcdir)/m4/getgroups.m4 $(top_srcdir)/m4/getline.m4 \ + $(top_srcdir)/m4/getopt.m4 $(top_srcdir)/m4/getpagesize.m4 \ + $(top_srcdir)/m4/getpass.m4 $(top_srcdir)/m4/getprogname.m4 \ + $(top_srcdir)/m4/getrandom.m4 $(top_srcdir)/m4/gettext.m4 \ + $(top_srcdir)/m4/gettime.m4 $(top_srcdir)/m4/gettimeofday.m4 \ + $(top_srcdir)/m4/gl-openssl.m4 \ + $(top_srcdir)/m4/gnulib-common.m4 \ + $(top_srcdir)/m4/gnulib-comp.m4 \ + $(top_srcdir)/m4/group-member.m4 \ + $(top_srcdir)/m4/host-cpu-c-abi.m4 $(top_srcdir)/m4/hostent.m4 \ + $(top_srcdir)/m4/iconv.m4 $(top_srcdir)/m4/iconv_h.m4 \ + $(top_srcdir)/m4/include_next.m4 $(top_srcdir)/m4/inet_ntop.m4 \ + $(top_srcdir)/m4/inline.m4 $(top_srcdir)/m4/intlmacosx.m4 \ + $(top_srcdir)/m4/intmax_t.m4 $(top_srcdir)/m4/inttypes.m4 \ + $(top_srcdir)/m4/inttypes_h.m4 $(top_srcdir)/m4/ioctl.m4 \ + $(top_srcdir)/m4/isblank.m4 $(top_srcdir)/m4/iswblank.m4 \ + $(top_srcdir)/m4/iswdigit.m4 $(top_srcdir)/m4/iswxdigit.m4 \ + $(top_srcdir)/m4/langinfo_h.m4 $(top_srcdir)/m4/largefile.m4 \ + $(top_srcdir)/m4/lib-ld.m4 $(top_srcdir)/m4/lib-link.m4 \ + $(top_srcdir)/m4/lib-prefix.m4 \ + $(top_srcdir)/m4/libunistring-base.m4 \ + $(top_srcdir)/m4/libunistring-optional.m4 \ + $(top_srcdir)/m4/libunistring.m4 $(top_srcdir)/m4/limits-h.m4 \ + $(top_srcdir)/m4/link.m4 $(top_srcdir)/m4/localcharset.m4 \ + $(top_srcdir)/m4/locale-fr.m4 $(top_srcdir)/m4/locale-ja.m4 \ + $(top_srcdir)/m4/locale-zh.m4 $(top_srcdir)/m4/locale_h.m4 \ + $(top_srcdir)/m4/localeconv.m4 $(top_srcdir)/m4/lock.m4 \ + $(top_srcdir)/m4/lseek.m4 $(top_srcdir)/m4/lstat.m4 \ + $(top_srcdir)/m4/malloc.m4 $(top_srcdir)/m4/malloca.m4 \ + $(top_srcdir)/m4/mbchar.m4 $(top_srcdir)/m4/mbiter.m4 \ + $(top_srcdir)/m4/mbrtowc.m4 $(top_srcdir)/m4/mbsinit.m4 \ + $(top_srcdir)/m4/mbsrtowcs.m4 $(top_srcdir)/m4/mbstate_t.m4 \ + $(top_srcdir)/m4/mbtowc.m4 $(top_srcdir)/m4/md4.m4 \ + $(top_srcdir)/m4/md5.m4 $(top_srcdir)/m4/memchr.m4 \ + $(top_srcdir)/m4/mempcpy.m4 $(top_srcdir)/m4/memrchr.m4 \ + $(top_srcdir)/m4/minmax.m4 $(top_srcdir)/m4/mkdir.m4 \ + $(top_srcdir)/m4/mkostemp.m4 $(top_srcdir)/m4/mkstemp.m4 \ + $(top_srcdir)/m4/mktime.m4 $(top_srcdir)/m4/mmap-anon.m4 \ + $(top_srcdir)/m4/mode_t.m4 $(top_srcdir)/m4/msvc-inval.m4 \ + $(top_srcdir)/m4/msvc-nothrow.m4 $(top_srcdir)/m4/multiarch.m4 \ + $(top_srcdir)/m4/nanosleep.m4 $(top_srcdir)/m4/netdb_h.m4 \ + $(top_srcdir)/m4/netinet_in_h.m4 \ + $(top_srcdir)/m4/nl_langinfo.m4 $(top_srcdir)/m4/nls.m4 \ + $(top_srcdir)/m4/nocrash.m4 $(top_srcdir)/m4/off_t.m4 \ + $(top_srcdir)/m4/open-cloexec.m4 \ + $(top_srcdir)/m4/open-slash.m4 $(top_srcdir)/m4/open.m4 \ + $(top_srcdir)/m4/openat.m4 $(top_srcdir)/m4/opendir.m4 \ + $(top_srcdir)/m4/pathmax.m4 $(top_srcdir)/m4/pipe.m4 \ + $(top_srcdir)/m4/pipe2.m4 $(top_srcdir)/m4/po.m4 \ + $(top_srcdir)/m4/posix_spawn.m4 \ + $(top_srcdir)/m4/posix_spawn_faction_addchdir.m4 \ + $(top_srcdir)/m4/printf.m4 \ + $(top_srcdir)/m4/pthread_rwlock_rdlock.m4 \ + $(top_srcdir)/m4/quote.m4 $(top_srcdir)/m4/quotearg.m4 \ + $(top_srcdir)/m4/raise.m4 $(top_srcdir)/m4/rawmemchr.m4 \ + $(top_srcdir)/m4/readdir.m4 $(top_srcdir)/m4/readlink.m4 \ + $(top_srcdir)/m4/realloc.m4 $(top_srcdir)/m4/regex.m4 \ + $(top_srcdir)/m4/rewinddir.m4 $(top_srcdir)/m4/save-cwd.m4 \ + $(top_srcdir)/m4/sched_h.m4 $(top_srcdir)/m4/secure_getenv.m4 \ + $(top_srcdir)/m4/select.m4 $(top_srcdir)/m4/servent.m4 \ + $(top_srcdir)/m4/setlocale_null.m4 \ + $(top_srcdir)/m4/sh-filename.m4 $(top_srcdir)/m4/sha1.m4 \ + $(top_srcdir)/m4/sha256.m4 $(top_srcdir)/m4/sha512.m4 \ + $(top_srcdir)/m4/sig_atomic_t.m4 $(top_srcdir)/m4/sigaction.m4 \ + $(top_srcdir)/m4/signal_h.m4 \ + $(top_srcdir)/m4/signalblocking.m4 $(top_srcdir)/m4/sigpipe.m4 \ + $(top_srcdir)/m4/size_max.m4 $(top_srcdir)/m4/snprintf.m4 \ + $(top_srcdir)/m4/socketlib.m4 $(top_srcdir)/m4/sockets.m4 \ + $(top_srcdir)/m4/socklen.m4 $(top_srcdir)/m4/sockpfaf.m4 \ + $(top_srcdir)/m4/spawn-pipe.m4 $(top_srcdir)/m4/spawn_h.m4 \ + $(top_srcdir)/m4/ssize_t.m4 $(top_srcdir)/m4/stat-time.m4 \ + $(top_srcdir)/m4/stat.m4 $(top_srcdir)/m4/stdalign.m4 \ + $(top_srcdir)/m4/stdbool.m4 $(top_srcdir)/m4/stddef_h.m4 \ + $(top_srcdir)/m4/stdint.m4 $(top_srcdir)/m4/stdint_h.m4 \ + $(top_srcdir)/m4/stdio_h.m4 $(top_srcdir)/m4/stdlib_h.m4 \ + $(top_srcdir)/m4/stpcpy.m4 $(top_srcdir)/m4/strcase.m4 \ + $(top_srcdir)/m4/strchrnul.m4 $(top_srcdir)/m4/strdup.m4 \ + $(top_srcdir)/m4/strerror.m4 $(top_srcdir)/m4/strerror_r.m4 \ + $(top_srcdir)/m4/string_h.m4 $(top_srcdir)/m4/strings_h.m4 \ + $(top_srcdir)/m4/strndup.m4 $(top_srcdir)/m4/strnlen.m4 \ + $(top_srcdir)/m4/strpbrk.m4 $(top_srcdir)/m4/strptime.m4 \ + $(top_srcdir)/m4/strtok_r.m4 $(top_srcdir)/m4/strtol.m4 \ + $(top_srcdir)/m4/strtoll.m4 $(top_srcdir)/m4/symlink.m4 \ + $(top_srcdir)/m4/sys_file_h.m4 $(top_srcdir)/m4/sys_ioctl_h.m4 \ + $(top_srcdir)/m4/sys_random_h.m4 \ + $(top_srcdir)/m4/sys_select_h.m4 \ + $(top_srcdir)/m4/sys_socket_h.m4 \ + $(top_srcdir)/m4/sys_stat_h.m4 $(top_srcdir)/m4/sys_time_h.m4 \ + $(top_srcdir)/m4/sys_types_h.m4 $(top_srcdir)/m4/sys_uio_h.m4 \ + $(top_srcdir)/m4/sys_wait_h.m4 $(top_srcdir)/m4/tempname.m4 \ + $(top_srcdir)/m4/threadlib.m4 $(top_srcdir)/m4/time_h.m4 \ + $(top_srcdir)/m4/time_r.m4 $(top_srcdir)/m4/timegm.m4 \ + $(top_srcdir)/m4/timespec.m4 $(top_srcdir)/m4/tm_gmtoff.m4 \ + $(top_srcdir)/m4/tmpdir.m4 $(top_srcdir)/m4/unistd-safer.m4 \ + $(top_srcdir)/m4/unistd_h.m4 $(top_srcdir)/m4/unlink.m4 \ + $(top_srcdir)/m4/unlocked-io.m4 $(top_srcdir)/m4/utime.m4 \ + $(top_srcdir)/m4/utime_h.m4 $(top_srcdir)/m4/utimens.m4 \ + $(top_srcdir)/m4/utimes.m4 $(top_srcdir)/m4/vasnprintf.m4 \ + $(top_srcdir)/m4/vasprintf.m4 $(top_srcdir)/m4/visibility.m4 \ + $(top_srcdir)/m4/vsnprintf.m4 $(top_srcdir)/m4/wait-process.m4 \ + $(top_srcdir)/m4/waitpid.m4 $(top_srcdir)/m4/warn-on-use.m4 \ + $(top_srcdir)/m4/warnings.m4 $(top_srcdir)/m4/wchar_h.m4 \ + $(top_srcdir)/m4/wchar_t.m4 $(top_srcdir)/m4/wcrtomb.m4 \ + $(top_srcdir)/m4/wctype_h.m4 $(top_srcdir)/m4/wcwidth.m4 \ + $(top_srcdir)/m4/wget.m4 $(top_srcdir)/m4/wget_manywarnings.m4 \ + $(top_srcdir)/m4/wint_t.m4 $(top_srcdir)/m4/wmemchr.m4 \ + $(top_srcdir)/m4/wmempcpy.m4 $(top_srcdir)/m4/write.m4 \ + $(top_srcdir)/m4/xalloc.m4 $(top_srcdir)/m4/xsize.m4 \ + $(top_srcdir)/m4/xstrndup.m4 $(top_srcdir)/m4/zzgnulib.m4 \ + $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +am__installdirs = "$(DESTDIR)$(bindir)" +PROGRAMS = $(bin_PROGRAMS) +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 = +libunittest_a_AR = $(AR) $(ARFLAGS) +libunittest_a_DEPENDENCIES = $(LIBOBJS) +am__libunittest_a_SOURCES_DIST = connect.c convert.c cookies.c ftp.c \ + css_.c css-url.c ftp-basic.c ftp-ls.c hash.c host.c hsts.c \ + html-parse.c html-url.c http.c init.c log.c main.c netrc.c \ + progress.c ptimer.c recur.c res.c retr.c spider.c url.c warc.c \ + xattr.c utils.c exits.c build_info.c iri.c metalink.c \ + css-url.h css-tokens.h connect.h convert.h cookies.h ftp.h \ + hash.h host.h hsts.h html-parse.h html-url.h http.h \ + http-ntlm.h init.h log.h mswindows.h netrc.h options.h \ + progress.h ptimer.h recur.h res.h retr.h spider.h ssl.h \ + sysdep.h url.h warc.h utils.h wget.h iri.h exits.h version.h \ + metalink.h xattr.h +@WITH_XATTR_TRUE@am__objects_1 = libunittest_a-xattr.$(OBJEXT) +@IRI_IS_ENABLED_TRUE@am__objects_2 = libunittest_a-iri.$(OBJEXT) +@METALINK_IS_ENABLED_TRUE@am__objects_3 = \ +@METALINK_IS_ENABLED_TRUE@ libunittest_a-metalink.$(OBJEXT) +am__objects_4 = libunittest_a-connect.$(OBJEXT) \ + libunittest_a-convert.$(OBJEXT) \ + libunittest_a-cookies.$(OBJEXT) libunittest_a-ftp.$(OBJEXT) \ + libunittest_a-css_.$(OBJEXT) libunittest_a-css-url.$(OBJEXT) \ + libunittest_a-ftp-basic.$(OBJEXT) \ + libunittest_a-ftp-ls.$(OBJEXT) libunittest_a-hash.$(OBJEXT) \ + libunittest_a-host.$(OBJEXT) libunittest_a-hsts.$(OBJEXT) \ + libunittest_a-html-parse.$(OBJEXT) \ + libunittest_a-html-url.$(OBJEXT) libunittest_a-http.$(OBJEXT) \ + libunittest_a-init.$(OBJEXT) libunittest_a-log.$(OBJEXT) \ + libunittest_a-main.$(OBJEXT) libunittest_a-netrc.$(OBJEXT) \ + libunittest_a-progress.$(OBJEXT) \ + libunittest_a-ptimer.$(OBJEXT) libunittest_a-recur.$(OBJEXT) \ + libunittest_a-res.$(OBJEXT) libunittest_a-retr.$(OBJEXT) \ + libunittest_a-spider.$(OBJEXT) libunittest_a-url.$(OBJEXT) \ + libunittest_a-warc.$(OBJEXT) $(am__objects_1) \ + libunittest_a-utils.$(OBJEXT) libunittest_a-exits.$(OBJEXT) \ + libunittest_a-build_info.$(OBJEXT) $(am__objects_2) \ + $(am__objects_3) +am_libunittest_a_OBJECTS = $(am__objects_4) \ + libunittest_a-build_info.$(OBJEXT) +nodist_libunittest_a_OBJECTS = libunittest_a-version.$(OBJEXT) +libunittest_a_OBJECTS = $(am_libunittest_a_OBJECTS) \ + $(nodist_libunittest_a_OBJECTS) +am__wget_SOURCES_DIST = connect.c convert.c cookies.c ftp.c css_.c \ + css-url.c ftp-basic.c ftp-ls.c hash.c host.c hsts.c \ + html-parse.c html-url.c http.c init.c log.c main.c netrc.c \ + progress.c ptimer.c recur.c res.c retr.c spider.c url.c warc.c \ + xattr.c utils.c exits.c build_info.c iri.c metalink.c \ + css-url.h css-tokens.h connect.h convert.h cookies.h ftp.h \ + hash.h host.h hsts.h html-parse.h html-url.h http.h \ + http-ntlm.h init.h log.h mswindows.h netrc.h options.h \ + progress.h ptimer.h recur.h res.h retr.h spider.h ssl.h \ + sysdep.h url.h warc.h utils.h wget.h iri.h exits.h version.h \ + metalink.h xattr.h +@WITH_XATTR_TRUE@am__objects_5 = xattr.$(OBJEXT) +@IRI_IS_ENABLED_TRUE@am__objects_6 = iri.$(OBJEXT) +@METALINK_IS_ENABLED_TRUE@am__objects_7 = metalink.$(OBJEXT) +am_wget_OBJECTS = connect.$(OBJEXT) convert.$(OBJEXT) \ + cookies.$(OBJEXT) ftp.$(OBJEXT) css_.$(OBJEXT) \ + css-url.$(OBJEXT) ftp-basic.$(OBJEXT) ftp-ls.$(OBJEXT) \ + hash.$(OBJEXT) host.$(OBJEXT) hsts.$(OBJEXT) \ + html-parse.$(OBJEXT) html-url.$(OBJEXT) http.$(OBJEXT) \ + init.$(OBJEXT) log.$(OBJEXT) main.$(OBJEXT) netrc.$(OBJEXT) \ + progress.$(OBJEXT) ptimer.$(OBJEXT) recur.$(OBJEXT) \ + res.$(OBJEXT) retr.$(OBJEXT) spider.$(OBJEXT) url.$(OBJEXT) \ + warc.$(OBJEXT) $(am__objects_5) utils.$(OBJEXT) \ + exits.$(OBJEXT) build_info.$(OBJEXT) $(am__objects_6) \ + $(am__objects_7) +nodist_wget_OBJECTS = version.$(OBJEXT) +wget_OBJECTS = $(am_wget_OBJECTS) $(nodist_wget_OBJECTS) +wget_LDADD = $(LDADD) +am__DEPENDENCIES_1 = +wget_DEPENDENCIES = $(LIBOBJS) ../lib/libgnu.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__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@ +depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp +am__maybe_remake_depfiles = depfiles +am__depfiles_remade = $(DEPDIR)/ftp-opie.Po $(DEPDIR)/gnutls.Po \ + $(DEPDIR)/http-ntlm.Po $(DEPDIR)/mswindows.Po \ + $(DEPDIR)/openssl.Po ./$(DEPDIR)/build_info.Po \ + ./$(DEPDIR)/connect.Po ./$(DEPDIR)/convert.Po \ + ./$(DEPDIR)/cookies.Po ./$(DEPDIR)/css-url.Po \ + ./$(DEPDIR)/css_.Po ./$(DEPDIR)/exits.Po \ + ./$(DEPDIR)/ftp-basic.Po ./$(DEPDIR)/ftp-ls.Po \ + ./$(DEPDIR)/ftp.Po ./$(DEPDIR)/hash.Po ./$(DEPDIR)/host.Po \ + ./$(DEPDIR)/hsts.Po ./$(DEPDIR)/html-parse.Po \ + ./$(DEPDIR)/html-url.Po ./$(DEPDIR)/http.Po \ + ./$(DEPDIR)/init.Po ./$(DEPDIR)/iri.Po \ + ./$(DEPDIR)/libunittest_a-build_info.Po \ + ./$(DEPDIR)/libunittest_a-connect.Po \ + ./$(DEPDIR)/libunittest_a-convert.Po \ + ./$(DEPDIR)/libunittest_a-cookies.Po \ + ./$(DEPDIR)/libunittest_a-css-url.Po \ + ./$(DEPDIR)/libunittest_a-css_.Po \ + ./$(DEPDIR)/libunittest_a-exits.Po \ + ./$(DEPDIR)/libunittest_a-ftp-basic.Po \ + ./$(DEPDIR)/libunittest_a-ftp-ls.Po \ + ./$(DEPDIR)/libunittest_a-ftp.Po \ + ./$(DEPDIR)/libunittest_a-hash.Po \ + ./$(DEPDIR)/libunittest_a-host.Po \ + ./$(DEPDIR)/libunittest_a-hsts.Po \ + ./$(DEPDIR)/libunittest_a-html-parse.Po \ + ./$(DEPDIR)/libunittest_a-html-url.Po \ + ./$(DEPDIR)/libunittest_a-http.Po \ + ./$(DEPDIR)/libunittest_a-init.Po \ + ./$(DEPDIR)/libunittest_a-iri.Po \ + ./$(DEPDIR)/libunittest_a-log.Po \ + ./$(DEPDIR)/libunittest_a-main.Po \ + ./$(DEPDIR)/libunittest_a-metalink.Po \ + ./$(DEPDIR)/libunittest_a-netrc.Po \ + ./$(DEPDIR)/libunittest_a-progress.Po \ + ./$(DEPDIR)/libunittest_a-ptimer.Po \ + ./$(DEPDIR)/libunittest_a-recur.Po \ + ./$(DEPDIR)/libunittest_a-res.Po \ + ./$(DEPDIR)/libunittest_a-retr.Po \ + ./$(DEPDIR)/libunittest_a-spider.Po \ + ./$(DEPDIR)/libunittest_a-url.Po \ + ./$(DEPDIR)/libunittest_a-utils.Po \ + ./$(DEPDIR)/libunittest_a-version.Po \ + ./$(DEPDIR)/libunittest_a-warc.Po \ + ./$(DEPDIR)/libunittest_a-xattr.Po ./$(DEPDIR)/log.Po \ + ./$(DEPDIR)/main.Po ./$(DEPDIR)/metalink.Po \ + ./$(DEPDIR)/netrc.Po ./$(DEPDIR)/progress.Po \ + ./$(DEPDIR)/ptimer.Po ./$(DEPDIR)/recur.Po ./$(DEPDIR)/res.Po \ + ./$(DEPDIR)/retr.Po ./$(DEPDIR)/spider.Po ./$(DEPDIR)/url.Po \ + ./$(DEPDIR)/utils.Po ./$(DEPDIR)/version.Po \ + ./$(DEPDIR)/warc.Po ./$(DEPDIR)/xattr.Po +am__mv = mv -f +AM_V_lt = $(am__v_lt_@AM_V@) +am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) +am__v_lt_0 = --silent +am__v_lt_1 = +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 = $(libunittest_a_SOURCES) $(nodist_libunittest_a_SOURCES) \ + $(wget_SOURCES) $(EXTRA_wget_SOURCES) $(nodist_wget_SOURCES) +DIST_SOURCES = $(am__libunittest_a_SOURCES_DIST) \ + $(am__wget_SOURCES_DIST) $(EXTRA_wget_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) \ + config.h.in +# 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 +am__DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/config.h.in \ + $(top_srcdir)/build-aux/depcomp ftp-opie.c gnutls.c \ + http-ntlm.c mswindows.c openssl.c +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +ALLOCA = @ALLOCA@ +ALLOCA_H = @ALLOCA_H@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +APPLE_UNIVERSAL_BUILD = @APPLE_UNIVERSAL_BUILD@ +AR = @AR@ +ARFLAGS = @ARFLAGS@ +ASM_SYMBOL_PREFIX = @ASM_SYMBOL_PREFIX@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +BITSIZEOF_PTRDIFF_T = @BITSIZEOF_PTRDIFF_T@ +BITSIZEOF_SIG_ATOMIC_T = @BITSIZEOF_SIG_ATOMIC_T@ +BITSIZEOF_SIZE_T = @BITSIZEOF_SIZE_T@ +BITSIZEOF_WCHAR_T = @BITSIZEOF_WCHAR_T@ +BITSIZEOF_WINT_T = @BITSIZEOF_WINT_T@ +BYTESWAP_H = @BYTESWAP_H@ +CARES_CFLAGS = @CARES_CFLAGS@ +CARES_LIBS = @CARES_LIBS@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CFLAG_VISIBILITY = @CFLAG_VISIBILITY@ +COMMENT_IF_NO_POD2MAN = @COMMENT_IF_NO_POD2MAN@ +CONFIG_INCLUDE = @CONFIG_INCLUDE@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CYGPATH_W = @CYGPATH_W@ + +# The following line is losing on some versions of make! +DEFS = @DEFS@ -DSYSTEM_WGETRC=\"$(sysconfdir)/wgetrc\" -DLOCALEDIR=\"$(localedir)\" +DEPDIR = @DEPDIR@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EMULTIHOP_HIDDEN = @EMULTIHOP_HIDDEN@ +EMULTIHOP_VALUE = @EMULTIHOP_VALUE@ +ENOLINK_HIDDEN = @ENOLINK_HIDDEN@ +ENOLINK_VALUE = @ENOLINK_VALUE@ +EOVERFLOW_HIDDEN = @EOVERFLOW_HIDDEN@ +EOVERFLOW_VALUE = @EOVERFLOW_VALUE@ +ERRNO_H = @ERRNO_H@ +EXEEXT = @EXEEXT@ +FLOAT_H = @FLOAT_H@ +FNMATCH_H = @FNMATCH_H@ +FUZZ_LIBS = @FUZZ_LIBS@ +GETADDRINFO_LIB = @GETADDRINFO_LIB@ +GETOPT_CDEFS_H = @GETOPT_CDEFS_H@ +GETOPT_H = @GETOPT_H@ +GETTEXT_MACRO_VERSION = @GETTEXT_MACRO_VERSION@ +GMSGFMT = @GMSGFMT@ +GMSGFMT_015 = @GMSGFMT_015@ +GNULIB_ACCEPT = @GNULIB_ACCEPT@ +GNULIB_ACCEPT4 = @GNULIB_ACCEPT4@ +GNULIB_ACCESS = @GNULIB_ACCESS@ +GNULIB_ALIGNED_ALLOC = @GNULIB_ALIGNED_ALLOC@ +GNULIB_ALPHASORT = @GNULIB_ALPHASORT@ +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_CHDIR = @GNULIB_CHDIR@ +GNULIB_CHOWN = @GNULIB_CHOWN@ +GNULIB_CLOSE = @GNULIB_CLOSE@ +GNULIB_CLOSEDIR = @GNULIB_CLOSEDIR@ +GNULIB_CONNECT = @GNULIB_CONNECT@ +GNULIB_COPY_FILE_RANGE = @GNULIB_COPY_FILE_RANGE@ +GNULIB_CREAT = @GNULIB_CREAT@ +GNULIB_CTIME = @GNULIB_CTIME@ +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_EXECL = @GNULIB_EXECL@ +GNULIB_EXECLE = @GNULIB_EXECLE@ +GNULIB_EXECLP = @GNULIB_EXECLP@ +GNULIB_EXECV = @GNULIB_EXECV@ +GNULIB_EXECVE = @GNULIB_EXECVE@ +GNULIB_EXECVP = @GNULIB_EXECVP@ +GNULIB_EXECVPE = @GNULIB_EXECVPE@ +GNULIB_EXPLICIT_BZERO = @GNULIB_EXPLICIT_BZERO@ +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_FLOCK = @GNULIB_FLOCK@ +GNULIB_FNMATCH = @GNULIB_FNMATCH@ +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_FREE_POSIX = @GNULIB_FREE_POSIX@ +GNULIB_FREOPEN = @GNULIB_FREOPEN@ +GNULIB_FSCANF = @GNULIB_FSCANF@ +GNULIB_FSEEK = @GNULIB_FSEEK@ +GNULIB_FSEEKO = @GNULIB_FSEEKO@ +GNULIB_FSTAT = @GNULIB_FSTAT@ +GNULIB_FSTATAT = @GNULIB_FSTATAT@ +GNULIB_FSYNC = @GNULIB_FSYNC@ +GNULIB_FTELL = @GNULIB_FTELL@ +GNULIB_FTELLO = @GNULIB_FTELLO@ +GNULIB_FTRUNCATE = @GNULIB_FTRUNCATE@ +GNULIB_FUTIMENS = @GNULIB_FUTIMENS@ +GNULIB_FWRITE = @GNULIB_FWRITE@ +GNULIB_GETADDRINFO = @GNULIB_GETADDRINFO@ +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_GETENTROPY = @GNULIB_GETENTROPY@ +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_GETOPT_POSIX = @GNULIB_GETOPT_POSIX@ +GNULIB_GETPAGESIZE = @GNULIB_GETPAGESIZE@ +GNULIB_GETPASS = @GNULIB_GETPASS@ +GNULIB_GETPEERNAME = @GNULIB_GETPEERNAME@ +GNULIB_GETRANDOM = @GNULIB_GETRANDOM@ +GNULIB_GETSOCKNAME = @GNULIB_GETSOCKNAME@ +GNULIB_GETSOCKOPT = @GNULIB_GETSOCKOPT@ +GNULIB_GETSUBOPT = @GNULIB_GETSUBOPT@ +GNULIB_GETTIMEOFDAY = @GNULIB_GETTIMEOFDAY@ +GNULIB_GETUMASK = @GNULIB_GETUMASK@ +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_ICONV = @GNULIB_ICONV@ +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_ISWBLANK = @GNULIB_ISWBLANK@ +GNULIB_ISWCTYPE = @GNULIB_ISWCTYPE@ +GNULIB_ISWDIGIT = @GNULIB_ISWDIGIT@ +GNULIB_ISWXDIGIT = @GNULIB_ISWXDIGIT@ +GNULIB_LCHMOD = @GNULIB_LCHMOD@ +GNULIB_LCHOWN = @GNULIB_LCHOWN@ +GNULIB_LINK = @GNULIB_LINK@ +GNULIB_LINKAT = @GNULIB_LINKAT@ +GNULIB_LISTEN = @GNULIB_LISTEN@ +GNULIB_LOCALECONV = @GNULIB_LOCALECONV@ +GNULIB_LOCALENAME = @GNULIB_LOCALENAME@ +GNULIB_LOCALTIME = @GNULIB_LOCALTIME@ +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_MDA_ACCESS = @GNULIB_MDA_ACCESS@ +GNULIB_MDA_CHDIR = @GNULIB_MDA_CHDIR@ +GNULIB_MDA_CHMOD = @GNULIB_MDA_CHMOD@ +GNULIB_MDA_CLOSE = @GNULIB_MDA_CLOSE@ +GNULIB_MDA_CREAT = @GNULIB_MDA_CREAT@ +GNULIB_MDA_DUP = @GNULIB_MDA_DUP@ +GNULIB_MDA_DUP2 = @GNULIB_MDA_DUP2@ +GNULIB_MDA_ECVT = @GNULIB_MDA_ECVT@ +GNULIB_MDA_EXECL = @GNULIB_MDA_EXECL@ +GNULIB_MDA_EXECLE = @GNULIB_MDA_EXECLE@ +GNULIB_MDA_EXECLP = @GNULIB_MDA_EXECLP@ +GNULIB_MDA_EXECV = @GNULIB_MDA_EXECV@ +GNULIB_MDA_EXECVE = @GNULIB_MDA_EXECVE@ +GNULIB_MDA_EXECVP = @GNULIB_MDA_EXECVP@ +GNULIB_MDA_EXECVPE = @GNULIB_MDA_EXECVPE@ +GNULIB_MDA_FCLOSEALL = @GNULIB_MDA_FCLOSEALL@ +GNULIB_MDA_FCVT = @GNULIB_MDA_FCVT@ +GNULIB_MDA_FDOPEN = @GNULIB_MDA_FDOPEN@ +GNULIB_MDA_FILENO = @GNULIB_MDA_FILENO@ +GNULIB_MDA_GCVT = @GNULIB_MDA_GCVT@ +GNULIB_MDA_GETCWD = @GNULIB_MDA_GETCWD@ +GNULIB_MDA_GETPID = @GNULIB_MDA_GETPID@ +GNULIB_MDA_GETW = @GNULIB_MDA_GETW@ +GNULIB_MDA_ISATTY = @GNULIB_MDA_ISATTY@ +GNULIB_MDA_LSEEK = @GNULIB_MDA_LSEEK@ +GNULIB_MDA_MEMCCPY = @GNULIB_MDA_MEMCCPY@ +GNULIB_MDA_MKDIR = @GNULIB_MDA_MKDIR@ +GNULIB_MDA_MKTEMP = @GNULIB_MDA_MKTEMP@ +GNULIB_MDA_OPEN = @GNULIB_MDA_OPEN@ +GNULIB_MDA_PUTENV = @GNULIB_MDA_PUTENV@ +GNULIB_MDA_PUTW = @GNULIB_MDA_PUTW@ +GNULIB_MDA_READ = @GNULIB_MDA_READ@ +GNULIB_MDA_RMDIR = @GNULIB_MDA_RMDIR@ +GNULIB_MDA_STRDUP = @GNULIB_MDA_STRDUP@ +GNULIB_MDA_SWAB = @GNULIB_MDA_SWAB@ +GNULIB_MDA_TEMPNAM = @GNULIB_MDA_TEMPNAM@ +GNULIB_MDA_TZSET = @GNULIB_MDA_TZSET@ +GNULIB_MDA_UMASK = @GNULIB_MDA_UMASK@ +GNULIB_MDA_UNLINK = @GNULIB_MDA_UNLINK@ +GNULIB_MDA_UTIME = @GNULIB_MDA_UTIME@ +GNULIB_MDA_WCSDUP = @GNULIB_MDA_WCSDUP@ +GNULIB_MDA_WRITE = @GNULIB_MDA_WRITE@ +GNULIB_MEMCHR = @GNULIB_MEMCHR@ +GNULIB_MEMMEM = @GNULIB_MEMMEM@ +GNULIB_MEMPCPY = @GNULIB_MEMPCPY@ +GNULIB_MEMRCHR = @GNULIB_MEMRCHR@ +GNULIB_MKDIR = @GNULIB_MKDIR@ +GNULIB_MKDIRAT = @GNULIB_MKDIRAT@ +GNULIB_MKDTEMP = @GNULIB_MKDTEMP@ +GNULIB_MKFIFO = @GNULIB_MKFIFO@ +GNULIB_MKFIFOAT = @GNULIB_MKFIFOAT@ +GNULIB_MKNOD = @GNULIB_MKNOD@ +GNULIB_MKNODAT = @GNULIB_MKNODAT@ +GNULIB_MKOSTEMP = @GNULIB_MKOSTEMP@ +GNULIB_MKOSTEMPS = @GNULIB_MKOSTEMPS@ +GNULIB_MKSTEMP = @GNULIB_MKSTEMP@ +GNULIB_MKSTEMPS = @GNULIB_MKSTEMPS@ +GNULIB_MKTIME = @GNULIB_MKTIME@ +GNULIB_NANOSLEEP = @GNULIB_NANOSLEEP@ +GNULIB_NL_LANGINFO = @GNULIB_NL_LANGINFO@ +GNULIB_NONBLOCKING = @GNULIB_NONBLOCKING@ +GNULIB_OBSTACK_PRINTF = @GNULIB_OBSTACK_PRINTF@ +GNULIB_OBSTACK_PRINTF_POSIX = @GNULIB_OBSTACK_PRINTF_POSIX@ +GNULIB_OPEN = @GNULIB_OPEN@ +GNULIB_OPENAT = @GNULIB_OPENAT@ +GNULIB_OPENDIR = @GNULIB_OPENDIR@ +GNULIB_OVERRIDES_STRUCT_STAT = @GNULIB_OVERRIDES_STRUCT_STAT@ +GNULIB_OVERRIDES_WINT_T = @GNULIB_OVERRIDES_WINT_T@ +GNULIB_PCLOSE = @GNULIB_PCLOSE@ +GNULIB_PERROR = @GNULIB_PERROR@ +GNULIB_PIPE = @GNULIB_PIPE@ +GNULIB_PIPE2 = @GNULIB_PIPE2@ +GNULIB_POPEN = @GNULIB_POPEN@ +GNULIB_POSIX_MEMALIGN = @GNULIB_POSIX_MEMALIGN@ +GNULIB_POSIX_OPENPT = @GNULIB_POSIX_OPENPT@ +GNULIB_POSIX_SPAWN = @GNULIB_POSIX_SPAWN@ +GNULIB_POSIX_SPAWNATTR_DESTROY = @GNULIB_POSIX_SPAWNATTR_DESTROY@ +GNULIB_POSIX_SPAWNATTR_GETFLAGS = @GNULIB_POSIX_SPAWNATTR_GETFLAGS@ +GNULIB_POSIX_SPAWNATTR_GETPGROUP = @GNULIB_POSIX_SPAWNATTR_GETPGROUP@ +GNULIB_POSIX_SPAWNATTR_GETSCHEDPARAM = @GNULIB_POSIX_SPAWNATTR_GETSCHEDPARAM@ +GNULIB_POSIX_SPAWNATTR_GETSCHEDPOLICY = @GNULIB_POSIX_SPAWNATTR_GETSCHEDPOLICY@ +GNULIB_POSIX_SPAWNATTR_GETSIGDEFAULT = @GNULIB_POSIX_SPAWNATTR_GETSIGDEFAULT@ +GNULIB_POSIX_SPAWNATTR_GETSIGMASK = @GNULIB_POSIX_SPAWNATTR_GETSIGMASK@ +GNULIB_POSIX_SPAWNATTR_INIT = @GNULIB_POSIX_SPAWNATTR_INIT@ +GNULIB_POSIX_SPAWNATTR_SETFLAGS = @GNULIB_POSIX_SPAWNATTR_SETFLAGS@ +GNULIB_POSIX_SPAWNATTR_SETPGROUP = @GNULIB_POSIX_SPAWNATTR_SETPGROUP@ +GNULIB_POSIX_SPAWNATTR_SETSCHEDPARAM = @GNULIB_POSIX_SPAWNATTR_SETSCHEDPARAM@ +GNULIB_POSIX_SPAWNATTR_SETSCHEDPOLICY = @GNULIB_POSIX_SPAWNATTR_SETSCHEDPOLICY@ +GNULIB_POSIX_SPAWNATTR_SETSIGDEFAULT = @GNULIB_POSIX_SPAWNATTR_SETSIGDEFAULT@ +GNULIB_POSIX_SPAWNATTR_SETSIGMASK = @GNULIB_POSIX_SPAWNATTR_SETSIGMASK@ +GNULIB_POSIX_SPAWNP = @GNULIB_POSIX_SPAWNP@ +GNULIB_POSIX_SPAWN_FILE_ACTIONS_ADDCHDIR = @GNULIB_POSIX_SPAWN_FILE_ACTIONS_ADDCHDIR@ +GNULIB_POSIX_SPAWN_FILE_ACTIONS_ADDCLOSE = @GNULIB_POSIX_SPAWN_FILE_ACTIONS_ADDCLOSE@ +GNULIB_POSIX_SPAWN_FILE_ACTIONS_ADDDUP2 = @GNULIB_POSIX_SPAWN_FILE_ACTIONS_ADDDUP2@ +GNULIB_POSIX_SPAWN_FILE_ACTIONS_ADDFCHDIR = @GNULIB_POSIX_SPAWN_FILE_ACTIONS_ADDFCHDIR@ +GNULIB_POSIX_SPAWN_FILE_ACTIONS_ADDOPEN = @GNULIB_POSIX_SPAWN_FILE_ACTIONS_ADDOPEN@ +GNULIB_POSIX_SPAWN_FILE_ACTIONS_DESTROY = @GNULIB_POSIX_SPAWN_FILE_ACTIONS_DESTROY@ +GNULIB_POSIX_SPAWN_FILE_ACTIONS_INIT = @GNULIB_POSIX_SPAWN_FILE_ACTIONS_INIT@ +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_REALLOCARRAY = @GNULIB_REALLOCARRAY@ +GNULIB_REALLOC_POSIX = @GNULIB_REALLOC_POSIX@ +GNULIB_REALPATH = @GNULIB_REALPATH@ +GNULIB_RECV = @GNULIB_RECV@ +GNULIB_RECVFROM = @GNULIB_RECVFROM@ +GNULIB_REMOVE = @GNULIB_REMOVE@ +GNULIB_RENAME = @GNULIB_RENAME@ +GNULIB_RENAMEAT = @GNULIB_RENAMEAT@ +GNULIB_REWINDDIR = @GNULIB_REWINDDIR@ +GNULIB_RMDIR = @GNULIB_RMDIR@ +GNULIB_RPMATCH = @GNULIB_RPMATCH@ +GNULIB_SCANDIR = @GNULIB_SCANDIR@ +GNULIB_SCANF = @GNULIB_SCANF@ +GNULIB_SCHED_YIELD = @GNULIB_SCHED_YIELD@ +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_SETLOCALE_NULL = @GNULIB_SETLOCALE_NULL@ +GNULIB_SETSOCKOPT = @GNULIB_SETSOCKOPT@ +GNULIB_SHUTDOWN = @GNULIB_SHUTDOWN@ +GNULIB_SIGABBREV_NP = @GNULIB_SIGABBREV_NP@ +GNULIB_SIGACTION = @GNULIB_SIGACTION@ +GNULIB_SIGDESCR_NP = @GNULIB_SIGDESCR_NP@ +GNULIB_SIGNAL_H_SIGPIPE = @GNULIB_SIGNAL_H_SIGPIPE@ +GNULIB_SIGPROCMASK = @GNULIB_SIGPROCMASK@ +GNULIB_SLEEP = @GNULIB_SLEEP@ +GNULIB_SNPRINTF = @GNULIB_SNPRINTF@ +GNULIB_SOCKET = @GNULIB_SOCKET@ +GNULIB_SPRINTF_POSIX = @GNULIB_SPRINTF_POSIX@ +GNULIB_STAT = @GNULIB_STAT@ +GNULIB_STDIO_H_NONBLOCKING = @GNULIB_STDIO_H_NONBLOCKING@ +GNULIB_STDIO_H_SIGPIPE = @GNULIB_STDIO_H_SIGPIPE@ +GNULIB_STPCPY = @GNULIB_STPCPY@ +GNULIB_STPNCPY = @GNULIB_STPNCPY@ +GNULIB_STRCASESTR = @GNULIB_STRCASESTR@ +GNULIB_STRCHRNUL = @GNULIB_STRCHRNUL@ +GNULIB_STRDUP = @GNULIB_STRDUP@ +GNULIB_STRERROR = @GNULIB_STRERROR@ +GNULIB_STRERRORNAME_NP = @GNULIB_STRERRORNAME_NP@ +GNULIB_STRERROR_R = @GNULIB_STRERROR_R@ +GNULIB_STRFTIME = @GNULIB_STRFTIME@ +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_STRTOLD = @GNULIB_STRTOLD@ +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_TIMEGM = @GNULIB_TIMEGM@ +GNULIB_TIME_R = @GNULIB_TIME_R@ +GNULIB_TIME_RZ = @GNULIB_TIME_RZ@ +GNULIB_TMPFILE = @GNULIB_TMPFILE@ +GNULIB_TOWCTRANS = @GNULIB_TOWCTRANS@ +GNULIB_TRUNCATE = @GNULIB_TRUNCATE@ +GNULIB_TTYNAME_R = @GNULIB_TTYNAME_R@ +GNULIB_TZSET = @GNULIB_TZSET@ +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_UTIME = @GNULIB_UTIME@ +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_WARN_CFLAGS = @GNULIB_WARN_CFLAGS@ +GNULIB_WCPCPY = @GNULIB_WCPCPY@ +GNULIB_WCPNCPY = @GNULIB_WCPNCPY@ +GNULIB_WCRTOMB = @GNULIB_WCRTOMB@ +GNULIB_WCSCASECMP = @GNULIB_WCSCASECMP@ +GNULIB_WCSCAT = @GNULIB_WCSCAT@ +GNULIB_WCSCHR = @GNULIB_WCSCHR@ +GNULIB_WCSCMP = @GNULIB_WCSCMP@ +GNULIB_WCSCOLL = @GNULIB_WCSCOLL@ +GNULIB_WCSCPY = @GNULIB_WCSCPY@ +GNULIB_WCSCSPN = @GNULIB_WCSCSPN@ +GNULIB_WCSDUP = @GNULIB_WCSDUP@ +GNULIB_WCSFTIME = @GNULIB_WCSFTIME@ +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_WMEMPCPY = @GNULIB_WMEMPCPY@ +GNULIB_WMEMSET = @GNULIB_WMEMSET@ +GNULIB_WRITE = @GNULIB_WRITE@ +GNULIB__EXIT = @GNULIB__EXIT@ +GNUTLS_CFLAGS = @GNUTLS_CFLAGS@ +GNUTLS_LIBS = @GNUTLS_LIBS@ +GPGME_CFLAGS = @GPGME_CFLAGS@ +GPGME_CONFIG = @GPGME_CONFIG@ +GPGME_LIBS = @GPGME_LIBS@ +GREP = @GREP@ +HAVE_ACCEPT4 = @HAVE_ACCEPT4@ +HAVE_ALIGNED_ALLOC = @HAVE_ALIGNED_ALLOC@ +HAVE_ALLOCA_H = @HAVE_ALLOCA_H@ +HAVE_ALPHASORT = @HAVE_ALPHASORT@ +HAVE_ARPA_INET_H = @HAVE_ARPA_INET_H@ +HAVE_ATOLL = @HAVE_ATOLL@ +HAVE_BTOWC = @HAVE_BTOWC@ +HAVE_C99_STDINT_H = @HAVE_C99_STDINT_H@ +HAVE_CANONICALIZE_FILE_NAME = @HAVE_CANONICALIZE_FILE_NAME@ +HAVE_CHOWN = @HAVE_CHOWN@ +HAVE_CLOSEDIR = @HAVE_CLOSEDIR@ +HAVE_COPY_FILE_RANGE = @HAVE_COPY_FILE_RANGE@ +HAVE_CRTDEFS_H = @HAVE_CRTDEFS_H@ +HAVE_DECL_DIRFD = @HAVE_DECL_DIRFD@ +HAVE_DECL_ECVT = @HAVE_DECL_ECVT@ +HAVE_DECL_ENVIRON = @HAVE_DECL_ENVIRON@ +HAVE_DECL_EXECVPE = @HAVE_DECL_EXECVPE@ +HAVE_DECL_FCHDIR = @HAVE_DECL_FCHDIR@ +HAVE_DECL_FCLOSEALL = @HAVE_DECL_FCLOSEALL@ +HAVE_DECL_FCVT = @HAVE_DECL_FCVT@ +HAVE_DECL_FDATASYNC = @HAVE_DECL_FDATASYNC@ +HAVE_DECL_FDOPENDIR = @HAVE_DECL_FDOPENDIR@ +HAVE_DECL_FPURGE = @HAVE_DECL_FPURGE@ +HAVE_DECL_FREEADDRINFO = @HAVE_DECL_FREEADDRINFO@ +HAVE_DECL_FSEEKO = @HAVE_DECL_FSEEKO@ +HAVE_DECL_FTELLO = @HAVE_DECL_FTELLO@ +HAVE_DECL_GAI_STRERROR = @HAVE_DECL_GAI_STRERROR@ +HAVE_DECL_GCVT = @HAVE_DECL_GCVT@ +HAVE_DECL_GETADDRINFO = @HAVE_DECL_GETADDRINFO@ +HAVE_DECL_GETDELIM = @HAVE_DECL_GETDELIM@ +HAVE_DECL_GETDOMAINNAME = @HAVE_DECL_GETDOMAINNAME@ +HAVE_DECL_GETLINE = @HAVE_DECL_GETLINE@ +HAVE_DECL_GETLOADAVG = @HAVE_DECL_GETLOADAVG@ +HAVE_DECL_GETLOGIN = @HAVE_DECL_GETLOGIN@ +HAVE_DECL_GETLOGIN_R = @HAVE_DECL_GETLOGIN_R@ +HAVE_DECL_GETNAMEINFO = @HAVE_DECL_GETNAMEINFO@ +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_INITSTATE = @HAVE_DECL_INITSTATE@ +HAVE_DECL_LOCALTIME_R = @HAVE_DECL_LOCALTIME_R@ +HAVE_DECL_MEMMEM = @HAVE_DECL_MEMMEM@ +HAVE_DECL_MEMRCHR = @HAVE_DECL_MEMRCHR@ +HAVE_DECL_OBSTACK_PRINTF = @HAVE_DECL_OBSTACK_PRINTF@ +HAVE_DECL_SETENV = @HAVE_DECL_SETENV@ +HAVE_DECL_SETHOSTNAME = @HAVE_DECL_SETHOSTNAME@ +HAVE_DECL_SETSTATE = @HAVE_DECL_SETSTATE@ +HAVE_DECL_SNPRINTF = @HAVE_DECL_SNPRINTF@ +HAVE_DECL_STRDUP = @HAVE_DECL_STRDUP@ +HAVE_DECL_STRERROR_R = @HAVE_DECL_STRERROR_R@ +HAVE_DECL_STRNCASECMP = @HAVE_DECL_STRNCASECMP@ +HAVE_DECL_STRNDUP = @HAVE_DECL_STRNDUP@ +HAVE_DECL_STRNLEN = @HAVE_DECL_STRNLEN@ +HAVE_DECL_STRSIGNAL = @HAVE_DECL_STRSIGNAL@ +HAVE_DECL_STRTOIMAX = @HAVE_DECL_STRTOIMAX@ +HAVE_DECL_STRTOK_R = @HAVE_DECL_STRTOK_R@ +HAVE_DECL_STRTOUMAX = @HAVE_DECL_STRTOUMAX@ +HAVE_DECL_TRUNCATE = @HAVE_DECL_TRUNCATE@ +HAVE_DECL_TTYNAME_R = @HAVE_DECL_TTYNAME_R@ +HAVE_DECL_UNSETENV = @HAVE_DECL_UNSETENV@ +HAVE_DECL_VSNPRINTF = @HAVE_DECL_VSNPRINTF@ +HAVE_DECL_WCSDUP = @HAVE_DECL_WCSDUP@ +HAVE_DECL_WCTOB = @HAVE_DECL_WCTOB@ +HAVE_DECL_WCWIDTH = @HAVE_DECL_WCWIDTH@ +HAVE_DIRENT_H = @HAVE_DIRENT_H@ +HAVE_DPRINTF = @HAVE_DPRINTF@ +HAVE_DUP3 = @HAVE_DUP3@ +HAVE_DUPLOCALE = @HAVE_DUPLOCALE@ +HAVE_EUIDACCESS = @HAVE_EUIDACCESS@ +HAVE_EXECVPE = @HAVE_EXECVPE@ +HAVE_EXPLICIT_BZERO = @HAVE_EXPLICIT_BZERO@ +HAVE_FACCESSAT = @HAVE_FACCESSAT@ +HAVE_FCHDIR = @HAVE_FCHDIR@ +HAVE_FCHMODAT = @HAVE_FCHMODAT@ +HAVE_FCHOWNAT = @HAVE_FCHOWNAT@ +HAVE_FCNTL = @HAVE_FCNTL@ +HAVE_FDATASYNC = @HAVE_FDATASYNC@ +HAVE_FDOPENDIR = @HAVE_FDOPENDIR@ +HAVE_FEATURES_H = @HAVE_FEATURES_H@ +HAVE_FFS = @HAVE_FFS@ +HAVE_FFSL = @HAVE_FFSL@ +HAVE_FFSLL = @HAVE_FFSLL@ +HAVE_FLOCK = @HAVE_FLOCK@ +HAVE_FNMATCH = @HAVE_FNMATCH@ +HAVE_FNMATCH_H = @HAVE_FNMATCH_H@ +HAVE_FREELOCALE = @HAVE_FREELOCALE@ +HAVE_FSEEKO = @HAVE_FSEEKO@ +HAVE_FSTATAT = @HAVE_FSTATAT@ +HAVE_FSYNC = @HAVE_FSYNC@ +HAVE_FTELLO = @HAVE_FTELLO@ +HAVE_FTRUNCATE = @HAVE_FTRUNCATE@ +HAVE_FUTIMENS = @HAVE_FUTIMENS@ +HAVE_GETDTABLESIZE = @HAVE_GETDTABLESIZE@ +HAVE_GETENTROPY = @HAVE_GETENTROPY@ +HAVE_GETGROUPS = @HAVE_GETGROUPS@ +HAVE_GETHOSTNAME = @HAVE_GETHOSTNAME@ +HAVE_GETLOGIN = @HAVE_GETLOGIN@ +HAVE_GETOPT_H = @HAVE_GETOPT_H@ +HAVE_GETPAGESIZE = @HAVE_GETPAGESIZE@ +HAVE_GETPASS = @HAVE_GETPASS@ +HAVE_GETRANDOM = @HAVE_GETRANDOM@ +HAVE_GETSUBOPT = @HAVE_GETSUBOPT@ +HAVE_GETTIMEOFDAY = @HAVE_GETTIMEOFDAY@ +HAVE_GETUMASK = @HAVE_GETUMASK@ +HAVE_GRANTPT = @HAVE_GRANTPT@ +HAVE_GROUP_MEMBER = @HAVE_GROUP_MEMBER@ +HAVE_IMAXDIV_T = @HAVE_IMAXDIV_T@ +HAVE_INITSTATE = @HAVE_INITSTATE@ +HAVE_INTTYPES_H = @HAVE_INTTYPES_H@ +HAVE_ISBLANK = @HAVE_ISBLANK@ +HAVE_ISWBLANK = @HAVE_ISWBLANK@ +HAVE_ISWCNTRL = @HAVE_ISWCNTRL@ +HAVE_LANGINFO_ALTMON = @HAVE_LANGINFO_ALTMON@ +HAVE_LANGINFO_CODESET = @HAVE_LANGINFO_CODESET@ +HAVE_LANGINFO_ERA = @HAVE_LANGINFO_ERA@ +HAVE_LANGINFO_H = @HAVE_LANGINFO_H@ +HAVE_LANGINFO_T_FMT_AMPM = @HAVE_LANGINFO_T_FMT_AMPM@ +HAVE_LANGINFO_YESEXPR = @HAVE_LANGINFO_YESEXPR@ +HAVE_LCHMOD = @HAVE_LCHMOD@ +HAVE_LCHOWN = @HAVE_LCHOWN@ +HAVE_LIBGNUTLS = @HAVE_LIBGNUTLS@ +HAVE_LIBSSL = @HAVE_LIBSSL@ +HAVE_LIBUNISTRING = @HAVE_LIBUNISTRING@ +HAVE_LINK = @HAVE_LINK@ +HAVE_LINKAT = @HAVE_LINKAT@ +HAVE_LSTAT = @HAVE_LSTAT@ +HAVE_MAX_ALIGN_T = @HAVE_MAX_ALIGN_T@ +HAVE_MBRLEN = @HAVE_MBRLEN@ +HAVE_MBRTOWC = @HAVE_MBRTOWC@ +HAVE_MBSINIT = @HAVE_MBSINIT@ +HAVE_MBSLEN = @HAVE_MBSLEN@ +HAVE_MBSNRTOWCS = @HAVE_MBSNRTOWCS@ +HAVE_MBSRTOWCS = @HAVE_MBSRTOWCS@ +HAVE_MBTOWC = @HAVE_MBTOWC@ +HAVE_MEMPCPY = @HAVE_MEMPCPY@ +HAVE_MKDIRAT = @HAVE_MKDIRAT@ +HAVE_MKDTEMP = @HAVE_MKDTEMP@ +HAVE_MKFIFO = @HAVE_MKFIFO@ +HAVE_MKFIFOAT = @HAVE_MKFIFOAT@ +HAVE_MKNOD = @HAVE_MKNOD@ +HAVE_MKNODAT = @HAVE_MKNODAT@ +HAVE_MKOSTEMP = @HAVE_MKOSTEMP@ +HAVE_MKOSTEMPS = @HAVE_MKOSTEMPS@ +HAVE_MKSTEMP = @HAVE_MKSTEMP@ +HAVE_MKSTEMPS = @HAVE_MKSTEMPS@ +HAVE_MSVC_INVALID_PARAMETER_HANDLER = @HAVE_MSVC_INVALID_PARAMETER_HANDLER@ +HAVE_NANOSLEEP = @HAVE_NANOSLEEP@ +HAVE_NETDB_H = @HAVE_NETDB_H@ +HAVE_NETINET_IN_H = @HAVE_NETINET_IN_H@ +HAVE_NEWLOCALE = @HAVE_NEWLOCALE@ +HAVE_NL_LANGINFO = @HAVE_NL_LANGINFO@ +HAVE_OPENAT = @HAVE_OPENAT@ +HAVE_OPENDIR = @HAVE_OPENDIR@ +HAVE_OS_H = @HAVE_OS_H@ +HAVE_PCLOSE = @HAVE_PCLOSE@ +HAVE_PIPE = @HAVE_PIPE@ +HAVE_PIPE2 = @HAVE_PIPE2@ +HAVE_POPEN = @HAVE_POPEN@ +HAVE_POSIX_MEMALIGN = @HAVE_POSIX_MEMALIGN@ +HAVE_POSIX_OPENPT = @HAVE_POSIX_OPENPT@ +HAVE_POSIX_SIGNALBLOCKING = @HAVE_POSIX_SIGNALBLOCKING@ +HAVE_POSIX_SPAWN = @HAVE_POSIX_SPAWN@ +HAVE_POSIX_SPAWNATTR_T = @HAVE_POSIX_SPAWNATTR_T@ +HAVE_POSIX_SPAWN_FILE_ACTIONS_ADDCHDIR = @HAVE_POSIX_SPAWN_FILE_ACTIONS_ADDCHDIR@ +HAVE_POSIX_SPAWN_FILE_ACTIONS_ADDFCHDIR = @HAVE_POSIX_SPAWN_FILE_ACTIONS_ADDFCHDIR@ +HAVE_POSIX_SPAWN_FILE_ACTIONS_T = @HAVE_POSIX_SPAWN_FILE_ACTIONS_T@ +HAVE_PREAD = @HAVE_PREAD@ +HAVE_PSELECT = @HAVE_PSELECT@ +HAVE_PTHREAD_SIGMASK = @HAVE_PTHREAD_SIGMASK@ +HAVE_PTSNAME = @HAVE_PTSNAME@ +HAVE_PTSNAME_R = @HAVE_PTSNAME_R@ +HAVE_PWRITE = @HAVE_PWRITE@ +HAVE_QSORT_R = @HAVE_QSORT_R@ +HAVE_RAISE = @HAVE_RAISE@ +HAVE_RANDOM = @HAVE_RANDOM@ +HAVE_RANDOM_H = @HAVE_RANDOM_H@ +HAVE_RANDOM_R = @HAVE_RANDOM_R@ +HAVE_RAWMEMCHR = @HAVE_RAWMEMCHR@ +HAVE_READDIR = @HAVE_READDIR@ +HAVE_READLINK = @HAVE_READLINK@ +HAVE_READLINKAT = @HAVE_READLINKAT@ +HAVE_REALLOCARRAY = @HAVE_REALLOCARRAY@ +HAVE_REALPATH = @HAVE_REALPATH@ +HAVE_RENAMEAT = @HAVE_RENAMEAT@ +HAVE_REWINDDIR = @HAVE_REWINDDIR@ +HAVE_RPMATCH = @HAVE_RPMATCH@ +HAVE_SA_FAMILY_T = @HAVE_SA_FAMILY_T@ +HAVE_SCANDIR = @HAVE_SCANDIR@ +HAVE_SCHED_H = @HAVE_SCHED_H@ +HAVE_SCHED_YIELD = @HAVE_SCHED_YIELD@ +HAVE_SECURE_GETENV = @HAVE_SECURE_GETENV@ +HAVE_SETENV = @HAVE_SETENV@ +HAVE_SETHOSTNAME = @HAVE_SETHOSTNAME@ +HAVE_SETSTATE = @HAVE_SETSTATE@ +HAVE_SIGABBREV_NP = @HAVE_SIGABBREV_NP@ +HAVE_SIGACTION = @HAVE_SIGACTION@ +HAVE_SIGDESCR_NP = @HAVE_SIGDESCR_NP@ +HAVE_SIGHANDLER_T = @HAVE_SIGHANDLER_T@ +HAVE_SIGINFO_T = @HAVE_SIGINFO_T@ +HAVE_SIGNED_SIG_ATOMIC_T = @HAVE_SIGNED_SIG_ATOMIC_T@ +HAVE_SIGNED_WCHAR_T = @HAVE_SIGNED_WCHAR_T@ +HAVE_SIGNED_WINT_T = @HAVE_SIGNED_WINT_T@ +HAVE_SIGSET_T = @HAVE_SIGSET_T@ +HAVE_SLEEP = @HAVE_SLEEP@ +HAVE_SPAWN_H = @HAVE_SPAWN_H@ +HAVE_STDINT_H = @HAVE_STDINT_H@ +HAVE_STPCPY = @HAVE_STPCPY@ +HAVE_STPNCPY = @HAVE_STPNCPY@ +HAVE_STRCASECMP = @HAVE_STRCASECMP@ +HAVE_STRCASESTR = @HAVE_STRCASESTR@ +HAVE_STRCHRNUL = @HAVE_STRCHRNUL@ +HAVE_STRERRORNAME_NP = @HAVE_STRERRORNAME_NP@ +HAVE_STRINGS_H = @HAVE_STRINGS_H@ +HAVE_STRPBRK = @HAVE_STRPBRK@ +HAVE_STRPTIME = @HAVE_STRPTIME@ +HAVE_STRSEP = @HAVE_STRSEP@ +HAVE_STRTOD = @HAVE_STRTOD@ +HAVE_STRTOLD = @HAVE_STRTOLD@ +HAVE_STRTOLL = @HAVE_STRTOLL@ +HAVE_STRTOULL = @HAVE_STRTOULL@ +HAVE_STRUCT_ADDRINFO = @HAVE_STRUCT_ADDRINFO@ +HAVE_STRUCT_RANDOM_DATA = @HAVE_STRUCT_RANDOM_DATA@ +HAVE_STRUCT_SCHED_PARAM = @HAVE_STRUCT_SCHED_PARAM@ +HAVE_STRUCT_SIGACTION_SA_SIGACTION = @HAVE_STRUCT_SIGACTION_SA_SIGACTION@ +HAVE_STRUCT_SOCKADDR_STORAGE = @HAVE_STRUCT_SOCKADDR_STORAGE@ +HAVE_STRUCT_SOCKADDR_STORAGE_SS_FAMILY = @HAVE_STRUCT_SOCKADDR_STORAGE_SS_FAMILY@ +HAVE_STRUCT_TIMEVAL = @HAVE_STRUCT_TIMEVAL@ +HAVE_STRVERSCMP = @HAVE_STRVERSCMP@ +HAVE_SYMLINK = @HAVE_SYMLINK@ +HAVE_SYMLINKAT = @HAVE_SYMLINKAT@ +HAVE_SYS_BITYPES_H = @HAVE_SYS_BITYPES_H@ +HAVE_SYS_CDEFS_H = @HAVE_SYS_CDEFS_H@ +HAVE_SYS_FILE_H = @HAVE_SYS_FILE_H@ +HAVE_SYS_INTTYPES_H = @HAVE_SYS_INTTYPES_H@ +HAVE_SYS_IOCTL_H = @HAVE_SYS_IOCTL_H@ +HAVE_SYS_LOADAVG_H = @HAVE_SYS_LOADAVG_H@ +HAVE_SYS_PARAM_H = @HAVE_SYS_PARAM_H@ +HAVE_SYS_RANDOM_H = @HAVE_SYS_RANDOM_H@ +HAVE_SYS_SELECT_H = @HAVE_SYS_SELECT_H@ +HAVE_SYS_SOCKET_H = @HAVE_SYS_SOCKET_H@ +HAVE_SYS_TIME_H = @HAVE_SYS_TIME_H@ +HAVE_SYS_TYPES_H = @HAVE_SYS_TYPES_H@ +HAVE_SYS_UIO_H = @HAVE_SYS_UIO_H@ +HAVE_TIMEGM = @HAVE_TIMEGM@ +HAVE_TIMEZONE_T = @HAVE_TIMEZONE_T@ +HAVE_TYPE_VOLATILE_SIG_ATOMIC_T = @HAVE_TYPE_VOLATILE_SIG_ATOMIC_T@ +HAVE_UNISTD_H = @HAVE_UNISTD_H@ +HAVE_UNLINKAT = @HAVE_UNLINKAT@ +HAVE_UNLOCKPT = @HAVE_UNLOCKPT@ +HAVE_USLEEP = @HAVE_USLEEP@ +HAVE_UTIME = @HAVE_UTIME@ +HAVE_UTIMENSAT = @HAVE_UTIMENSAT@ +HAVE_UTIME_H = @HAVE_UTIME_H@ +HAVE_VALGRIND = @HAVE_VALGRIND@ +HAVE_VASPRINTF = @HAVE_VASPRINTF@ +HAVE_VDPRINTF = @HAVE_VDPRINTF@ +HAVE_VISIBILITY = @HAVE_VISIBILITY@ +HAVE_WCHAR_H = @HAVE_WCHAR_H@ +HAVE_WCHAR_T = @HAVE_WCHAR_T@ +HAVE_WCPCPY = @HAVE_WCPCPY@ +HAVE_WCPNCPY = @HAVE_WCPNCPY@ +HAVE_WCRTOMB = @HAVE_WCRTOMB@ +HAVE_WCSCASECMP = @HAVE_WCSCASECMP@ +HAVE_WCSCAT = @HAVE_WCSCAT@ +HAVE_WCSCHR = @HAVE_WCSCHR@ +HAVE_WCSCMP = @HAVE_WCSCMP@ +HAVE_WCSCOLL = @HAVE_WCSCOLL@ +HAVE_WCSCPY = @HAVE_WCSCPY@ +HAVE_WCSCSPN = @HAVE_WCSCSPN@ +HAVE_WCSDUP = @HAVE_WCSDUP@ +HAVE_WCSFTIME = @HAVE_WCSFTIME@ +HAVE_WCSLEN = @HAVE_WCSLEN@ +HAVE_WCSNCASECMP = @HAVE_WCSNCASECMP@ +HAVE_WCSNCAT = @HAVE_WCSNCAT@ +HAVE_WCSNCMP = @HAVE_WCSNCMP@ +HAVE_WCSNCPY = @HAVE_WCSNCPY@ +HAVE_WCSNLEN = @HAVE_WCSNLEN@ +HAVE_WCSNRTOMBS = @HAVE_WCSNRTOMBS@ +HAVE_WCSPBRK = @HAVE_WCSPBRK@ +HAVE_WCSRCHR = @HAVE_WCSRCHR@ +HAVE_WCSRTOMBS = @HAVE_WCSRTOMBS@ +HAVE_WCSSPN = @HAVE_WCSSPN@ +HAVE_WCSSTR = @HAVE_WCSSTR@ +HAVE_WCSTOK = @HAVE_WCSTOK@ +HAVE_WCSWIDTH = @HAVE_WCSWIDTH@ +HAVE_WCSXFRM = @HAVE_WCSXFRM@ +HAVE_WCTRANS_T = @HAVE_WCTRANS_T@ +HAVE_WCTYPE_H = @HAVE_WCTYPE_H@ +HAVE_WCTYPE_T = @HAVE_WCTYPE_T@ +HAVE_WINSOCK2_H = @HAVE_WINSOCK2_H@ +HAVE_WINT_T = @HAVE_WINT_T@ +HAVE_WMEMCHR = @HAVE_WMEMCHR@ +HAVE_WMEMCMP = @HAVE_WMEMCMP@ +HAVE_WMEMCPY = @HAVE_WMEMCPY@ +HAVE_WMEMMOVE = @HAVE_WMEMMOVE@ +HAVE_WMEMPCPY = @HAVE_WMEMPCPY@ +HAVE_WMEMSET = @HAVE_WMEMSET@ +HAVE_WS2TCPIP_H = @HAVE_WS2TCPIP_H@ +HAVE_XLOCALE_H = @HAVE_XLOCALE_H@ +HAVE__BOOL = @HAVE__BOOL@ +HAVE__EXIT = @HAVE__EXIT@ +HOSTENT_LIB = @HOSTENT_LIB@ +ICONV_CONST = @ICONV_CONST@ +ICONV_H = @ICONV_H@ +INCLUDE_NEXT = @INCLUDE_NEXT@ +INCLUDE_NEXT_AS_FIRST_DIRECTIVE = @INCLUDE_NEXT_AS_FIRST_DIRECTIVE@ +INET_NTOP_LIB = @INET_NTOP_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@ +LDFLAGS = @LDFLAGS@ +LEX = @LEX@ +LEXLIB = @LEXLIB@ +LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ +LIBGNUTLS = @LIBGNUTLS@ +LIBGNUTLS_PREFIX = @LIBGNUTLS_PREFIX@ +LIBGNU_LIBDEPS = @LIBGNU_LIBDEPS@ +LIBGNU_LTLIBDEPS = @LIBGNU_LTLIBDEPS@ +LIBICONV = @LIBICONV@ +LIBINTL = @LIBINTL@ +LIBMULTITHREAD = @LIBMULTITHREAD@ +LIBOBJS = @LIBOBJS@ +LIBPMULTITHREAD = @LIBPMULTITHREAD@ +LIBPSL_CFLAGS = @LIBPSL_CFLAGS@ +LIBPSL_LIBS = @LIBPSL_LIBS@ +LIBPTHREAD = @LIBPTHREAD@ +LIBS = @LIBS@ +LIBSOCKET = @LIBSOCKET@ +LIBSSL = @LIBSSL@ +LIBSSL_PREFIX = @LIBSSL_PREFIX@ +LIBSTDTHREAD = @LIBSTDTHREAD@ +LIBTHREAD = @LIBTHREAD@ +LIBUNISTRING = @LIBUNISTRING@ +LIBUNISTRING_PREFIX = @LIBUNISTRING_PREFIX@ +LIBUNISTRING_UNICASE_H = @LIBUNISTRING_UNICASE_H@ +LIBUNISTRING_UNICTYPE_H = @LIBUNISTRING_UNICTYPE_H@ +LIBUNISTRING_UNINORM_H = @LIBUNISTRING_UNINORM_H@ +LIBUNISTRING_UNISTR_H = @LIBUNISTRING_UNISTR_H@ +LIBUNISTRING_UNITYPES_H = @LIBUNISTRING_UNITYPES_H@ +LIBUNISTRING_UNIWIDTH_H = @LIBUNISTRING_UNIWIDTH_H@ +LIB_CLOCK_GETTIME = @LIB_CLOCK_GETTIME@ +LIB_CRYPTO = @LIB_CRYPTO@ +LIB_FUZZING_ENGINE = @LIB_FUZZING_ENGINE@ +LIB_GETRANDOM = @LIB_GETRANDOM@ +LIB_HARD_LOCALE = @LIB_HARD_LOCALE@ +LIB_MBRTOWC = @LIB_MBRTOWC@ +LIB_NANOSLEEP = @LIB_NANOSLEEP@ +LIB_NL_LANGINFO = @LIB_NL_LANGINFO@ +LIB_POSIX_SPAWN = @LIB_POSIX_SPAWN@ +LIB_SCHED_YIELD = @LIB_SCHED_YIELD@ +LIB_SELECT = @LIB_SELECT@ +LIB_SETLOCALE_NULL = @LIB_SETLOCALE_NULL@ +LIMITS_H = @LIMITS_H@ +LOCALCHARSET_TESTS_ENVIRONMENT = @LOCALCHARSET_TESTS_ENVIRONMENT@ +LOCALE_FR = @LOCALE_FR@ +LOCALE_FR_UTF8 = @LOCALE_FR_UTF8@ +LOCALE_JA = @LOCALE_JA@ +LOCALE_ZH_CN = @LOCALE_ZH_CN@ +LTLIBGNUTLS = @LTLIBGNUTLS@ +LTLIBICONV = @LTLIBICONV@ +LTLIBINTL = @LTLIBINTL@ +LTLIBMULTITHREAD = @LTLIBMULTITHREAD@ +LTLIBOBJS = @LTLIBOBJS@ +LTLIBSSL = @LTLIBSSL@ +LTLIBTHREAD = @LTLIBTHREAD@ +LTLIBUNISTRING = @LTLIBUNISTRING@ +MAKEINFO = @MAKEINFO@ +METALINK_CFLAGS = @METALINK_CFLAGS@ +METALINK_LIBS = @METALINK_LIBS@ +MKDIR_P = @MKDIR_P@ +MSGFMT = @MSGFMT@ +MSGFMT_015 = @MSGFMT_015@ +MSGMERGE = @MSGMERGE@ +NETINET_IN_H = @NETINET_IN_H@ +NETTLE_LIBS = @NETTLE_LIBS@ +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_FNMATCH_H = @NEXT_AS_FIRST_DIRECTIVE_FNMATCH_H@ +NEXT_AS_FIRST_DIRECTIVE_GETOPT_H = @NEXT_AS_FIRST_DIRECTIVE_GETOPT_H@ +NEXT_AS_FIRST_DIRECTIVE_ICONV_H = @NEXT_AS_FIRST_DIRECTIVE_ICONV_H@ +NEXT_AS_FIRST_DIRECTIVE_INTTYPES_H = @NEXT_AS_FIRST_DIRECTIVE_INTTYPES_H@ +NEXT_AS_FIRST_DIRECTIVE_LANGINFO_H = @NEXT_AS_FIRST_DIRECTIVE_LANGINFO_H@ +NEXT_AS_FIRST_DIRECTIVE_LIMITS_H = @NEXT_AS_FIRST_DIRECTIVE_LIMITS_H@ +NEXT_AS_FIRST_DIRECTIVE_LOCALE_H = @NEXT_AS_FIRST_DIRECTIVE_LOCALE_H@ +NEXT_AS_FIRST_DIRECTIVE_NETDB_H = @NEXT_AS_FIRST_DIRECTIVE_NETDB_H@ +NEXT_AS_FIRST_DIRECTIVE_NETINET_IN_H = @NEXT_AS_FIRST_DIRECTIVE_NETINET_IN_H@ +NEXT_AS_FIRST_DIRECTIVE_SCHED_H = @NEXT_AS_FIRST_DIRECTIVE_SCHED_H@ +NEXT_AS_FIRST_DIRECTIVE_SIGNAL_H = @NEXT_AS_FIRST_DIRECTIVE_SIGNAL_H@ +NEXT_AS_FIRST_DIRECTIVE_SPAWN_H = @NEXT_AS_FIRST_DIRECTIVE_SPAWN_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_FILE_H = @NEXT_AS_FIRST_DIRECTIVE_SYS_FILE_H@ +NEXT_AS_FIRST_DIRECTIVE_SYS_IOCTL_H = @NEXT_AS_FIRST_DIRECTIVE_SYS_IOCTL_H@ +NEXT_AS_FIRST_DIRECTIVE_SYS_RANDOM_H = @NEXT_AS_FIRST_DIRECTIVE_SYS_RANDOM_H@ +NEXT_AS_FIRST_DIRECTIVE_SYS_SELECT_H = @NEXT_AS_FIRST_DIRECTIVE_SYS_SELECT_H@ +NEXT_AS_FIRST_DIRECTIVE_SYS_SOCKET_H = @NEXT_AS_FIRST_DIRECTIVE_SYS_SOCKET_H@ +NEXT_AS_FIRST_DIRECTIVE_SYS_STAT_H = @NEXT_AS_FIRST_DIRECTIVE_SYS_STAT_H@ +NEXT_AS_FIRST_DIRECTIVE_SYS_TIME_H = @NEXT_AS_FIRST_DIRECTIVE_SYS_TIME_H@ +NEXT_AS_FIRST_DIRECTIVE_SYS_TYPES_H = @NEXT_AS_FIRST_DIRECTIVE_SYS_TYPES_H@ +NEXT_AS_FIRST_DIRECTIVE_SYS_UIO_H = @NEXT_AS_FIRST_DIRECTIVE_SYS_UIO_H@ +NEXT_AS_FIRST_DIRECTIVE_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_UTIME_H = @NEXT_AS_FIRST_DIRECTIVE_UTIME_H@ +NEXT_AS_FIRST_DIRECTIVE_WCHAR_H = @NEXT_AS_FIRST_DIRECTIVE_WCHAR_H@ +NEXT_AS_FIRST_DIRECTIVE_WCTYPE_H = @NEXT_AS_FIRST_DIRECTIVE_WCTYPE_H@ +NEXT_CTYPE_H = @NEXT_CTYPE_H@ +NEXT_DIRENT_H = @NEXT_DIRENT_H@ +NEXT_ERRNO_H = @NEXT_ERRNO_H@ +NEXT_FCNTL_H = @NEXT_FCNTL_H@ +NEXT_FLOAT_H = @NEXT_FLOAT_H@ +NEXT_FNMATCH_H = @NEXT_FNMATCH_H@ +NEXT_GETOPT_H = @NEXT_GETOPT_H@ +NEXT_ICONV_H = @NEXT_ICONV_H@ +NEXT_INTTYPES_H = @NEXT_INTTYPES_H@ +NEXT_LANGINFO_H = @NEXT_LANGINFO_H@ +NEXT_LIMITS_H = @NEXT_LIMITS_H@ +NEXT_LOCALE_H = @NEXT_LOCALE_H@ +NEXT_NETDB_H = @NEXT_NETDB_H@ +NEXT_NETINET_IN_H = @NEXT_NETINET_IN_H@ +NEXT_SCHED_H = @NEXT_SCHED_H@ +NEXT_SIGNAL_H = @NEXT_SIGNAL_H@ +NEXT_SPAWN_H = @NEXT_SPAWN_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_FILE_H = @NEXT_SYS_FILE_H@ +NEXT_SYS_IOCTL_H = @NEXT_SYS_IOCTL_H@ +NEXT_SYS_RANDOM_H = @NEXT_SYS_RANDOM_H@ +NEXT_SYS_SELECT_H = @NEXT_SYS_SELECT_H@ +NEXT_SYS_SOCKET_H = @NEXT_SYS_SOCKET_H@ +NEXT_SYS_STAT_H = @NEXT_SYS_STAT_H@ +NEXT_SYS_TIME_H = @NEXT_SYS_TIME_H@ +NEXT_SYS_TYPES_H = @NEXT_SYS_TYPES_H@ +NEXT_SYS_UIO_H = @NEXT_SYS_UIO_H@ +NEXT_SYS_WAIT_H = @NEXT_SYS_WAIT_H@ +NEXT_TIME_H = @NEXT_TIME_H@ +NEXT_UNISTD_H = @NEXT_UNISTD_H@ +NEXT_UTIME_H = @NEXT_UTIME_H@ +NEXT_WCHAR_H = @NEXT_WCHAR_H@ +NEXT_WCTYPE_H = @NEXT_WCTYPE_H@ +OBJEXT = @OBJEXT@ +OPENSSL_CFLAGS = @OPENSSL_CFLAGS@ +OPENSSL_LIBS = @OPENSSL_LIBS@ +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@ +PCRE2_CFLAGS = @PCRE2_CFLAGS@ +PCRE2_LIBS = @PCRE2_LIBS@ +PCRE_CFLAGS = @PCRE_CFLAGS@ +PCRE_LIBS = @PCRE_LIBS@ +PERL = @PERL@ +PKG_CONFIG = @PKG_CONFIG@ +PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ +PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ +POD2MAN = @POD2MAN@ +POSUB = @POSUB@ +PRAGMA_COLUMNS = @PRAGMA_COLUMNS@ +PRAGMA_SYSTEM_HEADER = @PRAGMA_SYSTEM_HEADER@ +PRIPTR_PREFIX = @PRIPTR_PREFIX@ +PTHREAD_H_DEFINES_STRUCT_TIMESPEC = @PTHREAD_H_DEFINES_STRUCT_TIMESPEC@ +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_ACCESS = @REPLACE_ACCESS@ +REPLACE_ALIGNED_ALLOC = @REPLACE_ALIGNED_ALLOC@ +REPLACE_BTOWC = @REPLACE_BTOWC@ +REPLACE_CALLOC = @REPLACE_CALLOC@ +REPLACE_CANONICALIZE_FILE_NAME = @REPLACE_CANONICALIZE_FILE_NAME@ +REPLACE_CHOWN = @REPLACE_CHOWN@ +REPLACE_CLOSE = @REPLACE_CLOSE@ +REPLACE_CLOSEDIR = @REPLACE_CLOSEDIR@ +REPLACE_CREAT = @REPLACE_CREAT@ +REPLACE_CTIME = @REPLACE_CTIME@ +REPLACE_DIRFD = @REPLACE_DIRFD@ +REPLACE_DPRINTF = @REPLACE_DPRINTF@ +REPLACE_DUP = @REPLACE_DUP@ +REPLACE_DUP2 = @REPLACE_DUP2@ +REPLACE_DUPLOCALE = @REPLACE_DUPLOCALE@ +REPLACE_EXECL = @REPLACE_EXECL@ +REPLACE_EXECLE = @REPLACE_EXECLE@ +REPLACE_EXECLP = @REPLACE_EXECLP@ +REPLACE_EXECV = @REPLACE_EXECV@ +REPLACE_EXECVE = @REPLACE_EXECVE@ +REPLACE_EXECVP = @REPLACE_EXECVP@ +REPLACE_EXECVPE = @REPLACE_EXECVPE@ +REPLACE_FACCESSAT = @REPLACE_FACCESSAT@ +REPLACE_FCHMODAT = @REPLACE_FCHMODAT@ +REPLACE_FCHOWNAT = @REPLACE_FCHOWNAT@ +REPLACE_FCLOSE = @REPLACE_FCLOSE@ +REPLACE_FCNTL = @REPLACE_FCNTL@ +REPLACE_FDOPEN = @REPLACE_FDOPEN@ +REPLACE_FDOPENDIR = @REPLACE_FDOPENDIR@ +REPLACE_FFLUSH = @REPLACE_FFLUSH@ +REPLACE_FNMATCH = @REPLACE_FNMATCH@ +REPLACE_FOPEN = @REPLACE_FOPEN@ +REPLACE_FPRINTF = @REPLACE_FPRINTF@ +REPLACE_FPURGE = @REPLACE_FPURGE@ +REPLACE_FREE = @REPLACE_FREE@ +REPLACE_FREELOCALE = @REPLACE_FREELOCALE@ +REPLACE_FREOPEN = @REPLACE_FREOPEN@ +REPLACE_FSEEK = @REPLACE_FSEEK@ +REPLACE_FSEEKO = @REPLACE_FSEEKO@ +REPLACE_FSTAT = @REPLACE_FSTAT@ +REPLACE_FSTATAT = @REPLACE_FSTATAT@ +REPLACE_FTELL = @REPLACE_FTELL@ +REPLACE_FTELLO = @REPLACE_FTELLO@ +REPLACE_FTRUNCATE = @REPLACE_FTRUNCATE@ +REPLACE_FUTIMENS = @REPLACE_FUTIMENS@ +REPLACE_GAI_STRERROR = @REPLACE_GAI_STRERROR@ +REPLACE_GETADDRINFO = @REPLACE_GETADDRINFO@ +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_GETPASS = @REPLACE_GETPASS@ +REPLACE_GETRANDOM = @REPLACE_GETRANDOM@ +REPLACE_GETTIMEOFDAY = @REPLACE_GETTIMEOFDAY@ +REPLACE_GMTIME = @REPLACE_GMTIME@ +REPLACE_ICONV = @REPLACE_ICONV@ +REPLACE_ICONV_OPEN = @REPLACE_ICONV_OPEN@ +REPLACE_ICONV_UTF = @REPLACE_ICONV_UTF@ +REPLACE_INET_NTOP = @REPLACE_INET_NTOP@ +REPLACE_INET_PTON = @REPLACE_INET_PTON@ +REPLACE_INITSTATE = @REPLACE_INITSTATE@ +REPLACE_IOCTL = @REPLACE_IOCTL@ +REPLACE_ISATTY = @REPLACE_ISATTY@ +REPLACE_ISWBLANK = @REPLACE_ISWBLANK@ +REPLACE_ISWCNTRL = @REPLACE_ISWCNTRL@ +REPLACE_ISWDIGIT = @REPLACE_ISWDIGIT@ +REPLACE_ISWXDIGIT = @REPLACE_ISWXDIGIT@ +REPLACE_ITOLD = @REPLACE_ITOLD@ +REPLACE_LCHOWN = @REPLACE_LCHOWN@ +REPLACE_LINK = @REPLACE_LINK@ +REPLACE_LINKAT = @REPLACE_LINKAT@ +REPLACE_LOCALECONV = @REPLACE_LOCALECONV@ +REPLACE_LOCALTIME = @REPLACE_LOCALTIME@ +REPLACE_LOCALTIME_R = @REPLACE_LOCALTIME_R@ +REPLACE_LSEEK = @REPLACE_LSEEK@ +REPLACE_LSTAT = @REPLACE_LSTAT@ +REPLACE_MALLOC = @REPLACE_MALLOC@ +REPLACE_MBRLEN = @REPLACE_MBRLEN@ +REPLACE_MBRTOWC = @REPLACE_MBRTOWC@ +REPLACE_MBSINIT = @REPLACE_MBSINIT@ +REPLACE_MBSNRTOWCS = @REPLACE_MBSNRTOWCS@ +REPLACE_MBSRTOWCS = @REPLACE_MBSRTOWCS@ +REPLACE_MBSTATE_T = @REPLACE_MBSTATE_T@ +REPLACE_MBTOWC = @REPLACE_MBTOWC@ +REPLACE_MEMCHR = @REPLACE_MEMCHR@ +REPLACE_MEMMEM = @REPLACE_MEMMEM@ +REPLACE_MKDIR = @REPLACE_MKDIR@ +REPLACE_MKFIFO = @REPLACE_MKFIFO@ +REPLACE_MKNOD = @REPLACE_MKNOD@ +REPLACE_MKSTEMP = @REPLACE_MKSTEMP@ +REPLACE_MKTIME = @REPLACE_MKTIME@ +REPLACE_NANOSLEEP = @REPLACE_NANOSLEEP@ +REPLACE_NEWLOCALE = @REPLACE_NEWLOCALE@ +REPLACE_NL_LANGINFO = @REPLACE_NL_LANGINFO@ +REPLACE_NULL = @REPLACE_NULL@ +REPLACE_OBSTACK_PRINTF = @REPLACE_OBSTACK_PRINTF@ +REPLACE_OPEN = @REPLACE_OPEN@ +REPLACE_OPENAT = @REPLACE_OPENAT@ +REPLACE_OPENDIR = @REPLACE_OPENDIR@ +REPLACE_PERROR = @REPLACE_PERROR@ +REPLACE_POPEN = @REPLACE_POPEN@ +REPLACE_POSIX_MEMALIGN = @REPLACE_POSIX_MEMALIGN@ +REPLACE_POSIX_SPAWN = @REPLACE_POSIX_SPAWN@ +REPLACE_POSIX_SPAWN_FILE_ACTIONS_ADDCHDIR = @REPLACE_POSIX_SPAWN_FILE_ACTIONS_ADDCHDIR@ +REPLACE_POSIX_SPAWN_FILE_ACTIONS_ADDCLOSE = @REPLACE_POSIX_SPAWN_FILE_ACTIONS_ADDCLOSE@ +REPLACE_POSIX_SPAWN_FILE_ACTIONS_ADDDUP2 = @REPLACE_POSIX_SPAWN_FILE_ACTIONS_ADDDUP2@ +REPLACE_POSIX_SPAWN_FILE_ACTIONS_ADDFCHDIR = @REPLACE_POSIX_SPAWN_FILE_ACTIONS_ADDFCHDIR@ +REPLACE_POSIX_SPAWN_FILE_ACTIONS_ADDOPEN = @REPLACE_POSIX_SPAWN_FILE_ACTIONS_ADDOPEN@ +REPLACE_PREAD = @REPLACE_PREAD@ +REPLACE_PRINTF = @REPLACE_PRINTF@ +REPLACE_PSELECT = @REPLACE_PSELECT@ +REPLACE_PTHREAD_SIGMASK = @REPLACE_PTHREAD_SIGMASK@ +REPLACE_PTSNAME = @REPLACE_PTSNAME@ +REPLACE_PTSNAME_R = @REPLACE_PTSNAME_R@ +REPLACE_PUTENV = @REPLACE_PUTENV@ +REPLACE_PWRITE = @REPLACE_PWRITE@ +REPLACE_QSORT_R = @REPLACE_QSORT_R@ +REPLACE_RAISE = @REPLACE_RAISE@ +REPLACE_RANDOM = @REPLACE_RANDOM@ +REPLACE_RANDOM_R = @REPLACE_RANDOM_R@ +REPLACE_READ = @REPLACE_READ@ +REPLACE_READLINK = @REPLACE_READLINK@ +REPLACE_READLINKAT = @REPLACE_READLINKAT@ +REPLACE_REALLOC = @REPLACE_REALLOC@ +REPLACE_REALPATH = @REPLACE_REALPATH@ +REPLACE_REMOVE = @REPLACE_REMOVE@ +REPLACE_RENAME = @REPLACE_RENAME@ +REPLACE_RENAMEAT = @REPLACE_RENAMEAT@ +REPLACE_RMDIR = @REPLACE_RMDIR@ +REPLACE_SCHED_YIELD = @REPLACE_SCHED_YIELD@ +REPLACE_SELECT = @REPLACE_SELECT@ +REPLACE_SETENV = @REPLACE_SETENV@ +REPLACE_SETLOCALE = @REPLACE_SETLOCALE@ +REPLACE_SETSTATE = @REPLACE_SETSTATE@ +REPLACE_SLEEP = @REPLACE_SLEEP@ +REPLACE_SNPRINTF = @REPLACE_SNPRINTF@ +REPLACE_SPRINTF = @REPLACE_SPRINTF@ +REPLACE_STAT = @REPLACE_STAT@ +REPLACE_STDIO_READ_FUNCS = @REPLACE_STDIO_READ_FUNCS@ +REPLACE_STDIO_WRITE_FUNCS = @REPLACE_STDIO_WRITE_FUNCS@ +REPLACE_STPNCPY = @REPLACE_STPNCPY@ +REPLACE_STRCASESTR = @REPLACE_STRCASESTR@ +REPLACE_STRCHRNUL = @REPLACE_STRCHRNUL@ +REPLACE_STRDUP = @REPLACE_STRDUP@ +REPLACE_STRERROR = @REPLACE_STRERROR@ +REPLACE_STRERRORNAME_NP = @REPLACE_STRERRORNAME_NP@ +REPLACE_STRERROR_R = @REPLACE_STRERROR_R@ +REPLACE_STRFTIME = @REPLACE_STRFTIME@ +REPLACE_STRNCAT = @REPLACE_STRNCAT@ +REPLACE_STRNDUP = @REPLACE_STRNDUP@ +REPLACE_STRNLEN = @REPLACE_STRNLEN@ +REPLACE_STRSIGNAL = @REPLACE_STRSIGNAL@ +REPLACE_STRSTR = @REPLACE_STRSTR@ +REPLACE_STRTOD = @REPLACE_STRTOD@ +REPLACE_STRTOIMAX = @REPLACE_STRTOIMAX@ +REPLACE_STRTOK_R = @REPLACE_STRTOK_R@ +REPLACE_STRTOLD = @REPLACE_STRTOLD@ +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_TRUNCATE = @REPLACE_TRUNCATE@ +REPLACE_TTYNAME_R = @REPLACE_TTYNAME_R@ +REPLACE_TZSET = @REPLACE_TZSET@ +REPLACE_UNLINK = @REPLACE_UNLINK@ +REPLACE_UNLINKAT = @REPLACE_UNLINKAT@ +REPLACE_UNSETENV = @REPLACE_UNSETENV@ +REPLACE_USLEEP = @REPLACE_USLEEP@ +REPLACE_UTIME = @REPLACE_UTIME@ +REPLACE_UTIMENSAT = @REPLACE_UTIMENSAT@ +REPLACE_VASPRINTF = @REPLACE_VASPRINTF@ +REPLACE_VDPRINTF = @REPLACE_VDPRINTF@ +REPLACE_VFPRINTF = @REPLACE_VFPRINTF@ +REPLACE_VPRINTF = @REPLACE_VPRINTF@ +REPLACE_VSNPRINTF = @REPLACE_VSNPRINTF@ +REPLACE_VSPRINTF = @REPLACE_VSPRINTF@ +REPLACE_WCRTOMB = @REPLACE_WCRTOMB@ +REPLACE_WCSFTIME = @REPLACE_WCSFTIME@ +REPLACE_WCSNRTOMBS = @REPLACE_WCSNRTOMBS@ +REPLACE_WCSRTOMBS = @REPLACE_WCSRTOMBS@ +REPLACE_WCSTOK = @REPLACE_WCSTOK@ +REPLACE_WCSWIDTH = @REPLACE_WCSWIDTH@ +REPLACE_WCTOB = @REPLACE_WCTOB@ +REPLACE_WCTOMB = @REPLACE_WCTOMB@ +REPLACE_WCWIDTH = @REPLACE_WCWIDTH@ +REPLACE_WRITE = @REPLACE_WRITE@ +SED = @SED@ +SERVENT_LIB = @SERVENT_LIB@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +SIG_ATOMIC_T_SUFFIX = @SIG_ATOMIC_T_SUFFIX@ +SIZE_T_SUFFIX = @SIZE_T_SUFFIX@ +STDALIGN_H = @STDALIGN_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@ +UINT32_MAX_LT_UINTMAX_MAX = @UINT32_MAX_LT_UINTMAX_MAX@ +UINT64_MAX_EQ_ULONG_MAX = @UINT64_MAX_EQ_ULONG_MAX@ +UNDEFINE_STRTOK_R = @UNDEFINE_STRTOK_R@ +UNISTD_H_DEFINES_STRUCT_TIMESPEC = @UNISTD_H_DEFINES_STRUCT_TIMESPEC@ +UNISTD_H_HAVE_SYS_RANDOM_H = @UNISTD_H_HAVE_SYS_RANDOM_H@ +UNISTD_H_HAVE_WINSOCK2_H = @UNISTD_H_HAVE_WINSOCK2_H@ +UNISTD_H_HAVE_WINSOCK2_H_AND_USE_SOCKETS = @UNISTD_H_HAVE_WINSOCK2_H_AND_USE_SOCKETS@ +USE_NLS = @USE_NLS@ +UUID_CFLAGS = @UUID_CFLAGS@ +UUID_LIBS = @UUID_LIBS@ +VALGRIND_TESTS = @VALGRIND_TESTS@ +VERSION = @VERSION@ +WARN_CFLAGS = @WARN_CFLAGS@ +WCHAR_T_SUFFIX = @WCHAR_T_SUFFIX@ +WINDOWS_64_BIT_OFF_T = @WINDOWS_64_BIT_OFF_T@ +WINDOWS_64_BIT_ST_SIZE = @WINDOWS_64_BIT_ST_SIZE@ +WINDOWS_STAT_INODES = @WINDOWS_STAT_INODES@ +WINDOWS_STAT_TIMESPEC = @WINDOWS_STAT_TIMESPEC@ +WINT_T_SUFFIX = @WINT_T_SUFFIX@ +XGETTEXT = @XGETTEXT@ +XGETTEXT_015 = @XGETTEXT_015@ +XGETTEXT_EXTRA_OPTIONS = @XGETTEXT_EXTRA_OPTIONS@ +ZLIB_CFLAGS = @ZLIB_CFLAGS@ +ZLIB_LIBS = @ZLIB_LIBS@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_CC = @ac_ct_CC@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +gl_LIBOBJS = @gl_LIBOBJS@ +gl_LTLIBOBJS = @gl_LTLIBOBJS@ +gltests_LIBOBJS = @gltests_LIBOBJS@ +gltests_LTLIBOBJS = @gltests_LTLIBOBJS@ +gltests_WITNESS = @gltests_WITNESS@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +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@ +@IRI_IS_ENABLED_TRUE@IRI_OBJ = iri.c +@METALINK_IS_ENABLED_TRUE@METALINK_OBJ = metalink.c +@WITH_XATTR_TRUE@XATTR_OBJ = xattr.c +EXTRA_DIST = css.l css.c css_.c build_info.c.in build_info.c +wget_SOURCES = connect.c convert.c cookies.c ftp.c \ + css_.c css-url.c \ + ftp-basic.c ftp-ls.c hash.c host.c hsts.c html-parse.c html-url.c \ + http.c init.c log.c main.c netrc.c progress.c ptimer.c \ + recur.c res.c retr.c spider.c url.c warc.c $(XATTR_OBJ) \ + utils.c exits.c build_info.c $(IRI_OBJ) $(METALINK_OBJ) \ + css-url.h css-tokens.h connect.h convert.h cookies.h \ + ftp.h hash.h host.h hsts.h html-parse.h html-url.h \ + http.h http-ntlm.h init.h log.h mswindows.h netrc.h \ + options.h progress.h ptimer.h recur.h res.h retr.h \ + spider.h ssl.h sysdep.h url.h warc.h utils.h wget.h iri.h \ + exits.h version.h metalink.h xattr.h + +nodist_wget_SOURCES = version.c +EXTRA_wget_SOURCES = iri.c +LDADD = $(CODE_COVERAGE_LIBS) $(LIBOBJS) ../lib/libgnu.a $(GETADDRINFO_LIB) $(HOSTENT_LIB)\ + $(INET_NTOP_LIB) $(LIBSOCKET) $(LIB_CLOCK_GETTIME) $(LIB_CRYPTO)\ + $(LIB_NANOSLEEP) $(LIB_POSIX_SPAWN) $(LIB_SELECT) $(LIBICONV) $(LIBINTL)\ + $(LIBTHREAD) $(LIBUNISTRING) $(SERVENT_LIB) + +AM_CPPFLAGS = -I$(top_builddir)/lib -I$(top_srcdir)/lib $(CODE_COVERAGE_CPPFLAGS) +AM_CFLAGS = $(WERROR_CFLAGS) $(WARN_CFLAGS) $(CODE_COVERAGE_CFLAGS) +ESCAPEQUOTE = sed -e 's/[\\"]/\\&/g' -e 's/\\"/"/' -e 's/\\";$$/";/' +check_LIBRARIES = libunittest.a +libunittest_a_SOURCES = $(wget_SOURCES) build_info.c +nodist_libunittest_a_SOURCES = version.c +libunittest_a_CPPFLAGS = -DTESTING "-I$(top_builddir)/lib" "-I$(top_srcdir)/lib" $(CODE_COVERAGE_CPPLAGS) +libunittest_a_LIBADD = $(LIBOBJS) +CLEANFILES = *~ *.bak core core.[0-9]* build_info.c version.c +all: config.h + $(MAKE) $(AM_MAKEFLAGS) all-am + +.SUFFIXES: +.SUFFIXES: .c .o .obj +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu src/Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +config.h: stamp-h1 + @test -f $@ || rm -f stamp-h1 + @test -f $@ || $(MAKE) $(AM_MAKEFLAGS) stamp-h1 + +stamp-h1: $(srcdir)/config.h.in $(top_builddir)/config.status + @rm -f stamp-h1 + cd $(top_builddir) && $(SHELL) ./config.status src/config.h +$(srcdir)/config.h.in: $(am__configure_deps) + ($(am__cd) $(top_srcdir) && $(AUTOHEADER)) + rm -f stamp-h1 + touch $@ + +distclean-hdr: + -rm -f config.h stamp-h1 +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) + +clean-checkLIBRARIES: + -test -z "$(check_LIBRARIES)" || rm -f $(check_LIBRARIES) + +libunittest.a: $(libunittest_a_OBJECTS) $(libunittest_a_DEPENDENCIES) $(EXTRA_libunittest_a_DEPENDENCIES) + $(AM_V_at)-rm -f libunittest.a + $(AM_V_AR)$(libunittest_a_AR) libunittest.a $(libunittest_a_OBJECTS) $(libunittest_a_LIBADD) + $(AM_V_at)$(RANLIB) libunittest.a + +wget$(EXEEXT): $(wget_OBJECTS) $(wget_DEPENDENCIES) $(EXTRA_wget_DEPENDENCIES) + @rm -f wget$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(wget_OBJECTS) $(wget_LDADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/ftp-opie.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/gnutls.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/http-ntlm.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/mswindows.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/openssl.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/build_info.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/connect.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/convert.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cookies.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/css-url.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/css_.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/exits.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ftp-basic.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ftp-ls.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ftp.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hash.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/host.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hsts.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/html-parse.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/html-url.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/http.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/init.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/iri.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libunittest_a-build_info.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libunittest_a-connect.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libunittest_a-convert.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libunittest_a-cookies.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libunittest_a-css-url.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libunittest_a-css_.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libunittest_a-exits.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libunittest_a-ftp-basic.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libunittest_a-ftp-ls.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libunittest_a-ftp.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libunittest_a-hash.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libunittest_a-host.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libunittest_a-hsts.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libunittest_a-html-parse.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libunittest_a-html-url.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libunittest_a-http.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libunittest_a-init.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libunittest_a-iri.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libunittest_a-log.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libunittest_a-main.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libunittest_a-metalink.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libunittest_a-netrc.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libunittest_a-progress.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libunittest_a-ptimer.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libunittest_a-recur.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libunittest_a-res.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libunittest_a-retr.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libunittest_a-spider.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libunittest_a-url.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libunittest_a-utils.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libunittest_a-version.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libunittest_a-warc.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libunittest_a-xattr.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/log.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/main.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/metalink.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/netrc.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/progress.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ptimer.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/recur.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/res.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/retr.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/spider.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/url.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/utils.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/version.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/warc.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xattr.Po@am__quote@ # am--include-marker + +$(am__depfiles_remade): + @$(MKDIR_P) $(@D) + @echo '# dummy' >$@-t && $(am__mv) $@-t $@ + +am--depfiles: $(am__depfiles_remade) + +.c.o: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.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)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.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) '$<'` + +libunittest_a-connect.o: connect.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libunittest_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libunittest_a-connect.o -MD -MP -MF $(DEPDIR)/libunittest_a-connect.Tpo -c -o libunittest_a-connect.o `test -f 'connect.c' || echo '$(srcdir)/'`connect.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libunittest_a-connect.Tpo $(DEPDIR)/libunittest_a-connect.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='connect.c' object='libunittest_a-connect.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libunittest_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libunittest_a-connect.o `test -f 'connect.c' || echo '$(srcdir)/'`connect.c + +libunittest_a-connect.obj: connect.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libunittest_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libunittest_a-connect.obj -MD -MP -MF $(DEPDIR)/libunittest_a-connect.Tpo -c -o libunittest_a-connect.obj `if test -f 'connect.c'; then $(CYGPATH_W) 'connect.c'; else $(CYGPATH_W) '$(srcdir)/connect.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libunittest_a-connect.Tpo $(DEPDIR)/libunittest_a-connect.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='connect.c' object='libunittest_a-connect.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libunittest_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libunittest_a-connect.obj `if test -f 'connect.c'; then $(CYGPATH_W) 'connect.c'; else $(CYGPATH_W) '$(srcdir)/connect.c'; fi` + +libunittest_a-convert.o: convert.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libunittest_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libunittest_a-convert.o -MD -MP -MF $(DEPDIR)/libunittest_a-convert.Tpo -c -o libunittest_a-convert.o `test -f 'convert.c' || echo '$(srcdir)/'`convert.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libunittest_a-convert.Tpo $(DEPDIR)/libunittest_a-convert.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='convert.c' object='libunittest_a-convert.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libunittest_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libunittest_a-convert.o `test -f 'convert.c' || echo '$(srcdir)/'`convert.c + +libunittest_a-convert.obj: convert.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libunittest_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libunittest_a-convert.obj -MD -MP -MF $(DEPDIR)/libunittest_a-convert.Tpo -c -o libunittest_a-convert.obj `if test -f 'convert.c'; then $(CYGPATH_W) 'convert.c'; else $(CYGPATH_W) '$(srcdir)/convert.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libunittest_a-convert.Tpo $(DEPDIR)/libunittest_a-convert.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='convert.c' object='libunittest_a-convert.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libunittest_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libunittest_a-convert.obj `if test -f 'convert.c'; then $(CYGPATH_W) 'convert.c'; else $(CYGPATH_W) '$(srcdir)/convert.c'; fi` + +libunittest_a-cookies.o: cookies.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libunittest_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libunittest_a-cookies.o -MD -MP -MF $(DEPDIR)/libunittest_a-cookies.Tpo -c -o libunittest_a-cookies.o `test -f 'cookies.c' || echo '$(srcdir)/'`cookies.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libunittest_a-cookies.Tpo $(DEPDIR)/libunittest_a-cookies.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cookies.c' object='libunittest_a-cookies.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libunittest_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libunittest_a-cookies.o `test -f 'cookies.c' || echo '$(srcdir)/'`cookies.c + +libunittest_a-cookies.obj: cookies.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libunittest_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libunittest_a-cookies.obj -MD -MP -MF $(DEPDIR)/libunittest_a-cookies.Tpo -c -o libunittest_a-cookies.obj `if test -f 'cookies.c'; then $(CYGPATH_W) 'cookies.c'; else $(CYGPATH_W) '$(srcdir)/cookies.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libunittest_a-cookies.Tpo $(DEPDIR)/libunittest_a-cookies.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cookies.c' object='libunittest_a-cookies.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libunittest_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libunittest_a-cookies.obj `if test -f 'cookies.c'; then $(CYGPATH_W) 'cookies.c'; else $(CYGPATH_W) '$(srcdir)/cookies.c'; fi` + +libunittest_a-ftp.o: ftp.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libunittest_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libunittest_a-ftp.o -MD -MP -MF $(DEPDIR)/libunittest_a-ftp.Tpo -c -o libunittest_a-ftp.o `test -f 'ftp.c' || echo '$(srcdir)/'`ftp.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libunittest_a-ftp.Tpo $(DEPDIR)/libunittest_a-ftp.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ftp.c' object='libunittest_a-ftp.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libunittest_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libunittest_a-ftp.o `test -f 'ftp.c' || echo '$(srcdir)/'`ftp.c + +libunittest_a-ftp.obj: ftp.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libunittest_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libunittest_a-ftp.obj -MD -MP -MF $(DEPDIR)/libunittest_a-ftp.Tpo -c -o libunittest_a-ftp.obj `if test -f 'ftp.c'; then $(CYGPATH_W) 'ftp.c'; else $(CYGPATH_W) '$(srcdir)/ftp.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libunittest_a-ftp.Tpo $(DEPDIR)/libunittest_a-ftp.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ftp.c' object='libunittest_a-ftp.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libunittest_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libunittest_a-ftp.obj `if test -f 'ftp.c'; then $(CYGPATH_W) 'ftp.c'; else $(CYGPATH_W) '$(srcdir)/ftp.c'; fi` + +libunittest_a-css_.o: css_.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libunittest_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libunittest_a-css_.o -MD -MP -MF $(DEPDIR)/libunittest_a-css_.Tpo -c -o libunittest_a-css_.o `test -f 'css_.c' || echo '$(srcdir)/'`css_.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libunittest_a-css_.Tpo $(DEPDIR)/libunittest_a-css_.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='css_.c' object='libunittest_a-css_.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libunittest_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libunittest_a-css_.o `test -f 'css_.c' || echo '$(srcdir)/'`css_.c + +libunittest_a-css_.obj: css_.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libunittest_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libunittest_a-css_.obj -MD -MP -MF $(DEPDIR)/libunittest_a-css_.Tpo -c -o libunittest_a-css_.obj `if test -f 'css_.c'; then $(CYGPATH_W) 'css_.c'; else $(CYGPATH_W) '$(srcdir)/css_.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libunittest_a-css_.Tpo $(DEPDIR)/libunittest_a-css_.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='css_.c' object='libunittest_a-css_.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libunittest_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libunittest_a-css_.obj `if test -f 'css_.c'; then $(CYGPATH_W) 'css_.c'; else $(CYGPATH_W) '$(srcdir)/css_.c'; fi` + +libunittest_a-css-url.o: css-url.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libunittest_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libunittest_a-css-url.o -MD -MP -MF $(DEPDIR)/libunittest_a-css-url.Tpo -c -o libunittest_a-css-url.o `test -f 'css-url.c' || echo '$(srcdir)/'`css-url.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libunittest_a-css-url.Tpo $(DEPDIR)/libunittest_a-css-url.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='css-url.c' object='libunittest_a-css-url.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libunittest_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libunittest_a-css-url.o `test -f 'css-url.c' || echo '$(srcdir)/'`css-url.c + +libunittest_a-css-url.obj: css-url.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libunittest_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libunittest_a-css-url.obj -MD -MP -MF $(DEPDIR)/libunittest_a-css-url.Tpo -c -o libunittest_a-css-url.obj `if test -f 'css-url.c'; then $(CYGPATH_W) 'css-url.c'; else $(CYGPATH_W) '$(srcdir)/css-url.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libunittest_a-css-url.Tpo $(DEPDIR)/libunittest_a-css-url.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='css-url.c' object='libunittest_a-css-url.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libunittest_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libunittest_a-css-url.obj `if test -f 'css-url.c'; then $(CYGPATH_W) 'css-url.c'; else $(CYGPATH_W) '$(srcdir)/css-url.c'; fi` + +libunittest_a-ftp-basic.o: ftp-basic.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libunittest_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libunittest_a-ftp-basic.o -MD -MP -MF $(DEPDIR)/libunittest_a-ftp-basic.Tpo -c -o libunittest_a-ftp-basic.o `test -f 'ftp-basic.c' || echo '$(srcdir)/'`ftp-basic.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libunittest_a-ftp-basic.Tpo $(DEPDIR)/libunittest_a-ftp-basic.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ftp-basic.c' object='libunittest_a-ftp-basic.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libunittest_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libunittest_a-ftp-basic.o `test -f 'ftp-basic.c' || echo '$(srcdir)/'`ftp-basic.c + +libunittest_a-ftp-basic.obj: ftp-basic.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libunittest_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libunittest_a-ftp-basic.obj -MD -MP -MF $(DEPDIR)/libunittest_a-ftp-basic.Tpo -c -o libunittest_a-ftp-basic.obj `if test -f 'ftp-basic.c'; then $(CYGPATH_W) 'ftp-basic.c'; else $(CYGPATH_W) '$(srcdir)/ftp-basic.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libunittest_a-ftp-basic.Tpo $(DEPDIR)/libunittest_a-ftp-basic.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ftp-basic.c' object='libunittest_a-ftp-basic.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libunittest_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libunittest_a-ftp-basic.obj `if test -f 'ftp-basic.c'; then $(CYGPATH_W) 'ftp-basic.c'; else $(CYGPATH_W) '$(srcdir)/ftp-basic.c'; fi` + +libunittest_a-ftp-ls.o: ftp-ls.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libunittest_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libunittest_a-ftp-ls.o -MD -MP -MF $(DEPDIR)/libunittest_a-ftp-ls.Tpo -c -o libunittest_a-ftp-ls.o `test -f 'ftp-ls.c' || echo '$(srcdir)/'`ftp-ls.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libunittest_a-ftp-ls.Tpo $(DEPDIR)/libunittest_a-ftp-ls.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ftp-ls.c' object='libunittest_a-ftp-ls.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libunittest_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libunittest_a-ftp-ls.o `test -f 'ftp-ls.c' || echo '$(srcdir)/'`ftp-ls.c + +libunittest_a-ftp-ls.obj: ftp-ls.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libunittest_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libunittest_a-ftp-ls.obj -MD -MP -MF $(DEPDIR)/libunittest_a-ftp-ls.Tpo -c -o libunittest_a-ftp-ls.obj `if test -f 'ftp-ls.c'; then $(CYGPATH_W) 'ftp-ls.c'; else $(CYGPATH_W) '$(srcdir)/ftp-ls.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libunittest_a-ftp-ls.Tpo $(DEPDIR)/libunittest_a-ftp-ls.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ftp-ls.c' object='libunittest_a-ftp-ls.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libunittest_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libunittest_a-ftp-ls.obj `if test -f 'ftp-ls.c'; then $(CYGPATH_W) 'ftp-ls.c'; else $(CYGPATH_W) '$(srcdir)/ftp-ls.c'; fi` + +libunittest_a-hash.o: hash.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libunittest_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libunittest_a-hash.o -MD -MP -MF $(DEPDIR)/libunittest_a-hash.Tpo -c -o libunittest_a-hash.o `test -f 'hash.c' || echo '$(srcdir)/'`hash.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libunittest_a-hash.Tpo $(DEPDIR)/libunittest_a-hash.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='hash.c' object='libunittest_a-hash.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libunittest_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libunittest_a-hash.o `test -f 'hash.c' || echo '$(srcdir)/'`hash.c + +libunittest_a-hash.obj: hash.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libunittest_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libunittest_a-hash.obj -MD -MP -MF $(DEPDIR)/libunittest_a-hash.Tpo -c -o libunittest_a-hash.obj `if test -f 'hash.c'; then $(CYGPATH_W) 'hash.c'; else $(CYGPATH_W) '$(srcdir)/hash.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libunittest_a-hash.Tpo $(DEPDIR)/libunittest_a-hash.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='hash.c' object='libunittest_a-hash.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libunittest_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libunittest_a-hash.obj `if test -f 'hash.c'; then $(CYGPATH_W) 'hash.c'; else $(CYGPATH_W) '$(srcdir)/hash.c'; fi` + +libunittest_a-host.o: host.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libunittest_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libunittest_a-host.o -MD -MP -MF $(DEPDIR)/libunittest_a-host.Tpo -c -o libunittest_a-host.o `test -f 'host.c' || echo '$(srcdir)/'`host.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libunittest_a-host.Tpo $(DEPDIR)/libunittest_a-host.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='host.c' object='libunittest_a-host.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libunittest_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libunittest_a-host.o `test -f 'host.c' || echo '$(srcdir)/'`host.c + +libunittest_a-host.obj: host.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libunittest_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libunittest_a-host.obj -MD -MP -MF $(DEPDIR)/libunittest_a-host.Tpo -c -o libunittest_a-host.obj `if test -f 'host.c'; then $(CYGPATH_W) 'host.c'; else $(CYGPATH_W) '$(srcdir)/host.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libunittest_a-host.Tpo $(DEPDIR)/libunittest_a-host.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='host.c' object='libunittest_a-host.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libunittest_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libunittest_a-host.obj `if test -f 'host.c'; then $(CYGPATH_W) 'host.c'; else $(CYGPATH_W) '$(srcdir)/host.c'; fi` + +libunittest_a-hsts.o: hsts.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libunittest_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libunittest_a-hsts.o -MD -MP -MF $(DEPDIR)/libunittest_a-hsts.Tpo -c -o libunittest_a-hsts.o `test -f 'hsts.c' || echo '$(srcdir)/'`hsts.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libunittest_a-hsts.Tpo $(DEPDIR)/libunittest_a-hsts.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='hsts.c' object='libunittest_a-hsts.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libunittest_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libunittest_a-hsts.o `test -f 'hsts.c' || echo '$(srcdir)/'`hsts.c + +libunittest_a-hsts.obj: hsts.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libunittest_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libunittest_a-hsts.obj -MD -MP -MF $(DEPDIR)/libunittest_a-hsts.Tpo -c -o libunittest_a-hsts.obj `if test -f 'hsts.c'; then $(CYGPATH_W) 'hsts.c'; else $(CYGPATH_W) '$(srcdir)/hsts.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libunittest_a-hsts.Tpo $(DEPDIR)/libunittest_a-hsts.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='hsts.c' object='libunittest_a-hsts.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libunittest_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libunittest_a-hsts.obj `if test -f 'hsts.c'; then $(CYGPATH_W) 'hsts.c'; else $(CYGPATH_W) '$(srcdir)/hsts.c'; fi` + +libunittest_a-html-parse.o: html-parse.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libunittest_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libunittest_a-html-parse.o -MD -MP -MF $(DEPDIR)/libunittest_a-html-parse.Tpo -c -o libunittest_a-html-parse.o `test -f 'html-parse.c' || echo '$(srcdir)/'`html-parse.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libunittest_a-html-parse.Tpo $(DEPDIR)/libunittest_a-html-parse.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='html-parse.c' object='libunittest_a-html-parse.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libunittest_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libunittest_a-html-parse.o `test -f 'html-parse.c' || echo '$(srcdir)/'`html-parse.c + +libunittest_a-html-parse.obj: html-parse.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libunittest_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libunittest_a-html-parse.obj -MD -MP -MF $(DEPDIR)/libunittest_a-html-parse.Tpo -c -o libunittest_a-html-parse.obj `if test -f 'html-parse.c'; then $(CYGPATH_W) 'html-parse.c'; else $(CYGPATH_W) '$(srcdir)/html-parse.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libunittest_a-html-parse.Tpo $(DEPDIR)/libunittest_a-html-parse.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='html-parse.c' object='libunittest_a-html-parse.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libunittest_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libunittest_a-html-parse.obj `if test -f 'html-parse.c'; then $(CYGPATH_W) 'html-parse.c'; else $(CYGPATH_W) '$(srcdir)/html-parse.c'; fi` + +libunittest_a-html-url.o: html-url.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libunittest_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libunittest_a-html-url.o -MD -MP -MF $(DEPDIR)/libunittest_a-html-url.Tpo -c -o libunittest_a-html-url.o `test -f 'html-url.c' || echo '$(srcdir)/'`html-url.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libunittest_a-html-url.Tpo $(DEPDIR)/libunittest_a-html-url.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='html-url.c' object='libunittest_a-html-url.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libunittest_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libunittest_a-html-url.o `test -f 'html-url.c' || echo '$(srcdir)/'`html-url.c + +libunittest_a-html-url.obj: html-url.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libunittest_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libunittest_a-html-url.obj -MD -MP -MF $(DEPDIR)/libunittest_a-html-url.Tpo -c -o libunittest_a-html-url.obj `if test -f 'html-url.c'; then $(CYGPATH_W) 'html-url.c'; else $(CYGPATH_W) '$(srcdir)/html-url.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libunittest_a-html-url.Tpo $(DEPDIR)/libunittest_a-html-url.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='html-url.c' object='libunittest_a-html-url.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libunittest_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libunittest_a-html-url.obj `if test -f 'html-url.c'; then $(CYGPATH_W) 'html-url.c'; else $(CYGPATH_W) '$(srcdir)/html-url.c'; fi` + +libunittest_a-http.o: http.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libunittest_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libunittest_a-http.o -MD -MP -MF $(DEPDIR)/libunittest_a-http.Tpo -c -o libunittest_a-http.o `test -f 'http.c' || echo '$(srcdir)/'`http.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libunittest_a-http.Tpo $(DEPDIR)/libunittest_a-http.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='http.c' object='libunittest_a-http.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libunittest_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libunittest_a-http.o `test -f 'http.c' || echo '$(srcdir)/'`http.c + +libunittest_a-http.obj: http.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libunittest_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libunittest_a-http.obj -MD -MP -MF $(DEPDIR)/libunittest_a-http.Tpo -c -o libunittest_a-http.obj `if test -f 'http.c'; then $(CYGPATH_W) 'http.c'; else $(CYGPATH_W) '$(srcdir)/http.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libunittest_a-http.Tpo $(DEPDIR)/libunittest_a-http.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='http.c' object='libunittest_a-http.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libunittest_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libunittest_a-http.obj `if test -f 'http.c'; then $(CYGPATH_W) 'http.c'; else $(CYGPATH_W) '$(srcdir)/http.c'; fi` + +libunittest_a-init.o: init.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libunittest_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libunittest_a-init.o -MD -MP -MF $(DEPDIR)/libunittest_a-init.Tpo -c -o libunittest_a-init.o `test -f 'init.c' || echo '$(srcdir)/'`init.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libunittest_a-init.Tpo $(DEPDIR)/libunittest_a-init.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='init.c' object='libunittest_a-init.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libunittest_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libunittest_a-init.o `test -f 'init.c' || echo '$(srcdir)/'`init.c + +libunittest_a-init.obj: init.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libunittest_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libunittest_a-init.obj -MD -MP -MF $(DEPDIR)/libunittest_a-init.Tpo -c -o libunittest_a-init.obj `if test -f 'init.c'; then $(CYGPATH_W) 'init.c'; else $(CYGPATH_W) '$(srcdir)/init.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libunittest_a-init.Tpo $(DEPDIR)/libunittest_a-init.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='init.c' object='libunittest_a-init.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libunittest_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libunittest_a-init.obj `if test -f 'init.c'; then $(CYGPATH_W) 'init.c'; else $(CYGPATH_W) '$(srcdir)/init.c'; fi` + +libunittest_a-log.o: log.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libunittest_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libunittest_a-log.o -MD -MP -MF $(DEPDIR)/libunittest_a-log.Tpo -c -o libunittest_a-log.o `test -f 'log.c' || echo '$(srcdir)/'`log.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libunittest_a-log.Tpo $(DEPDIR)/libunittest_a-log.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='log.c' object='libunittest_a-log.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libunittest_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libunittest_a-log.o `test -f 'log.c' || echo '$(srcdir)/'`log.c + +libunittest_a-log.obj: log.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libunittest_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libunittest_a-log.obj -MD -MP -MF $(DEPDIR)/libunittest_a-log.Tpo -c -o libunittest_a-log.obj `if test -f 'log.c'; then $(CYGPATH_W) 'log.c'; else $(CYGPATH_W) '$(srcdir)/log.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libunittest_a-log.Tpo $(DEPDIR)/libunittest_a-log.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='log.c' object='libunittest_a-log.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libunittest_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libunittest_a-log.obj `if test -f 'log.c'; then $(CYGPATH_W) 'log.c'; else $(CYGPATH_W) '$(srcdir)/log.c'; fi` + +libunittest_a-main.o: main.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libunittest_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libunittest_a-main.o -MD -MP -MF $(DEPDIR)/libunittest_a-main.Tpo -c -o libunittest_a-main.o `test -f 'main.c' || echo '$(srcdir)/'`main.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libunittest_a-main.Tpo $(DEPDIR)/libunittest_a-main.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='main.c' object='libunittest_a-main.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libunittest_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libunittest_a-main.o `test -f 'main.c' || echo '$(srcdir)/'`main.c + +libunittest_a-main.obj: main.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libunittest_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libunittest_a-main.obj -MD -MP -MF $(DEPDIR)/libunittest_a-main.Tpo -c -o libunittest_a-main.obj `if test -f 'main.c'; then $(CYGPATH_W) 'main.c'; else $(CYGPATH_W) '$(srcdir)/main.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libunittest_a-main.Tpo $(DEPDIR)/libunittest_a-main.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='main.c' object='libunittest_a-main.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libunittest_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libunittest_a-main.obj `if test -f 'main.c'; then $(CYGPATH_W) 'main.c'; else $(CYGPATH_W) '$(srcdir)/main.c'; fi` + +libunittest_a-netrc.o: netrc.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libunittest_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libunittest_a-netrc.o -MD -MP -MF $(DEPDIR)/libunittest_a-netrc.Tpo -c -o libunittest_a-netrc.o `test -f 'netrc.c' || echo '$(srcdir)/'`netrc.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libunittest_a-netrc.Tpo $(DEPDIR)/libunittest_a-netrc.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='netrc.c' object='libunittest_a-netrc.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libunittest_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libunittest_a-netrc.o `test -f 'netrc.c' || echo '$(srcdir)/'`netrc.c + +libunittest_a-netrc.obj: netrc.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libunittest_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libunittest_a-netrc.obj -MD -MP -MF $(DEPDIR)/libunittest_a-netrc.Tpo -c -o libunittest_a-netrc.obj `if test -f 'netrc.c'; then $(CYGPATH_W) 'netrc.c'; else $(CYGPATH_W) '$(srcdir)/netrc.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libunittest_a-netrc.Tpo $(DEPDIR)/libunittest_a-netrc.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='netrc.c' object='libunittest_a-netrc.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libunittest_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libunittest_a-netrc.obj `if test -f 'netrc.c'; then $(CYGPATH_W) 'netrc.c'; else $(CYGPATH_W) '$(srcdir)/netrc.c'; fi` + +libunittest_a-progress.o: progress.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libunittest_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libunittest_a-progress.o -MD -MP -MF $(DEPDIR)/libunittest_a-progress.Tpo -c -o libunittest_a-progress.o `test -f 'progress.c' || echo '$(srcdir)/'`progress.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libunittest_a-progress.Tpo $(DEPDIR)/libunittest_a-progress.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='progress.c' object='libunittest_a-progress.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libunittest_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libunittest_a-progress.o `test -f 'progress.c' || echo '$(srcdir)/'`progress.c + +libunittest_a-progress.obj: progress.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libunittest_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libunittest_a-progress.obj -MD -MP -MF $(DEPDIR)/libunittest_a-progress.Tpo -c -o libunittest_a-progress.obj `if test -f 'progress.c'; then $(CYGPATH_W) 'progress.c'; else $(CYGPATH_W) '$(srcdir)/progress.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libunittest_a-progress.Tpo $(DEPDIR)/libunittest_a-progress.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='progress.c' object='libunittest_a-progress.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libunittest_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libunittest_a-progress.obj `if test -f 'progress.c'; then $(CYGPATH_W) 'progress.c'; else $(CYGPATH_W) '$(srcdir)/progress.c'; fi` + +libunittest_a-ptimer.o: ptimer.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libunittest_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libunittest_a-ptimer.o -MD -MP -MF $(DEPDIR)/libunittest_a-ptimer.Tpo -c -o libunittest_a-ptimer.o `test -f 'ptimer.c' || echo '$(srcdir)/'`ptimer.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libunittest_a-ptimer.Tpo $(DEPDIR)/libunittest_a-ptimer.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ptimer.c' object='libunittest_a-ptimer.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libunittest_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libunittest_a-ptimer.o `test -f 'ptimer.c' || echo '$(srcdir)/'`ptimer.c + +libunittest_a-ptimer.obj: ptimer.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libunittest_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libunittest_a-ptimer.obj -MD -MP -MF $(DEPDIR)/libunittest_a-ptimer.Tpo -c -o libunittest_a-ptimer.obj `if test -f 'ptimer.c'; then $(CYGPATH_W) 'ptimer.c'; else $(CYGPATH_W) '$(srcdir)/ptimer.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libunittest_a-ptimer.Tpo $(DEPDIR)/libunittest_a-ptimer.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ptimer.c' object='libunittest_a-ptimer.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libunittest_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libunittest_a-ptimer.obj `if test -f 'ptimer.c'; then $(CYGPATH_W) 'ptimer.c'; else $(CYGPATH_W) '$(srcdir)/ptimer.c'; fi` + +libunittest_a-recur.o: recur.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libunittest_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libunittest_a-recur.o -MD -MP -MF $(DEPDIR)/libunittest_a-recur.Tpo -c -o libunittest_a-recur.o `test -f 'recur.c' || echo '$(srcdir)/'`recur.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libunittest_a-recur.Tpo $(DEPDIR)/libunittest_a-recur.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='recur.c' object='libunittest_a-recur.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libunittest_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libunittest_a-recur.o `test -f 'recur.c' || echo '$(srcdir)/'`recur.c + +libunittest_a-recur.obj: recur.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libunittest_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libunittest_a-recur.obj -MD -MP -MF $(DEPDIR)/libunittest_a-recur.Tpo -c -o libunittest_a-recur.obj `if test -f 'recur.c'; then $(CYGPATH_W) 'recur.c'; else $(CYGPATH_W) '$(srcdir)/recur.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libunittest_a-recur.Tpo $(DEPDIR)/libunittest_a-recur.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='recur.c' object='libunittest_a-recur.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libunittest_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libunittest_a-recur.obj `if test -f 'recur.c'; then $(CYGPATH_W) 'recur.c'; else $(CYGPATH_W) '$(srcdir)/recur.c'; fi` + +libunittest_a-res.o: res.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libunittest_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libunittest_a-res.o -MD -MP -MF $(DEPDIR)/libunittest_a-res.Tpo -c -o libunittest_a-res.o `test -f 'res.c' || echo '$(srcdir)/'`res.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libunittest_a-res.Tpo $(DEPDIR)/libunittest_a-res.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='res.c' object='libunittest_a-res.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libunittest_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libunittest_a-res.o `test -f 'res.c' || echo '$(srcdir)/'`res.c + +libunittest_a-res.obj: res.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libunittest_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libunittest_a-res.obj -MD -MP -MF $(DEPDIR)/libunittest_a-res.Tpo -c -o libunittest_a-res.obj `if test -f 'res.c'; then $(CYGPATH_W) 'res.c'; else $(CYGPATH_W) '$(srcdir)/res.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libunittest_a-res.Tpo $(DEPDIR)/libunittest_a-res.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='res.c' object='libunittest_a-res.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libunittest_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libunittest_a-res.obj `if test -f 'res.c'; then $(CYGPATH_W) 'res.c'; else $(CYGPATH_W) '$(srcdir)/res.c'; fi` + +libunittest_a-retr.o: retr.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libunittest_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libunittest_a-retr.o -MD -MP -MF $(DEPDIR)/libunittest_a-retr.Tpo -c -o libunittest_a-retr.o `test -f 'retr.c' || echo '$(srcdir)/'`retr.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libunittest_a-retr.Tpo $(DEPDIR)/libunittest_a-retr.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='retr.c' object='libunittest_a-retr.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libunittest_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libunittest_a-retr.o `test -f 'retr.c' || echo '$(srcdir)/'`retr.c + +libunittest_a-retr.obj: retr.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libunittest_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libunittest_a-retr.obj -MD -MP -MF $(DEPDIR)/libunittest_a-retr.Tpo -c -o libunittest_a-retr.obj `if test -f 'retr.c'; then $(CYGPATH_W) 'retr.c'; else $(CYGPATH_W) '$(srcdir)/retr.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libunittest_a-retr.Tpo $(DEPDIR)/libunittest_a-retr.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='retr.c' object='libunittest_a-retr.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libunittest_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libunittest_a-retr.obj `if test -f 'retr.c'; then $(CYGPATH_W) 'retr.c'; else $(CYGPATH_W) '$(srcdir)/retr.c'; fi` + +libunittest_a-spider.o: spider.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libunittest_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libunittest_a-spider.o -MD -MP -MF $(DEPDIR)/libunittest_a-spider.Tpo -c -o libunittest_a-spider.o `test -f 'spider.c' || echo '$(srcdir)/'`spider.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libunittest_a-spider.Tpo $(DEPDIR)/libunittest_a-spider.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='spider.c' object='libunittest_a-spider.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libunittest_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libunittest_a-spider.o `test -f 'spider.c' || echo '$(srcdir)/'`spider.c + +libunittest_a-spider.obj: spider.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libunittest_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libunittest_a-spider.obj -MD -MP -MF $(DEPDIR)/libunittest_a-spider.Tpo -c -o libunittest_a-spider.obj `if test -f 'spider.c'; then $(CYGPATH_W) 'spider.c'; else $(CYGPATH_W) '$(srcdir)/spider.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libunittest_a-spider.Tpo $(DEPDIR)/libunittest_a-spider.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='spider.c' object='libunittest_a-spider.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libunittest_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libunittest_a-spider.obj `if test -f 'spider.c'; then $(CYGPATH_W) 'spider.c'; else $(CYGPATH_W) '$(srcdir)/spider.c'; fi` + +libunittest_a-url.o: url.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libunittest_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libunittest_a-url.o -MD -MP -MF $(DEPDIR)/libunittest_a-url.Tpo -c -o libunittest_a-url.o `test -f 'url.c' || echo '$(srcdir)/'`url.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libunittest_a-url.Tpo $(DEPDIR)/libunittest_a-url.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='url.c' object='libunittest_a-url.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libunittest_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libunittest_a-url.o `test -f 'url.c' || echo '$(srcdir)/'`url.c + +libunittest_a-url.obj: url.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libunittest_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libunittest_a-url.obj -MD -MP -MF $(DEPDIR)/libunittest_a-url.Tpo -c -o libunittest_a-url.obj `if test -f 'url.c'; then $(CYGPATH_W) 'url.c'; else $(CYGPATH_W) '$(srcdir)/url.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libunittest_a-url.Tpo $(DEPDIR)/libunittest_a-url.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='url.c' object='libunittest_a-url.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libunittest_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libunittest_a-url.obj `if test -f 'url.c'; then $(CYGPATH_W) 'url.c'; else $(CYGPATH_W) '$(srcdir)/url.c'; fi` + +libunittest_a-warc.o: warc.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libunittest_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libunittest_a-warc.o -MD -MP -MF $(DEPDIR)/libunittest_a-warc.Tpo -c -o libunittest_a-warc.o `test -f 'warc.c' || echo '$(srcdir)/'`warc.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libunittest_a-warc.Tpo $(DEPDIR)/libunittest_a-warc.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='warc.c' object='libunittest_a-warc.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libunittest_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libunittest_a-warc.o `test -f 'warc.c' || echo '$(srcdir)/'`warc.c + +libunittest_a-warc.obj: warc.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libunittest_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libunittest_a-warc.obj -MD -MP -MF $(DEPDIR)/libunittest_a-warc.Tpo -c -o libunittest_a-warc.obj `if test -f 'warc.c'; then $(CYGPATH_W) 'warc.c'; else $(CYGPATH_W) '$(srcdir)/warc.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libunittest_a-warc.Tpo $(DEPDIR)/libunittest_a-warc.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='warc.c' object='libunittest_a-warc.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libunittest_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libunittest_a-warc.obj `if test -f 'warc.c'; then $(CYGPATH_W) 'warc.c'; else $(CYGPATH_W) '$(srcdir)/warc.c'; fi` + +libunittest_a-xattr.o: xattr.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libunittest_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libunittest_a-xattr.o -MD -MP -MF $(DEPDIR)/libunittest_a-xattr.Tpo -c -o libunittest_a-xattr.o `test -f 'xattr.c' || echo '$(srcdir)/'`xattr.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libunittest_a-xattr.Tpo $(DEPDIR)/libunittest_a-xattr.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='xattr.c' object='libunittest_a-xattr.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libunittest_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libunittest_a-xattr.o `test -f 'xattr.c' || echo '$(srcdir)/'`xattr.c + +libunittest_a-xattr.obj: xattr.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libunittest_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libunittest_a-xattr.obj -MD -MP -MF $(DEPDIR)/libunittest_a-xattr.Tpo -c -o libunittest_a-xattr.obj `if test -f 'xattr.c'; then $(CYGPATH_W) 'xattr.c'; else $(CYGPATH_W) '$(srcdir)/xattr.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libunittest_a-xattr.Tpo $(DEPDIR)/libunittest_a-xattr.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='xattr.c' object='libunittest_a-xattr.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libunittest_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libunittest_a-xattr.obj `if test -f 'xattr.c'; then $(CYGPATH_W) 'xattr.c'; else $(CYGPATH_W) '$(srcdir)/xattr.c'; fi` + +libunittest_a-utils.o: utils.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libunittest_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libunittest_a-utils.o -MD -MP -MF $(DEPDIR)/libunittest_a-utils.Tpo -c -o libunittest_a-utils.o `test -f 'utils.c' || echo '$(srcdir)/'`utils.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libunittest_a-utils.Tpo $(DEPDIR)/libunittest_a-utils.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='utils.c' object='libunittest_a-utils.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libunittest_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libunittest_a-utils.o `test -f 'utils.c' || echo '$(srcdir)/'`utils.c + +libunittest_a-utils.obj: utils.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libunittest_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libunittest_a-utils.obj -MD -MP -MF $(DEPDIR)/libunittest_a-utils.Tpo -c -o libunittest_a-utils.obj `if test -f 'utils.c'; then $(CYGPATH_W) 'utils.c'; else $(CYGPATH_W) '$(srcdir)/utils.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libunittest_a-utils.Tpo $(DEPDIR)/libunittest_a-utils.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='utils.c' object='libunittest_a-utils.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libunittest_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libunittest_a-utils.obj `if test -f 'utils.c'; then $(CYGPATH_W) 'utils.c'; else $(CYGPATH_W) '$(srcdir)/utils.c'; fi` + +libunittest_a-exits.o: exits.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libunittest_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libunittest_a-exits.o -MD -MP -MF $(DEPDIR)/libunittest_a-exits.Tpo -c -o libunittest_a-exits.o `test -f 'exits.c' || echo '$(srcdir)/'`exits.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libunittest_a-exits.Tpo $(DEPDIR)/libunittest_a-exits.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='exits.c' object='libunittest_a-exits.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libunittest_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libunittest_a-exits.o `test -f 'exits.c' || echo '$(srcdir)/'`exits.c + +libunittest_a-exits.obj: exits.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libunittest_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libunittest_a-exits.obj -MD -MP -MF $(DEPDIR)/libunittest_a-exits.Tpo -c -o libunittest_a-exits.obj `if test -f 'exits.c'; then $(CYGPATH_W) 'exits.c'; else $(CYGPATH_W) '$(srcdir)/exits.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libunittest_a-exits.Tpo $(DEPDIR)/libunittest_a-exits.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='exits.c' object='libunittest_a-exits.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libunittest_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libunittest_a-exits.obj `if test -f 'exits.c'; then $(CYGPATH_W) 'exits.c'; else $(CYGPATH_W) '$(srcdir)/exits.c'; fi` + +libunittest_a-build_info.o: build_info.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libunittest_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libunittest_a-build_info.o -MD -MP -MF $(DEPDIR)/libunittest_a-build_info.Tpo -c -o libunittest_a-build_info.o `test -f 'build_info.c' || echo '$(srcdir)/'`build_info.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libunittest_a-build_info.Tpo $(DEPDIR)/libunittest_a-build_info.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='build_info.c' object='libunittest_a-build_info.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libunittest_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libunittest_a-build_info.o `test -f 'build_info.c' || echo '$(srcdir)/'`build_info.c + +libunittest_a-build_info.obj: build_info.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libunittest_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libunittest_a-build_info.obj -MD -MP -MF $(DEPDIR)/libunittest_a-build_info.Tpo -c -o libunittest_a-build_info.obj `if test -f 'build_info.c'; then $(CYGPATH_W) 'build_info.c'; else $(CYGPATH_W) '$(srcdir)/build_info.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libunittest_a-build_info.Tpo $(DEPDIR)/libunittest_a-build_info.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='build_info.c' object='libunittest_a-build_info.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libunittest_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libunittest_a-build_info.obj `if test -f 'build_info.c'; then $(CYGPATH_W) 'build_info.c'; else $(CYGPATH_W) '$(srcdir)/build_info.c'; fi` + +libunittest_a-iri.o: iri.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libunittest_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libunittest_a-iri.o -MD -MP -MF $(DEPDIR)/libunittest_a-iri.Tpo -c -o libunittest_a-iri.o `test -f 'iri.c' || echo '$(srcdir)/'`iri.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libunittest_a-iri.Tpo $(DEPDIR)/libunittest_a-iri.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='iri.c' object='libunittest_a-iri.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libunittest_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libunittest_a-iri.o `test -f 'iri.c' || echo '$(srcdir)/'`iri.c + +libunittest_a-iri.obj: iri.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libunittest_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libunittest_a-iri.obj -MD -MP -MF $(DEPDIR)/libunittest_a-iri.Tpo -c -o libunittest_a-iri.obj `if test -f 'iri.c'; then $(CYGPATH_W) 'iri.c'; else $(CYGPATH_W) '$(srcdir)/iri.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libunittest_a-iri.Tpo $(DEPDIR)/libunittest_a-iri.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='iri.c' object='libunittest_a-iri.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libunittest_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libunittest_a-iri.obj `if test -f 'iri.c'; then $(CYGPATH_W) 'iri.c'; else $(CYGPATH_W) '$(srcdir)/iri.c'; fi` + +libunittest_a-metalink.o: metalink.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libunittest_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libunittest_a-metalink.o -MD -MP -MF $(DEPDIR)/libunittest_a-metalink.Tpo -c -o libunittest_a-metalink.o `test -f 'metalink.c' || echo '$(srcdir)/'`metalink.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libunittest_a-metalink.Tpo $(DEPDIR)/libunittest_a-metalink.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='metalink.c' object='libunittest_a-metalink.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libunittest_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libunittest_a-metalink.o `test -f 'metalink.c' || echo '$(srcdir)/'`metalink.c + +libunittest_a-metalink.obj: metalink.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libunittest_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libunittest_a-metalink.obj -MD -MP -MF $(DEPDIR)/libunittest_a-metalink.Tpo -c -o libunittest_a-metalink.obj `if test -f 'metalink.c'; then $(CYGPATH_W) 'metalink.c'; else $(CYGPATH_W) '$(srcdir)/metalink.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libunittest_a-metalink.Tpo $(DEPDIR)/libunittest_a-metalink.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='metalink.c' object='libunittest_a-metalink.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libunittest_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libunittest_a-metalink.obj `if test -f 'metalink.c'; then $(CYGPATH_W) 'metalink.c'; else $(CYGPATH_W) '$(srcdir)/metalink.c'; fi` + +libunittest_a-version.o: version.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libunittest_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libunittest_a-version.o -MD -MP -MF $(DEPDIR)/libunittest_a-version.Tpo -c -o libunittest_a-version.o `test -f 'version.c' || echo '$(srcdir)/'`version.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libunittest_a-version.Tpo $(DEPDIR)/libunittest_a-version.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='version.c' object='libunittest_a-version.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libunittest_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libunittest_a-version.o `test -f 'version.c' || echo '$(srcdir)/'`version.c + +libunittest_a-version.obj: version.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libunittest_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libunittest_a-version.obj -MD -MP -MF $(DEPDIR)/libunittest_a-version.Tpo -c -o libunittest_a-version.obj `if test -f 'version.c'; then $(CYGPATH_W) 'version.c'; else $(CYGPATH_W) '$(srcdir)/version.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libunittest_a-version.Tpo $(DEPDIR)/libunittest_a-version.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='version.c' object='libunittest_a-version.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libunittest_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libunittest_a-version.obj `if test -f 'version.c'; then $(CYGPATH_W) 'version.c'; else $(CYGPATH_W) '$(srcdir)/version.c'; fi` + +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-am +TAGS: tags + +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + set x; \ + here=`pwd`; \ + $(am__define_uniq_tagged_files); \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: ctags-am + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" +cscopelist: cscopelist-am + +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) distdir-am + +distdir-am: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am + $(MAKE) $(AM_MAKEFLAGS) $(check_LIBRARIES) +check: check-am +all-am: Makefile $(PROGRAMS) config.h +installdirs: + for dir in "$(DESTDIR)$(bindir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + +clean-generic: + -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-binPROGRAMS clean-checkLIBRARIES clean-generic \ + mostlyclean-am + +distclean: distclean-am + -rm -f $(DEPDIR)/ftp-opie.Po + -rm -f $(DEPDIR)/gnutls.Po + -rm -f $(DEPDIR)/http-ntlm.Po + -rm -f $(DEPDIR)/mswindows.Po + -rm -f $(DEPDIR)/openssl.Po + -rm -f ./$(DEPDIR)/build_info.Po + -rm -f ./$(DEPDIR)/connect.Po + -rm -f ./$(DEPDIR)/convert.Po + -rm -f ./$(DEPDIR)/cookies.Po + -rm -f ./$(DEPDIR)/css-url.Po + -rm -f ./$(DEPDIR)/css_.Po + -rm -f ./$(DEPDIR)/exits.Po + -rm -f ./$(DEPDIR)/ftp-basic.Po + -rm -f ./$(DEPDIR)/ftp-ls.Po + -rm -f ./$(DEPDIR)/ftp.Po + -rm -f ./$(DEPDIR)/hash.Po + -rm -f ./$(DEPDIR)/host.Po + -rm -f ./$(DEPDIR)/hsts.Po + -rm -f ./$(DEPDIR)/html-parse.Po + -rm -f ./$(DEPDIR)/html-url.Po + -rm -f ./$(DEPDIR)/http.Po + -rm -f ./$(DEPDIR)/init.Po + -rm -f ./$(DEPDIR)/iri.Po + -rm -f ./$(DEPDIR)/libunittest_a-build_info.Po + -rm -f ./$(DEPDIR)/libunittest_a-connect.Po + -rm -f ./$(DEPDIR)/libunittest_a-convert.Po + -rm -f ./$(DEPDIR)/libunittest_a-cookies.Po + -rm -f ./$(DEPDIR)/libunittest_a-css-url.Po + -rm -f ./$(DEPDIR)/libunittest_a-css_.Po + -rm -f ./$(DEPDIR)/libunittest_a-exits.Po + -rm -f ./$(DEPDIR)/libunittest_a-ftp-basic.Po + -rm -f ./$(DEPDIR)/libunittest_a-ftp-ls.Po + -rm -f ./$(DEPDIR)/libunittest_a-ftp.Po + -rm -f ./$(DEPDIR)/libunittest_a-hash.Po + -rm -f ./$(DEPDIR)/libunittest_a-host.Po + -rm -f ./$(DEPDIR)/libunittest_a-hsts.Po + -rm -f ./$(DEPDIR)/libunittest_a-html-parse.Po + -rm -f ./$(DEPDIR)/libunittest_a-html-url.Po + -rm -f ./$(DEPDIR)/libunittest_a-http.Po + -rm -f ./$(DEPDIR)/libunittest_a-init.Po + -rm -f ./$(DEPDIR)/libunittest_a-iri.Po + -rm -f ./$(DEPDIR)/libunittest_a-log.Po + -rm -f ./$(DEPDIR)/libunittest_a-main.Po + -rm -f ./$(DEPDIR)/libunittest_a-metalink.Po + -rm -f ./$(DEPDIR)/libunittest_a-netrc.Po + -rm -f ./$(DEPDIR)/libunittest_a-progress.Po + -rm -f ./$(DEPDIR)/libunittest_a-ptimer.Po + -rm -f ./$(DEPDIR)/libunittest_a-recur.Po + -rm -f ./$(DEPDIR)/libunittest_a-res.Po + -rm -f ./$(DEPDIR)/libunittest_a-retr.Po + -rm -f ./$(DEPDIR)/libunittest_a-spider.Po + -rm -f ./$(DEPDIR)/libunittest_a-url.Po + -rm -f ./$(DEPDIR)/libunittest_a-utils.Po + -rm -f ./$(DEPDIR)/libunittest_a-version.Po + -rm -f ./$(DEPDIR)/libunittest_a-warc.Po + -rm -f ./$(DEPDIR)/libunittest_a-xattr.Po + -rm -f ./$(DEPDIR)/log.Po + -rm -f ./$(DEPDIR)/main.Po + -rm -f ./$(DEPDIR)/metalink.Po + -rm -f ./$(DEPDIR)/netrc.Po + -rm -f ./$(DEPDIR)/progress.Po + -rm -f ./$(DEPDIR)/ptimer.Po + -rm -f ./$(DEPDIR)/recur.Po + -rm -f ./$(DEPDIR)/res.Po + -rm -f ./$(DEPDIR)/retr.Po + -rm -f ./$(DEPDIR)/spider.Po + -rm -f ./$(DEPDIR)/url.Po + -rm -f ./$(DEPDIR)/utils.Po + -rm -f ./$(DEPDIR)/version.Po + -rm -f ./$(DEPDIR)/warc.Po + -rm -f ./$(DEPDIR)/xattr.Po + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-hdr distclean-local distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: install-binPROGRAMS + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -f $(DEPDIR)/ftp-opie.Po + -rm -f $(DEPDIR)/gnutls.Po + -rm -f $(DEPDIR)/http-ntlm.Po + -rm -f $(DEPDIR)/mswindows.Po + -rm -f $(DEPDIR)/openssl.Po + -rm -f ./$(DEPDIR)/build_info.Po + -rm -f ./$(DEPDIR)/connect.Po + -rm -f ./$(DEPDIR)/convert.Po + -rm -f ./$(DEPDIR)/cookies.Po + -rm -f ./$(DEPDIR)/css-url.Po + -rm -f ./$(DEPDIR)/css_.Po + -rm -f ./$(DEPDIR)/exits.Po + -rm -f ./$(DEPDIR)/ftp-basic.Po + -rm -f ./$(DEPDIR)/ftp-ls.Po + -rm -f ./$(DEPDIR)/ftp.Po + -rm -f ./$(DEPDIR)/hash.Po + -rm -f ./$(DEPDIR)/host.Po + -rm -f ./$(DEPDIR)/hsts.Po + -rm -f ./$(DEPDIR)/html-parse.Po + -rm -f ./$(DEPDIR)/html-url.Po + -rm -f ./$(DEPDIR)/http.Po + -rm -f ./$(DEPDIR)/init.Po + -rm -f ./$(DEPDIR)/iri.Po + -rm -f ./$(DEPDIR)/libunittest_a-build_info.Po + -rm -f ./$(DEPDIR)/libunittest_a-connect.Po + -rm -f ./$(DEPDIR)/libunittest_a-convert.Po + -rm -f ./$(DEPDIR)/libunittest_a-cookies.Po + -rm -f ./$(DEPDIR)/libunittest_a-css-url.Po + -rm -f ./$(DEPDIR)/libunittest_a-css_.Po + -rm -f ./$(DEPDIR)/libunittest_a-exits.Po + -rm -f ./$(DEPDIR)/libunittest_a-ftp-basic.Po + -rm -f ./$(DEPDIR)/libunittest_a-ftp-ls.Po + -rm -f ./$(DEPDIR)/libunittest_a-ftp.Po + -rm -f ./$(DEPDIR)/libunittest_a-hash.Po + -rm -f ./$(DEPDIR)/libunittest_a-host.Po + -rm -f ./$(DEPDIR)/libunittest_a-hsts.Po + -rm -f ./$(DEPDIR)/libunittest_a-html-parse.Po + -rm -f ./$(DEPDIR)/libunittest_a-html-url.Po + -rm -f ./$(DEPDIR)/libunittest_a-http.Po + -rm -f ./$(DEPDIR)/libunittest_a-init.Po + -rm -f ./$(DEPDIR)/libunittest_a-iri.Po + -rm -f ./$(DEPDIR)/libunittest_a-log.Po + -rm -f ./$(DEPDIR)/libunittest_a-main.Po + -rm -f ./$(DEPDIR)/libunittest_a-metalink.Po + -rm -f ./$(DEPDIR)/libunittest_a-netrc.Po + -rm -f ./$(DEPDIR)/libunittest_a-progress.Po + -rm -f ./$(DEPDIR)/libunittest_a-ptimer.Po + -rm -f ./$(DEPDIR)/libunittest_a-recur.Po + -rm -f ./$(DEPDIR)/libunittest_a-res.Po + -rm -f ./$(DEPDIR)/libunittest_a-retr.Po + -rm -f ./$(DEPDIR)/libunittest_a-spider.Po + -rm -f ./$(DEPDIR)/libunittest_a-url.Po + -rm -f ./$(DEPDIR)/libunittest_a-utils.Po + -rm -f ./$(DEPDIR)/libunittest_a-version.Po + -rm -f ./$(DEPDIR)/libunittest_a-warc.Po + -rm -f ./$(DEPDIR)/libunittest_a-xattr.Po + -rm -f ./$(DEPDIR)/log.Po + -rm -f ./$(DEPDIR)/main.Po + -rm -f ./$(DEPDIR)/metalink.Po + -rm -f ./$(DEPDIR)/netrc.Po + -rm -f ./$(DEPDIR)/progress.Po + -rm -f ./$(DEPDIR)/ptimer.Po + -rm -f ./$(DEPDIR)/recur.Po + -rm -f ./$(DEPDIR)/res.Po + -rm -f ./$(DEPDIR)/retr.Po + -rm -f ./$(DEPDIR)/spider.Po + -rm -f ./$(DEPDIR)/url.Po + -rm -f ./$(DEPDIR)/utils.Po + -rm -f ./$(DEPDIR)/version.Po + -rm -f ./$(DEPDIR)/warc.Po + -rm -f ./$(DEPDIR)/xattr.Po + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-binPROGRAMS + +.MAKE: all check-am install-am install-strip + +.PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ + clean-binPROGRAMS clean-checkLIBRARIES clean-generic \ + cscopelist-am ctags ctags-am distclean distclean-compile \ + distclean-generic distclean-hdr distclean-local 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-pdf install-pdf-am install-ps \ + install-ps-am install-strip installcheck installcheck-am \ + installdirs maintainer-clean maintainer-clean-generic \ + mostlyclean mostlyclean-compile mostlyclean-generic pdf pdf-am \ + ps ps-am tags tags-am uninstall uninstall-am \ + uninstall-binPROGRAMS + +.PRECIOUS: Makefile + + +../lib/libgnu.a: + cd ../lib && $(MAKE) $(AM_MAKEFLAGS) + +build_info.c: $(srcdir)/Makefile.am $(srcdir)/build_info.c.in + if test -n "$(VPATH)"; then cp "$(srcdir)/build_info.c.in" .; fi + $(PERL) "$(top_srcdir)/build-aux/build_info.pl" \ + "$(top_builddir)/src/build_info.c" + if test -n "$(VPATH)"; then rm -f build_info.c.in; fi +version.c: $(wget_SOURCES) ../lib/libgnu.a + echo '/* version.c */' > $@ + echo '/* Autogenerated by Makefile - DO NOT EDIT */' >> $@ + echo '' >> $@ + echo '#include "version.h"' >> $@ + echo 'const char *version_string = "@VERSION@";' >> $@ + echo 'const char *compilation_string = "'$(COMPILE)'";' \ + | $(ESCAPEQUOTE) >> $@ + echo 'const char *link_string = "'$(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(AM_LDFLAGS) $(LDFLAGS) $(LIBS) $(wget_LDADD)'";' \ + | $(ESCAPEQUOTE) >> $@ + +css.c: $(srcdir)/css.l + $(LEX) $(LFLAGS) -o$@ $^ + +css_.c: css.c + echo '#include "wget.h"' > $@ + cat css.c >> $@ + +distclean-local: + rm -f css.c css_.c + +# 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/src/build_info.c b/src/build_info.c new file mode 100644 index 0000000..bf6e6a9 --- /dev/null +++ b/src/build_info.c @@ -0,0 +1,101 @@ +/* Autogenerated by build_info.pl - DO NOT EDIT */ + +/* This stores global variables that are initialized with + preprocessor declarations for output with the --version flag. + + Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, + 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc. */ + +#include "wget.h" +#include +#include "version.h" + +const char *compiled_features[] = +{ + +#if defined HAVE_LIBCARES + "+cares", +#else + "-cares", +#endif + +#if defined ENABLE_DIGEST + "+digest", +#else + "-digest", +#endif + +#if defined HAVE_GPGME + "+gpgme", +#else + "-gpgme", +#endif + +#if defined HAVE_SSL + "+https", +#else + "-https", +#endif + +#if defined ENABLE_IPV6 + "+ipv6", +#else + "-ipv6", +#endif + +#if defined ENABLE_IRI + "+iri", +#else + "-iri", +#endif + +#if SIZEOF_OFF_T >= 8 || defined WINDOWS + "+large-file", +#else + "-large-file", +#endif + +#if defined HAVE_METALINK + "+metalink", +#else + "-metalink", +#endif + +#if defined ENABLE_NLS + "+nls", +#else + "-nls", +#endif + +#if defined ENABLE_NTLM + "+ntlm", +#else + "-ntlm", +#endif + +#if defined ENABLE_OPIE + "+opie", +#else + "-opie", +#endif + +#if defined HAVE_LIBPSL + "+psl", +#else + "-psl", +#endif + +#if defined HAVE_LIBSSL || defined HAVE_LIBSSL32 + "+ssl/openssl", +#elif defined HAVE_LIBGNUTLS + "+ssl/gnutls", +#else + "-ssl", +#endif + + + /* sentinel value */ + NULL +}; + + diff --git a/src/build_info.c.in b/src/build_info.c.in new file mode 100644 index 0000000..c7493e9 --- /dev/null +++ b/src/build_info.c.in @@ -0,0 +1,18 @@ +digest defined ENABLE_DIGEST +https defined HAVE_SSL +ipv6 defined ENABLE_IPV6 +iri defined ENABLE_IRI +large-file SIZEOF_OFF_T >= 8 || defined WINDOWS + +nls defined ENABLE_NLS +ntlm defined ENABLE_NTLM +opie defined ENABLE_OPIE +psl defined HAVE_LIBPSL +cares defined HAVE_LIBCARES + +metalink defined HAVE_METALINK +gpgme defined HAVE_GPGME + +ssl choice: + openssl defined HAVE_LIBSSL || defined HAVE_LIBSSL32 + gnutls defined HAVE_LIBGNUTLS diff --git a/src/config.h.in b/src/config.h.in new file mode 100644 index 0000000..936d100 --- /dev/null +++ b/src/config.h.in @@ -0,0 +1,2685 @@ +/* src/config.h.in. Generated from configure.ac by autoheader. */ + +/* Define if building universal (internal helper macro) */ +#undef AC_APPLE_UNIVERSAL_BUILD + +/* Define to the number of bits in type 'ptrdiff_t'. */ +#undef BITSIZEOF_PTRDIFF_T + +/* Define to the number of bits in type 'sig_atomic_t'. */ +#undef BITSIZEOF_SIG_ATOMIC_T + +/* Define to the number of bits in type 'size_t'. */ +#undef BITSIZEOF_SIZE_T + +/* Define to the number of bits in type 'wchar_t'. */ +#undef BITSIZEOF_WCHAR_T + +/* Define to the number of bits in type 'wint_t'. */ +#undef BITSIZEOF_WINT_T + +/* Define to 1 if using `alloca.c'. */ +#undef C_ALLOCA + +/* Define as the bit index in the word where to find bit 0 of the exponent of + 'double'. */ +#undef DBL_EXPBIT0_BIT + +/* Define as the word index where to find the exponent of 'double'. */ +#undef DBL_EXPBIT0_WORD + +/* the name of the file descriptor member of DIR */ +#undef DIR_FD_MEMBER_NAME + +#ifdef DIR_FD_MEMBER_NAME +# define DIR_TO_FD(Dir_p) ((Dir_p)->DIR_FD_MEMBER_NAME) +#else +# define DIR_TO_FD(Dir_p) -1 +#endif + + +/* Define to 1 if // is a file system root distinct from /. */ +#undef DOUBLE_SLASH_IS_DISTINCT_ROOT + +/* Define if struct dirent has a member d_ino that actually works. */ +#undef D_INO_IN_DIRENT + +/* Define if you want the debug output support compiled in. */ +#undef ENABLE_DEBUG + +/* Define if you want the HTTP Digest Authorization compiled in. */ +#undef ENABLE_DIGEST + +/* Define if IPv6 support is enabled. */ +#undef ENABLE_IPV6 + +/* Define if IRI support is enabled. */ +#undef ENABLE_IRI + +/* Define to 1 if translation of program messages to the user's native + language is requested. */ +#undef ENABLE_NLS + +/* Define if you want the NTLM authorization support compiled in. */ +#undef ENABLE_NTLM + +/* Define if you want Opie support for FTP compiled in. */ +#undef ENABLE_OPIE + +/* Define if you want file meta-data storing into POSIX Extended Attributes + compiled in. */ +#undef ENABLE_XATTR + +/* Define this to 1 if F_DUPFD behavior does not match POSIX */ +#undef FCNTL_DUPFD_BUGGY + +/* Define to nothing if C supports flexible array members, and to 1 if it does + not. That way, with a declaration like 'struct s { int n; short + d[FLEXIBLE_ARRAY_MEMBER]; };', the struct hack can be used with pre-C99 + compilers. Use 'FLEXSIZEOF (struct s, d, N * sizeof (short))' to calculate + the size in bytes of such a struct containing an N-element array. */ +#undef FLEXIBLE_ARRAY_MEMBER + +/* Define to 1 if fopen() fails to recognize a trailing slash. */ +#undef FOPEN_TRAILING_SLASH_BUG + +/* Define to 1 if the system's ftello function has the Solaris bug. */ +#undef FTELLO_BROKEN_AFTER_SWITCHING_FROM_READ_TO_WRITE + +/* Define to 1 if fflush is known to work on stdin as per POSIX.1-2008, 0 if + fflush is known to not work, -1 if unknown. */ +#undef FUNC_FFLUSH_STDIN + +/* Define to 1 if mkdir mistakenly creates a directory given with a trailing + dot component. */ +#undef FUNC_MKDIR_DOT_BUG + +/* Define to 1 if nl_langinfo (YESEXPR) returns a non-empty string. */ +#undef FUNC_NL_LANGINFO_YESEXPR_WORKS + +/* Define to 1 if realpath() can malloc memory, always gives an absolute path, + and handles trailing slash correctly. */ +#undef FUNC_REALPATH_WORKS + +/* Define to 1 if futimesat mishandles a NULL file name. */ +#undef FUTIMESAT_NULL_BUG + +/* Define to 1 if this is a fuzzing build */ +#undef FUZZING + +/* Define to the type of elements in the array set by `getgroups'. Usually + this is either `int' or `gid_t'. */ +#undef GETGROUPS_T + +/* Define this to 1 if getgroups(0,NULL) does not return the number of groups. + */ +#undef GETGROUPS_ZERO_BUG + +/* Define this to 'void' or 'struct timezone' to match the system's + declaration of the second argument to gettimeofday. */ +#undef GETTIMEOFDAY_TIMEZONE + +/* Compile Gnulib crypto stream ops. */ +#undef GL_COMPILE_CRYPTO_STREAM + +/* Define to a C preprocessor expression that evaluates to 1 or 0, depending + whether the gnulib module canonicalize shall be considered present. */ +#undef GNULIB_CANONICALIZE + +/* Define to a C preprocessor expression that evaluates to 1 or 0, depending + whether the gnulib module dirname shall be considered present. */ +#undef GNULIB_DIRNAME + +/* Define to a C preprocessor expression that evaluates to 1 or 0, depending + whether the gnulib module fdopendir shall be considered present. */ +#undef GNULIB_FDOPENDIR + +/* Define to a C preprocessor expression that evaluates to 1 or 0, depending + whether the gnulib module fd-safer-flag shall be considered present. */ +#undef GNULIB_FD_SAFER_FLAG + +/* Define to a C preprocessor expression that evaluates to 1 or 0, depending + whether the gnulib module fflush shall be considered present. */ +#undef GNULIB_FFLUSH + +/* Define to a C preprocessor expression that evaluates to 1 or 0, depending + whether the gnulib module fnmatch-gnu shall be considered present. */ +#undef GNULIB_FNMATCH_GNU + +/* Define to a C preprocessor expression that evaluates to 1 or 0, depending + whether the gnulib module fopen-gnu shall be considered present. */ +#undef GNULIB_FOPEN_GNU + +/* Define to a C preprocessor expression that evaluates to 1 or 0, depending + whether the gnulib module fscanf shall be considered present. */ +#undef GNULIB_FSCANF + +/* Define to a C preprocessor expression that evaluates to 1 or 0, depending + whether the gnulib module getcwd shall be considered present. */ +#undef GNULIB_GETCWD + +/* Define to a C preprocessor expression that evaluates to 1 or 0, depending + whether the gnulib module isblank shall be considered present. */ +#undef GNULIB_ISBLANK + +/* Define to a C preprocessor expression that evaluates to 1 or 0, depending + whether the gnulib module lock shall be considered present. */ +#undef GNULIB_LOCK + +/* Define to a C preprocessor expression that evaluates to 1 or 0, depending + whether the gnulib module mkostemp shall be considered present. */ +#undef GNULIB_MKOSTEMP + +/* Define to a C preprocessor expression that evaluates to 1 or 0, depending + whether the gnulib module msvc-nothrow shall be considered present. */ +#undef GNULIB_MSVC_NOTHROW + +/* Define to a C preprocessor expression that evaluates to 1 or 0, depending + whether the gnulib module openat shall be considered present. */ +#undef GNULIB_OPENAT + +/* Define to a C preprocessor expression that evaluates to 1 or 0, depending + whether the gnulib module pipe2-safer shall be considered present. */ +#undef GNULIB_PIPE2_SAFER + +/* Define to 1 if printf and friends should be labeled with attribute + "__gnu_printf__" instead of "__printf__" */ +#undef GNULIB_PRINTF_ATTRIBUTE_FLAVOR_GNU + +/* Define to a C preprocessor expression that evaluates to 1 or 0, depending + whether the gnulib module scanf shall be considered present. */ +#undef GNULIB_SCANF + +/* Define to a C preprocessor expression that evaluates to 1 or 0, depending + whether the gnulib module sigpipe shall be considered present. */ +#undef GNULIB_SIGPIPE + +/* Define to a C preprocessor expression that evaluates to 1 or 0, depending + whether the gnulib module snprintf shall be considered present. */ +#undef GNULIB_SNPRINTF + +/* Define to a C preprocessor expression that evaluates to 1 or 0, depending + whether the gnulib module strerror shall be considered present. */ +#undef GNULIB_STRERROR + +/* Define to a C preprocessor expression that evaluates to 1 or 0, depending + whether the gnulib module strerror_r-posix shall be considered present. */ +#undef GNULIB_STRERROR_R_POSIX + +/* Define to a C preprocessor expression that evaluates to 1 or 0, depending + whether the gnulib module tempname shall be considered present. */ +#undef GNULIB_TEMPNAME + +/* Define to 1 when the gnulib module accept should be tested. */ +#undef GNULIB_TEST_ACCEPT + +/* Define to 1 when the gnulib module access should be tested. */ +#undef GNULIB_TEST_ACCESS + +/* Define to 1 when the gnulib module bind should be tested. */ +#undef GNULIB_TEST_BIND + +/* Define to 1 when the gnulib module btowc should be tested. */ +#undef GNULIB_TEST_BTOWC + +/* Define to 1 when the gnulib module canonicalize should be tested. */ +#undef GNULIB_TEST_CANONICALIZE + +/* Define to 1 when the gnulib module canonicalize_file_name should be tested. + */ +#undef GNULIB_TEST_CANONICALIZE_FILE_NAME + +/* Define to 1 when the gnulib module chdir should be tested. */ +#undef GNULIB_TEST_CHDIR + +/* Define to 1 when the gnulib module cloexec should be tested. */ +#undef GNULIB_TEST_CLOEXEC + +/* Define to 1 when the gnulib module close should be tested. */ +#undef GNULIB_TEST_CLOSE + +/* Define to 1 when the gnulib module closedir should be tested. */ +#undef GNULIB_TEST_CLOSEDIR + +/* Define to 1 when the gnulib module connect should be tested. */ +#undef GNULIB_TEST_CONNECT + +/* Define to 1 when the gnulib module dirfd should be tested. */ +#undef GNULIB_TEST_DIRFD + +/* Define to 1 when the gnulib module dup should be tested. */ +#undef GNULIB_TEST_DUP + +/* Define to 1 when the gnulib module dup2 should be tested. */ +#undef GNULIB_TEST_DUP2 + +/* Define to 1 when the gnulib module environ should be tested. */ +#undef GNULIB_TEST_ENVIRON + +/* Define to 1 when the gnulib module fchdir should be tested. */ +#undef GNULIB_TEST_FCHDIR + +/* Define to 1 when the gnulib module fcntl should be tested. */ +#undef GNULIB_TEST_FCNTL + +/* Define to 1 when the gnulib module fdopendir should be tested. */ +#undef GNULIB_TEST_FDOPENDIR + +/* Define to 1 when the gnulib module fflush should be tested. */ +#undef GNULIB_TEST_FFLUSH + +/* Define to 1 when the gnulib module fnmatch should be tested. */ +#undef GNULIB_TEST_FNMATCH + +/* Define to 1 when the gnulib module fopen should be tested. */ +#undef GNULIB_TEST_FOPEN + +/* Define to 1 when the gnulib module fpurge should be tested. */ +#undef GNULIB_TEST_FPURGE + +/* Define to 1 when the gnulib module free-posix should be tested. */ +#undef GNULIB_TEST_FREE_POSIX + +/* Define to 1 when the gnulib module fseek should be tested. */ +#undef GNULIB_TEST_FSEEK + +/* Define to 1 when the gnulib module fseeko should be tested. */ +#undef GNULIB_TEST_FSEEKO + +/* Define to 1 when the gnulib module fstat should be tested. */ +#undef GNULIB_TEST_FSTAT + +/* Define to 1 when the gnulib module fstatat should be tested. */ +#undef GNULIB_TEST_FSTATAT + +/* Define to 1 when the gnulib module ftell should be tested. */ +#undef GNULIB_TEST_FTELL + +/* Define to 1 when the gnulib module ftello should be tested. */ +#undef GNULIB_TEST_FTELLO + +/* Define to 1 when the gnulib module futimens should be tested. */ +#undef GNULIB_TEST_FUTIMENS + +/* Define to 1 when the gnulib module getaddrinfo should be tested. */ +#undef GNULIB_TEST_GETADDRINFO + +/* Define to 1 when the gnulib module getcwd should be tested. */ +#undef GNULIB_TEST_GETCWD + +/* Define to 1 when the gnulib module getdelim should be tested. */ +#undef GNULIB_TEST_GETDELIM + +/* Define to 1 when the gnulib module getdtablesize should be tested. */ +#undef GNULIB_TEST_GETDTABLESIZE + +/* Define to 1 when the gnulib module getgroups should be tested. */ +#undef GNULIB_TEST_GETGROUPS + +/* Define to 1 when the gnulib module getline should be tested. */ +#undef GNULIB_TEST_GETLINE + +/* Define to 1 when the gnulib module getopt-posix should be tested. */ +#undef GNULIB_TEST_GETOPT_POSIX + +/* Define to 1 when the gnulib module getpass should be tested. */ +#undef GNULIB_TEST_GETPASS + +/* Define to 1 when the gnulib module getpeername should be tested. */ +#undef GNULIB_TEST_GETPEERNAME + +/* Define to 1 when the gnulib module getrandom should be tested. */ +#undef GNULIB_TEST_GETRANDOM + +/* Define to 1 when the gnulib module getsockname should be tested. */ +#undef GNULIB_TEST_GETSOCKNAME + +/* Define to 1 when the gnulib module gettimeofday should be tested. */ +#undef GNULIB_TEST_GETTIMEOFDAY + +/* Define to 1 when the gnulib module group-member should be tested. */ +#undef GNULIB_TEST_GROUP_MEMBER + +/* Define to 1 when the gnulib module ioctl should be tested. */ +#undef GNULIB_TEST_IOCTL + +/* Define to 1 when the gnulib module iswblank should be tested. */ +#undef GNULIB_TEST_ISWBLANK + +/* Define to 1 when the gnulib module iswdigit should be tested. */ +#undef GNULIB_TEST_ISWDIGIT + +/* Define to 1 when the gnulib module iswxdigit should be tested. */ +#undef GNULIB_TEST_ISWXDIGIT + +/* Define to 1 when the gnulib module link should be tested. */ +#undef GNULIB_TEST_LINK + +/* Define to 1 when the gnulib module listen should be tested. */ +#undef GNULIB_TEST_LISTEN + +/* Define to 1 when the gnulib module localeconv should be tested. */ +#undef GNULIB_TEST_LOCALECONV + +/* Define to 1 when the gnulib module lseek should be tested. */ +#undef GNULIB_TEST_LSEEK + +/* Define to 1 when the gnulib module lstat should be tested. */ +#undef GNULIB_TEST_LSTAT + +/* Define to 1 when the gnulib module malloc-posix should be tested. */ +#undef GNULIB_TEST_MALLOC_POSIX + +/* Define to 1 when the gnulib module mbrtowc should be tested. */ +#undef GNULIB_TEST_MBRTOWC + +/* Define to 1 when the gnulib module mbsinit should be tested. */ +#undef GNULIB_TEST_MBSINIT + +/* Define to 1 when the gnulib module mbsrtowcs should be tested. */ +#undef GNULIB_TEST_MBSRTOWCS + +/* Define to 1 when the gnulib module mbtowc should be tested. */ +#undef GNULIB_TEST_MBTOWC + +/* Define to 1 when the gnulib module memchr should be tested. */ +#undef GNULIB_TEST_MEMCHR + +/* Define to 1 when the gnulib module mempcpy should be tested. */ +#undef GNULIB_TEST_MEMPCPY + +/* Define to 1 when the gnulib module memrchr should be tested. */ +#undef GNULIB_TEST_MEMRCHR + +/* Define to 1 when the gnulib module mkdir should be tested. */ +#undef GNULIB_TEST_MKDIR + +/* Define to 1 when the gnulib module mkostemp should be tested. */ +#undef GNULIB_TEST_MKOSTEMP + +/* Define to 1 when the gnulib module mkstemp should be tested. */ +#undef GNULIB_TEST_MKSTEMP + +/* Define to 1 when the gnulib module mktime should be tested. */ +#undef GNULIB_TEST_MKTIME + +/* Define to 1 when the gnulib module nanosleep should be tested. */ +#undef GNULIB_TEST_NANOSLEEP + +/* Define to 1 when the gnulib module nl_langinfo should be tested. */ +#undef GNULIB_TEST_NL_LANGINFO + +/* Define to 1 when the gnulib module open should be tested. */ +#undef GNULIB_TEST_OPEN + +/* Define to 1 when the gnulib module openat should be tested. */ +#undef GNULIB_TEST_OPENAT + +/* Define to 1 when the gnulib module opendir should be tested. */ +#undef GNULIB_TEST_OPENDIR + +/* Define to 1 when the gnulib module pipe should be tested. */ +#undef GNULIB_TEST_PIPE + +/* Define to 1 when the gnulib module pipe2 should be tested. */ +#undef GNULIB_TEST_PIPE2 + +/* Define to 1 when the gnulib module posix_spawn should be tested. */ +#undef GNULIB_TEST_POSIX_SPAWN + +/* Define to 1 when the gnulib module posix_spawnattr_destroy should be + tested. */ +#undef GNULIB_TEST_POSIX_SPAWNATTR_DESTROY + +/* Define to 1 when the gnulib module posix_spawnattr_init should be tested. + */ +#undef GNULIB_TEST_POSIX_SPAWNATTR_INIT + +/* Define to 1 when the gnulib module posix_spawnattr_setflags should be + tested. */ +#undef GNULIB_TEST_POSIX_SPAWNATTR_SETFLAGS + +/* Define to 1 when the gnulib module posix_spawnattr_setpgroup should be + tested. */ +#undef GNULIB_TEST_POSIX_SPAWNATTR_SETPGROUP + +/* Define to 1 when the gnulib module posix_spawnattr_setsigmask should be + tested. */ +#undef GNULIB_TEST_POSIX_SPAWNATTR_SETSIGMASK + +/* Define to 1 when the gnulib module posix_spawnp should be tested. */ +#undef GNULIB_TEST_POSIX_SPAWNP + +/* Define to 1 when the gnulib module posix_spawn_file_actions_addchdir should + be tested. */ +#undef GNULIB_TEST_POSIX_SPAWN_FILE_ACTIONS_ADDCHDIR + +/* Define to 1 when the gnulib module posix_spawn_file_actions_addclose should + be tested. */ +#undef GNULIB_TEST_POSIX_SPAWN_FILE_ACTIONS_ADDCLOSE + +/* Define to 1 when the gnulib module posix_spawn_file_actions_adddup2 should + be tested. */ +#undef GNULIB_TEST_POSIX_SPAWN_FILE_ACTIONS_ADDDUP2 + +/* Define to 1 when the gnulib module posix_spawn_file_actions_addopen should + be tested. */ +#undef GNULIB_TEST_POSIX_SPAWN_FILE_ACTIONS_ADDOPEN + +/* Define to 1 when the gnulib module posix_spawn_file_actions_destroy should + be tested. */ +#undef GNULIB_TEST_POSIX_SPAWN_FILE_ACTIONS_DESTROY + +/* Define to 1 when the gnulib module posix_spawn_file_actions_init should be + tested. */ +#undef GNULIB_TEST_POSIX_SPAWN_FILE_ACTIONS_INIT + +/* Define to 1 when the gnulib module raise should be tested. */ +#undef GNULIB_TEST_RAISE + +/* Define to 1 when the gnulib module rawmemchr should be tested. */ +#undef GNULIB_TEST_RAWMEMCHR + +/* Define to 1 when the gnulib module readdir should be tested. */ +#undef GNULIB_TEST_READDIR + +/* Define to 1 when the gnulib module readlink should be tested. */ +#undef GNULIB_TEST_READLINK + +/* Define to 1 when the gnulib module realloc-posix should be tested. */ +#undef GNULIB_TEST_REALLOC_POSIX + +/* Define to 1 when the gnulib module recv should be tested. */ +#undef GNULIB_TEST_RECV + +/* Define to 1 when the gnulib module rewinddir should be tested. */ +#undef GNULIB_TEST_REWINDDIR + +/* Define to 1 when the gnulib module secure_getenv should be tested. */ +#undef GNULIB_TEST_SECURE_GETENV + +/* Define to 1 when the gnulib module select should be tested. */ +#undef GNULIB_TEST_SELECT + +/* Define to 1 when the gnulib module send should be tested. */ +#undef GNULIB_TEST_SEND + +/* Define to 1 when the gnulib module setlocale_null should be tested. */ +#undef GNULIB_TEST_SETLOCALE_NULL + +/* Define to 1 when the gnulib module setsockopt should be tested. */ +#undef GNULIB_TEST_SETSOCKOPT + +/* Define to 1 when the gnulib module sigaction should be tested. */ +#undef GNULIB_TEST_SIGACTION + +/* Define to 1 when the gnulib module sigprocmask should be tested. */ +#undef GNULIB_TEST_SIGPROCMASK + +/* Define to 1 when the gnulib module snprintf should be tested. */ +#undef GNULIB_TEST_SNPRINTF + +/* Define to 1 when the gnulib module socket should be tested. */ +#undef GNULIB_TEST_SOCKET + +/* Define to 1 when the gnulib module stat should be tested. */ +#undef GNULIB_TEST_STAT + +/* Define to 1 when the gnulib module stpcpy should be tested. */ +#undef GNULIB_TEST_STPCPY + +/* Define to 1 when the gnulib module strchrnul should be tested. */ +#undef GNULIB_TEST_STRCHRNUL + +/* Define to 1 when the gnulib module strdup should be tested. */ +#undef GNULIB_TEST_STRDUP + +/* Define to 1 when the gnulib module strerror should be tested. */ +#undef GNULIB_TEST_STRERROR + +/* Define to 1 when the gnulib module strerror_r should be tested. */ +#undef GNULIB_TEST_STRERROR_R + +/* Define to 1 when the gnulib module strndup should be tested. */ +#undef GNULIB_TEST_STRNDUP + +/* Define to 1 when the gnulib module strnlen should be tested. */ +#undef GNULIB_TEST_STRNLEN + +/* Define to 1 when the gnulib module strpbrk should be tested. */ +#undef GNULIB_TEST_STRPBRK + +/* Define to 1 when the gnulib module strptime should be tested. */ +#undef GNULIB_TEST_STRPTIME + +/* Define to 1 when the gnulib module strtok_r should be tested. */ +#undef GNULIB_TEST_STRTOK_R + +/* Define to 1 when the gnulib module strtoll should be tested. */ +#undef GNULIB_TEST_STRTOLL + +/* Define to 1 when the gnulib module symlink should be tested. */ +#undef GNULIB_TEST_SYMLINK + +/* Define to 1 when the gnulib module timegm should be tested. */ +#undef GNULIB_TEST_TIMEGM + +/* Define to 1 when the gnulib module time_r should be tested. */ +#undef GNULIB_TEST_TIME_R + +/* Define to 1 when the gnulib module uninorm/u8-normalize should be tested. + */ +#undef GNULIB_TEST_UNINORM_U8_NORMALIZE + +/* Define to 1 when the gnulib module unlink should be tested. */ +#undef GNULIB_TEST_UNLINK + +/* Define to 1 when the gnulib module utime should be tested. */ +#undef GNULIB_TEST_UTIME + +/* Define to 1 when the gnulib module vasprintf should be tested. */ +#undef GNULIB_TEST_VASPRINTF + +/* Define to 1 when the gnulib module vsnprintf should be tested. */ +#undef GNULIB_TEST_VSNPRINTF + +/* Define to 1 when the gnulib module waitpid should be tested. */ +#undef GNULIB_TEST_WAITPID + +/* Define to 1 when the gnulib module wcrtomb should be tested. */ +#undef GNULIB_TEST_WCRTOMB + +/* Define to 1 when the gnulib module wcwidth should be tested. */ +#undef GNULIB_TEST_WCWIDTH + +/* Define to 1 when the gnulib module wmemchr should be tested. */ +#undef GNULIB_TEST_WMEMCHR + +/* Define to 1 when the gnulib module wmempcpy should be tested. */ +#undef GNULIB_TEST_WMEMPCPY + +/* Define to 1 when the gnulib module write should be tested. */ +#undef GNULIB_TEST_WRITE + +/* Define to a C preprocessor expression that evaluates to 1 or 0, depending + whether the gnulib module unistr/u8-mbtouc-unsafe shall be considered + present. */ +#undef GNULIB_UNISTR_U8_MBTOUC_UNSAFE + +/* Define to a C preprocessor expression that evaluates to 1 or 0, depending + whether the gnulib module unistr/u8-uctomb shall be considered present. */ +#undef GNULIB_UNISTR_U8_UCTOMB + +/* Define to a C preprocessor expression that evaluates to 1 or 0, depending + whether the gnulib module xalloc shall be considered present. */ +#undef GNULIB_XALLOC + +/* Define to a C preprocessor expression that evaluates to 1 or 0, depending + whether the gnulib module xalloc-die shall be considered present. */ +#undef GNULIB_XALLOC_DIE + +/* Define to 1 if you have 'alloca' after including , a header that + may be supplied by this distribution. */ +#undef HAVE_ALLOCA + +/* Define to 1 if works. */ +#undef HAVE_ALLOCA_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_ARPA_INET_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_BCRYPT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_BP_SYM_H + +/* Define to 1 if you have the `btowc' function. */ +#undef HAVE_BTOWC + +/* Define to 1 if nanosleep mishandles large arguments. */ +#undef HAVE_BUG_BIG_NANOSLEEP + +/* Define to 1 if you have the header file. */ +#undef HAVE_BYTESWAP_H + +/* Define to 1 if you have the `canonicalize_file_name' function. */ +#undef HAVE_CANONICALIZE_FILE_NAME + +/* Define to 1 if you have the `catgets' function. */ +#undef HAVE_CATGETS + +/* Define to 1 if you have the Mac OS X function CFLocaleCopyCurrent in the + CoreFoundation framework. */ +#undef HAVE_CFLOCALECOPYCURRENT + +/* Define to 1 if you have the Mac OS X function CFPreferencesCopyAppValue in + the CoreFoundation framework. */ +#undef HAVE_CFPREFERENCESCOPYAPPVALUE + +/* Define to 1 if you have the `clock_gettime' function. */ +#undef HAVE_CLOCK_GETTIME + +/* Define to 1 if you have the `clock_settime' function. */ +#undef HAVE_CLOCK_SETTIME + +/* Define to 1 if you have the `closedir' function. */ +#undef HAVE_CLOSEDIR + +/* Define to 1 if you have the `confstr' function. */ +#undef HAVE_CONFSTR + +/* Define to 1 if you have the header file. */ +#undef HAVE_CRTDEFS_H + +/* Define if the GNU dcgettext() function is already present or preinstalled. + */ +#undef HAVE_DCGETTEXT + +/* Define to 1 if you have the declaration of `alarm', and to 0 if you don't. + */ +#undef HAVE_DECL_ALARM + +/* Define to 1 if you have the declaration of `clearerr_unlocked', and to 0 if + you don't. */ +#undef HAVE_DECL_CLEARERR_UNLOCKED + +/* Define to 1 if you have the declaration of `dirfd', and to 0 if you don't. + */ +#undef HAVE_DECL_DIRFD + +/* Define to 1 if you have the declaration of `ecvt', and to 0 if you don't. + */ +#undef HAVE_DECL_ECVT + +/* Define to 1 if you have the declaration of `execvpe', and to 0 if you + don't. */ +#undef HAVE_DECL_EXECVPE + +/* Define to 1 if you have the declaration of `fchdir', and to 0 if you don't. + */ +#undef HAVE_DECL_FCHDIR + +/* Define to 1 if you have the declaration of `fcloseall', and to 0 if you + don't. */ +#undef HAVE_DECL_FCLOSEALL + +/* Define to 1 if you have the declaration of `fcvt', and to 0 if you don't. + */ +#undef HAVE_DECL_FCVT + +/* Define to 1 if you have the declaration of `fdopendir', and to 0 if you + don't. */ +#undef HAVE_DECL_FDOPENDIR + +/* Define to 1 if you have the declaration of `feof_unlocked', and to 0 if you + don't. */ +#undef HAVE_DECL_FEOF_UNLOCKED + +/* Define to 1 if you have the declaration of `ferror_unlocked', and to 0 if + you don't. */ +#undef HAVE_DECL_FERROR_UNLOCKED + +/* Define to 1 if you have the declaration of `fflush_unlocked', and to 0 if + you don't. */ +#undef HAVE_DECL_FFLUSH_UNLOCKED + +/* Define to 1 if you have the declaration of `fgets_unlocked', and to 0 if + you don't. */ +#undef HAVE_DECL_FGETS_UNLOCKED + +/* Define to 1 if you have the declaration of `flockfile', and to 0 if you + don't. */ +#undef HAVE_DECL_FLOCKFILE + +/* Define to 1 if you have the declaration of `fpurge', and to 0 if you don't. + */ +#undef HAVE_DECL_FPURGE + +/* Define to 1 if you have the declaration of `fputc_unlocked', and to 0 if + you don't. */ +#undef HAVE_DECL_FPUTC_UNLOCKED + +/* Define to 1 if you have the declaration of `fputs_unlocked', and to 0 if + you don't. */ +#undef HAVE_DECL_FPUTS_UNLOCKED + +/* Define to 1 if you have the declaration of `fread_unlocked', and to 0 if + you don't. */ +#undef HAVE_DECL_FREAD_UNLOCKED + +/* Define to 1 if you have the declaration of `freeaddrinfo', and to 0 if you + don't. */ +#undef HAVE_DECL_FREEADDRINFO + +/* Define to 1 if you have the declaration of `fseeko', and to 0 if you don't. + */ +#undef HAVE_DECL_FSEEKO + +/* Define to 1 if you have the declaration of `ftello', and to 0 if you don't. + */ +#undef HAVE_DECL_FTELLO + +/* Define to 1 if you have the declaration of `funlockfile', and to 0 if you + don't. */ +#undef HAVE_DECL_FUNLOCKFILE + +/* Define to 1 if you have the declaration of `fwrite_unlocked', and to 0 if + you don't. */ +#undef HAVE_DECL_FWRITE_UNLOCKED + +/* Define to 1 if you have the declaration of `gai_strerror', and to 0 if you + don't. */ +#undef HAVE_DECL_GAI_STRERROR + +/* Define to 1 if you have the declaration of `gai_strerrorA', and to 0 if you + don't. */ +#undef HAVE_DECL_GAI_STRERRORA + +/* Define to 1 if you have the declaration of `gcvt', and to 0 if you don't. + */ +#undef HAVE_DECL_GCVT + +/* Define to 1 if you have the declaration of `getaddrinfo', and to 0 if you + don't. */ +#undef HAVE_DECL_GETADDRINFO + +/* Define to 1 if you have the declaration of `getchar_unlocked', and to 0 if + you don't. */ +#undef HAVE_DECL_GETCHAR_UNLOCKED + +/* Define to 1 if you have the declaration of `getcwd', and to 0 if you don't. + */ +#undef HAVE_DECL_GETCWD + +/* Define to 1 if you have the declaration of `getc_unlocked', and to 0 if you + don't. */ +#undef HAVE_DECL_GETC_UNLOCKED + +/* Define to 1 if you have the declaration of `getdelim', and to 0 if you + don't. */ +#undef HAVE_DECL_GETDELIM + +/* Define to 1 if you have the declaration of `getdtablesize', and to 0 if you + don't. */ +#undef HAVE_DECL_GETDTABLESIZE + +/* Define to 1 if you have the declaration of `getline', and to 0 if you + don't. */ +#undef HAVE_DECL_GETLINE + +/* Define to 1 if you have the declaration of `getnameinfo', and to 0 if you + don't. */ +#undef HAVE_DECL_GETNAMEINFO + +/* Define to 1 if you have the declaration of `h_errno', and to 0 if you + don't. */ +#undef HAVE_DECL_H_ERRNO + +/* Define to 1 if you have the declaration of `inet_ntop', and to 0 if you + don't. */ +#undef HAVE_DECL_INET_NTOP + +/* Define to 1 if you have the declaration of `isblank', and to 0 if you + don't. */ +#undef HAVE_DECL_ISBLANK + +/* Define to 1 if you have the declaration of `iswblank', and to 0 if you + don't. */ +#undef HAVE_DECL_ISWBLANK + +/* Define to 1 if you have the declaration of `localtime_r', and to 0 if you + don't. */ +#undef HAVE_DECL_LOCALTIME_R + +/* Define to 1 if you have the declaration of `mbrtowc', and to 0 if you + don't. */ +#undef HAVE_DECL_MBRTOWC + +/* Define to 1 if you have the declaration of `mbsinit', and to 0 if you + don't. */ +#undef HAVE_DECL_MBSINIT + +/* Define to 1 if you have the declaration of `mbsrtowcs', and to 0 if you + don't. */ +#undef HAVE_DECL_MBSRTOWCS + +/* Define to 1 if you have the declaration of `memrchr', and to 0 if you + don't. */ +#undef HAVE_DECL_MEMRCHR + +/* Define to 1 if you have the declaration of `program_invocation_name', and + to 0 if you don't. */ +#undef HAVE_DECL_PROGRAM_INVOCATION_NAME + +/* Define to 1 if you have the declaration of `program_invocation_short_name', + and to 0 if you don't. */ +#undef HAVE_DECL_PROGRAM_INVOCATION_SHORT_NAME + +/* Define to 1 if you have the declaration of `putchar_unlocked', and to 0 if + you don't. */ +#undef HAVE_DECL_PUTCHAR_UNLOCKED + +/* Define to 1 if you have the declaration of `putc_unlocked', and to 0 if you + don't. */ +#undef HAVE_DECL_PUTC_UNLOCKED + +/* Define to 1 if you have the declaration of `snprintf', and to 0 if you + don't. */ +#undef HAVE_DECL_SNPRINTF + +/* Define to 1 if you have the declaration of `strdup', and to 0 if you don't. + */ +#undef HAVE_DECL_STRDUP + +/* Define to 1 if you have the declaration of `strerror_r', and to 0 if you + don't. */ +#undef HAVE_DECL_STRERROR_R + +/* Define to 1 if you have the declaration of `strncasecmp', and to 0 if you + don't. */ +#undef HAVE_DECL_STRNCASECMP + +/* Define to 1 if you have the declaration of `strndup', and to 0 if you + don't. */ +#undef HAVE_DECL_STRNDUP + +/* Define to 1 if you have the declaration of `strnlen', and to 0 if you + don't. */ +#undef HAVE_DECL_STRNLEN + +/* Define to 1 if you have the declaration of `strtok_r', and to 0 if you + don't. */ +#undef HAVE_DECL_STRTOK_R + +/* Define to 1 if you have the declaration of `towlower', and to 0 if you + don't. */ +#undef HAVE_DECL_TOWLOWER + +/* Define to 1 if you have the declaration of `vsnprintf', and to 0 if you + don't. */ +#undef HAVE_DECL_VSNPRINTF + +/* Define to 1 if you have the declaration of `wcrtomb', and to 0 if you + don't. */ +#undef HAVE_DECL_WCRTOMB + +/* Define to 1 if you have the declaration of `wcsdup', and to 0 if you don't. + */ +#undef HAVE_DECL_WCSDUP + +/* Define to 1 if you have the declaration of `wcwidth', and to 0 if you + don't. */ +#undef HAVE_DECL_WCWIDTH + +/* Define to 1 if you have the declaration of `_fseeki64', and to 0 if you + don't. */ +#undef HAVE_DECL__FSEEKI64 + +/* Define to 1 if you have the declaration of `_snprintf', and to 0 if you + don't. */ +#undef HAVE_DECL__SNPRINTF + +/* Define to 1 if you have the declaration of `__argv', and to 0 if you don't. + */ +#undef HAVE_DECL___ARGV + +/* Define to 1 if you have the declaration of `__fsetlocking', and to 0 if you + don't. */ +#undef HAVE_DECL___FSETLOCKING + +/* Define to 1 if you have the header file. */ +#undef HAVE_DIRENT_H + +/* Define to 1 if you have the `dirfd' function. */ +#undef HAVE_DIRFD + +/* Define to 1 if you have the header file. */ +#undef HAVE_DLFCN_H + +/* Define to 1 if you have the `drand48' function. */ +#undef HAVE_DRAND48 + +/* Define if you have the declaration of environ. */ +#undef HAVE_ENVIRON_DECL + +/* Define to 1 if you have the `faccessat' function. */ +#undef HAVE_FACCESSAT + +/* Define to 1 if you have the `fchdir' function. */ +#undef HAVE_FCHDIR + +/* Define to 1 if you have the `fcntl' function. */ +#undef HAVE_FCNTL + +/* Define to 1 if you have the `fdopendir' function. */ +#undef HAVE_FDOPENDIR + +/* Define to 1 if you have the header file. */ +#undef HAVE_FEATURES_H + +/* Define to 1 if you have the `flock' function. */ +#undef HAVE_FLOCK + +/* Define to 1 if you have the `flockfile' function. */ +#undef HAVE_FLOCKFILE + +/* Define to 1 if you have the `fmemopen' function. */ +#undef HAVE_FMEMOPEN + +/* Define to 1 if you have the `fnmatch' function. */ +#undef HAVE_FNMATCH + +/* Define to 1 if you have the header file. */ +#undef HAVE_FNMATCH_H + +/* Define to 1 if you have the `fpurge' function. */ +#undef HAVE_FPURGE + +/* Define to 1 if fseeko (and presumably ftello) exists and is declared. */ +#undef HAVE_FSEEKO + +/* Define to 1 if you have the `fstatat' function. */ +#undef HAVE_FSTATAT + +/* Define to 1 if you have the `ftello' function. */ +#undef HAVE_FTELLO + +/* Define to 1 if you have the `funlockfile' function. */ +#undef HAVE_FUNLOCKFILE + +/* Define to 1 if you have the `futimens' function. */ +#undef HAVE_FUTIMENS + +/* Define to 1 if you have the `futimes' function. */ +#undef HAVE_FUTIMES + +/* Define to 1 if you have the `futimesat' function. */ +#undef HAVE_FUTIMESAT + +/* Define to 1 if getaddrinfo exists, or to 0 otherwise. */ +#undef HAVE_GETADDRINFO + +/* Define to 1 if getcwd works, but with shorter paths than is generally + tested with the replacement. */ +#undef HAVE_GETCWD_SHORTER + +/* Define to 1 if you have the `getdelim' function. */ +#undef HAVE_GETDELIM + +/* Define to 1 if you have the `getdtablesize' function. */ +#undef HAVE_GETDTABLESIZE + +/* Define to 1 if you have the `getegid' function. */ +#undef HAVE_GETEGID + +/* Define to 1 if you have the `geteuid' function. */ +#undef HAVE_GETEUID + +/* Define to 1 if you have the `getexecname' function. */ +#undef HAVE_GETEXECNAME + +/* Define to 1 if you have the `getgid' function. */ +#undef HAVE_GETGID + +/* Define to 1 if your system has a working `getgroups' function. */ +#undef HAVE_GETGROUPS + +/* Define to 1 if you have the `gethostbyname' function. */ +#undef HAVE_GETHOSTBYNAME + +/* Define to 1 if you have the header file. */ +#undef HAVE_GETOPT_H + +/* Define to 1 if you have the `getopt_long_only' function. */ +#undef HAVE_GETOPT_LONG_ONLY + +/* Define to 1 if you have the `getpagesize' function. */ +#undef HAVE_GETPAGESIZE + +/* Define to 1 if you have the `getpass' function. */ +#undef HAVE_GETPASS + +/* Define to 1 if you have the `getprogname' function. */ +#undef HAVE_GETPROGNAME + +/* Define to 1 if you have the `getrandom' function. */ +#undef HAVE_GETRANDOM + +/* Define to 1 if you have the `getservbyname' function. */ +#undef HAVE_GETSERVBYNAME + +/* Define if the GNU gettext() function is already present or preinstalled. */ +#undef HAVE_GETTEXT + +/* Define to 1 if you have the `gettimeofday' function. */ +#undef HAVE_GETTIMEOFDAY + +/* Define to 1 if you have the `getuid' function. */ +#undef HAVE_GETUID + +/* Define to 1 if you have the `gnutls_priority_set_direct' function. */ +#undef HAVE_GNUTLS_PRIORITY_SET_DIRECT + +/* Define if GPGME is available. */ +#undef HAVE_GPGME + +/* Define if you have the iconv() function and it works. */ +#undef HAVE_ICONV + +/* Define to 1 if you have the header file. */ +#undef HAVE_ICONV_H + +/* Define to 1 if you have the `inet_ntop' function. */ +#undef HAVE_INET_NTOP + +/* Define to 1 if the compiler supports one of the keywords 'inline', + '__inline__', '__inline' and effectively inlines functions marked as such. + */ +#undef HAVE_INLINE + +/* Define to 1 if the system has the type `int64_t'. */ +#undef HAVE_INT64_T + +/* Define if you have the 'intmax_t' type in or . */ +#undef HAVE_INTMAX_T + +/* Define to 1 if the system has the type `intptr_t'. */ +#undef HAVE_INTPTR_T + +/* Define to 1 if you have the header file. */ +#undef HAVE_INTTYPES_H + +/* Define if exists, doesn't clash with , and + declares uintmax_t. */ +#undef HAVE_INTTYPES_H_WITH_UINTMAX + +/* Define to 1 if you have the `ioctl' function. */ +#undef HAVE_IOCTL + +/* Define to 1 if defines AF_INET. */ +#undef HAVE_IPV4 + +/* Define to 1 if defines AF_INET6. */ +#undef HAVE_IPV6 + +/* Define to 1 if you have the `isatty' function. */ +#undef HAVE_ISATTY + +/* Define to 1 if you have the `isblank' function. */ +#undef HAVE_ISBLANK + +/* Define to 1 if you have the `issetugid' function. */ +#undef HAVE_ISSETUGID + +/* Define to 1 if you have the `iswblank' function. */ +#undef HAVE_ISWBLANK + +/* Define to 1 if you have the `iswcntrl' function. */ +#undef HAVE_ISWCNTRL + +/* Define to 1 if you have the `iswctype' function. */ +#undef HAVE_ISWCTYPE + +/* Define if you have and nl_langinfo(CODESET). */ +#undef HAVE_LANGINFO_CODESET + +/* Define to 1 if you have the header file. */ +#undef HAVE_LANGINFO_H + +/* Define if libcares is available. */ +#undef HAVE_LIBCARES + +/* Define to 1 if you have the `dl' library (-ldl). */ +#undef HAVE_LIBDL + +/* Define to 1 if you have the `eay32' library (-leay32). */ +#undef HAVE_LIBEAY32 + +/* Define if you have the libgnutls library. */ +#undef HAVE_LIBGNUTLS + +/* Define to 1 if you have the header file. */ +#undef HAVE_LIBINTL_H + +/* Define if libpcre is available. */ +#undef HAVE_LIBPCRE + +/* Define if libpcre2 is available. */ +#undef HAVE_LIBPCRE2 + +/* PSL support enabled */ +#undef HAVE_LIBPSL + +/* Define if you have the libssl library. */ +#undef HAVE_LIBSSL + +/* Define to 1 if you have the `ssl32' library (-lssl32). */ +#undef HAVE_LIBSSL32 + +/* Define if you have the libunistring library. */ +#undef HAVE_LIBUNISTRING + +/* Define if using libuuid. */ +#undef HAVE_LIBUUID + +/* Define if using zlib. */ +#undef HAVE_LIBZ + +/* Define to 1 if the bcrypt library is guaranteed to be present. */ +#undef HAVE_LIB_BCRYPT + +/* Define to 1 if you have the header file. */ +#undef HAVE_LIMITS_H + +/* Define to 1 if you have the `link' function. */ +#undef HAVE_LINK + +/* Define to 1 if you have 'struct sockaddr_alg' defined. */ +#undef HAVE_LINUX_IF_ALG_H + +/* Define to 1 if you have the `localtime_r' function. */ +#undef HAVE_LOCALTIME_R + +/* Define to 1 if the system has the type 'long long int'. */ +#undef HAVE_LONG_LONG_INT + +/* Define to 1 if you have the `lstat' function. */ +#undef HAVE_LSTAT + +/* Define to 1 if you have the `lutimes' function. */ +#undef HAVE_LUTIMES + +/* Define to 1 if you have the header file. */ +#undef HAVE_MALLOC_H + +/* Define if the 'malloc' function is POSIX compliant. */ +#undef HAVE_MALLOC_POSIX + +/* Define to 1 if mmap()'s MAP_ANONYMOUS flag is available after including + config.h and . */ +#undef HAVE_MAP_ANONYMOUS + +/* Define to 1 if you have the `mbrtowc' function. */ +#undef HAVE_MBRTOWC + +/* Define to 1 if you have the `mbsinit' function. */ +#undef HAVE_MBSINIT + +/* Define to 1 if you have the `mbsrtowcs' function. */ +#undef HAVE_MBSRTOWCS + +/* Define to 1 if declares mbstate_t. */ +#undef HAVE_MBSTATE_T + +/* Define to 1 if you have the `mbtowc' function. */ +#undef HAVE_MBTOWC + +/* Define to 1 if you have the `mempcpy' function. */ +#undef HAVE_MEMPCPY + +/* Define to 1 if you have the `memrchr' function. */ +#undef HAVE_MEMRCHR + +/* Define if using metalink. */ +#undef HAVE_METALINK + +/* Define to 1 if getcwd minimally works, that is, its result can be trusted + when it succeeds. */ +#undef HAVE_MINIMALLY_WORKING_GETCWD + +/* Define to 1 if you have the header file. */ +#undef HAVE_MINIX_CONFIG_H + +/* Define to 1 if defines the MIN and MAX macros. */ +#undef HAVE_MINMAX_IN_LIMITS_H + +/* Define to 1 if defines the MIN and MAX macros. */ +#undef HAVE_MINMAX_IN_SYS_PARAM_H + +/* Define to 1 if you have the `mkostemp' function. */ +#undef HAVE_MKOSTEMP + +/* Define to 1 if you have the `mkstemp' function. */ +#undef HAVE_MKSTEMP + +/* Define to 1 if you have a working `mmap' system call. */ +#undef HAVE_MMAP + +/* Define to 1 if you have the `mprotect' function. */ +#undef HAVE_MPROTECT + +/* Define to 1 on MSVC platforms that have the "invalid parameter handler" + concept. */ +#undef HAVE_MSVC_INVALID_PARAMETER_HANDLER + +/* Define to 1 if you have the header file. */ +#undef HAVE_NETDB_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_NETINET_IN_H + +/* Use libnettle */ +#undef HAVE_NETTLE + +/* Define to 1 if you have the `nl_langinfo' function. */ +#undef HAVE_NL_LANGINFO + +/* Define to 1 if you have the `openat' function. */ +#undef HAVE_OPENAT + +/* Define to 1 if you have the `opendir' function. */ +#undef HAVE_OPENDIR + +/* Define to 1 if libcrypto is used for MD5. */ +#undef HAVE_OPENSSL_MD5 + +/* Define to 1 if you have the header file. */ +#undef HAVE_OPENSSL_MD5_H + +/* Define to 1 if libcrypto is used for SHA1. */ +#undef HAVE_OPENSSL_SHA1 + +/* Define to 1 if libcrypto is used for SHA256. */ +#undef HAVE_OPENSSL_SHA256 + +/* Define to 1 if libcrypto is used for SHA512. */ +#undef HAVE_OPENSSL_SHA512 + +/* Define to 1 if you have the header file. */ +#undef HAVE_OPENSSL_SHA_H + +/* Define to 1 if getcwd works, except it sometimes fails when it shouldn't, + setting errno to ERANGE, ENAMETOOLONG, or ENOENT. */ +#undef HAVE_PARTLY_WORKING_GETCWD + +/* Define to 1 if you have the `pathconf' function. */ +#undef HAVE_PATHCONF + +/* Define to 1 if you have the header file. */ +#undef HAVE_PATHS_H + +/* Define to 1 if you have the `pipe' function. */ +#undef HAVE_PIPE + +/* Define to 1 if you have the `pipe2' function. */ +#undef HAVE_PIPE2 + +/* Define to 1 if you have the `posix_spawn' function. */ +#undef HAVE_POSIX_SPAWN + +/* Define to 1 if the system has the type `posix_spawnattr_t'. */ +#undef HAVE_POSIX_SPAWNATTR_T + +/* Define to 1 if you have the `posix_spawn_file_actions_addchdir' function. + */ +#undef HAVE_POSIX_SPAWN_FILE_ACTIONS_ADDCHDIR + +/* Define to 1 if you have the `posix_spawn_file_actions_addchdir_np' + function. */ +#undef HAVE_POSIX_SPAWN_FILE_ACTIONS_ADDCHDIR_NP + +/* Define to 1 if the system has the type `posix_spawn_file_actions_t'. */ +#undef HAVE_POSIX_SPAWN_FILE_ACTIONS_T + +/* Define to 1 if you have the `psl_latest' function. */ +#undef HAVE_PSL_LATEST + +/* Define if you have the header and the POSIX threads API. */ +#undef HAVE_PTHREAD_API + +/* Define if the defines PTHREAD_MUTEX_RECURSIVE. */ +#undef HAVE_PTHREAD_MUTEX_RECURSIVE + +/* Define if the POSIX multithreading library has read/write locks. */ +#undef HAVE_PTHREAD_RWLOCK + +/* Define if the 'pthread_rwlock_rdlock' function prefers a writer to a + reader. */ +#undef HAVE_PTHREAD_RWLOCK_RDLOCK_PREFER_WRITER + +/* Define to 1 if you have the header file. */ +#undef HAVE_PWD_H + +/* Define to 1 if you have the `raise' function. */ +#undef HAVE_RAISE + +/* Define to 1 if you have the `random' function. */ +#undef HAVE_RANDOM + +/* Define to 1 if you have the `RAND_egd' function. */ +#undef HAVE_RAND_EGD + +/* Define to 1 if you have the `rawmemchr' function. */ +#undef HAVE_RAWMEMCHR + +/* Define to 1 if you have the `readdir' function. */ +#undef HAVE_READDIR + +/* Define to 1 if you have the `readlink' function. */ +#undef HAVE_READLINK + +/* Define if the 'realloc' function is POSIX compliant. */ +#undef HAVE_REALLOC_POSIX + +/* Define to 1 if you have the `realpath' function. */ +#undef HAVE_REALPATH + +/* Define to 1 if you have the `rewinddir' function. */ +#undef HAVE_REWINDDIR + +/* Define to 1 if the system has the type `sa_family_t'. */ +#undef HAVE_SA_FAMILY_T + +/* Define to 1 if you have the header file. */ +#undef HAVE_SCHED_H + +/* Define to 1 if you have the `sched_setparam' function. */ +#undef HAVE_SCHED_SETPARAM + +/* Define to 1 if you have the `sched_setscheduler' function. */ +#undef HAVE_SCHED_SETSCHEDULER + +/* Define to 1 if you have the header file. */ +#undef HAVE_SDKDDKVER_H + +/* Define to 1 if you have the `secure_getenv' function. */ +#undef HAVE_SECURE_GETENV + +/* Define to 1 if you have the `setdtablesize' function. */ +#undef HAVE_SETDTABLESIZE + +/* Define to 1 if you have the `setegid' function. */ +#undef HAVE_SETEGID + +/* Define to 1 if you have the `seteuid' function. */ +#undef HAVE_SETEUID + +/* Define to 1 if you have the `shutdown' function. */ +#undef HAVE_SHUTDOWN + +/* Define to 1 if you have the `sigaction' function. */ +#undef HAVE_SIGACTION + +/* Define to 1 if you have the `sigaltstack' function. */ +#undef HAVE_SIGALTSTACK + +/* Define to 1 if you have the `sigblock' function. */ +#undef HAVE_SIGBLOCK + +/* Define to 1 if the system has the type `siginfo_t'. */ +#undef HAVE_SIGINFO_T + +/* Define to 1 if you have the `siginterrupt' function. */ +#undef HAVE_SIGINTERRUPT + +/* Define to 1 if 'sig_atomic_t' is a signed integer type. */ +#undef HAVE_SIGNED_SIG_ATOMIC_T + +/* Define to 1 if 'wchar_t' is a signed integer type. */ +#undef HAVE_SIGNED_WCHAR_T + +/* Define to 1 if 'wint_t' is a signed integer type. */ +#undef HAVE_SIGNED_WINT_T + +/* Define to 1 if you have the `sigsetjmp' function. */ +#undef HAVE_SIGSETJMP + +/* Define to 1 if the system has the type `sigset_t'. */ +#undef HAVE_SIGSET_T + +/* Define to 1 if the system has the type `sig_atomic_t'. */ +#undef HAVE_SIG_ATOMIC_T + +/* Define to 1 if you have the `sleep' function. */ +#undef HAVE_SLEEP + +/* Define to 1 if you have the `snprintf' function. */ +#undef HAVE_SNPRINTF + +/* Define if the return value of the snprintf function is the number of of + bytes (excluding the terminating NUL) that would have been produced if the + buffer had been large enough. */ +#undef HAVE_SNPRINTF_RETVAL_C99 + +/* Define if the string produced by the snprintf function is always NUL + terminated. */ +#undef HAVE_SNPRINTF_TRUNCATION_C99 + +/* Define if struct sockaddr_in6 has the sin6_scope_id member */ +#undef HAVE_SOCKADDR_IN6_SCOPE_ID + +/* Define to 1 if you have the header file. */ +#undef HAVE_SPAWN_H + +/* Define to 1 if stdbool.h conforms to C99. */ +#undef HAVE_STDBOOL_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STDINT_H + +/* Define if exists, doesn't clash with , and declares + uintmax_t. */ +#undef HAVE_STDINT_H_WITH_UINTMAX + +/* Define to 1 if you have the header file. */ +#undef HAVE_STDIO_EXT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STDIO_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STDLIB_H + +/* Define to 1 if you have the `stpcpy' function. */ +#undef HAVE_STPCPY + +/* Define to 1 if you have the `strcasecmp' function. */ +#undef HAVE_STRCASECMP + +/* Define to 1 if you have the `strchrnul' function. */ +#undef HAVE_STRCHRNUL + +/* Define to 1 if you have the `strdup' function. */ +#undef HAVE_STRDUP + +/* Define to 1 if you have the `strerror_r' function. */ +#undef HAVE_STRERROR_R + +/* Define to 1 if you have the header file. */ +#undef HAVE_STRINGS_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STRING_H + +/* Define to 1 if you have the `strlcpy' function. */ +#undef HAVE_STRLCPY + +/* Define to 1 if you have the `strncasecmp' function. */ +#undef HAVE_STRNCASECMP + +/* Define to 1 if you have the `strndup' function. */ +#undef HAVE_STRNDUP + +/* Define to 1 if you have the `strnlen' function. */ +#undef HAVE_STRNLEN + +/* Define to 1 if you have the `strpbrk' function. */ +#undef HAVE_STRPBRK + +/* Define to 1 if you have the `strptime' function. */ +#undef HAVE_STRPTIME + +/* Define to 1 if you have the `strtok_r' function. */ +#undef HAVE_STRTOK_R + +/* Define to 1 if you have the `strtol' function. */ +#undef HAVE_STRTOL + +/* Define to 1 if you have the `strtoll' function. */ +#undef HAVE_STRTOLL + +/* Define to 1 if the system has the type `struct addrinfo'. */ +#undef HAVE_STRUCT_ADDRINFO + +/* Define to 1 if `l_type' is a member of `struct flock'. */ +#undef HAVE_STRUCT_FLOCK_L_TYPE + +/* Define to 1 if `decimal_point' is a member of `struct lconv'. */ +#undef HAVE_STRUCT_LCONV_DECIMAL_POINT + +/* Define to 1 if `sa_sigaction' is a member of `struct sigaction'. */ +#undef HAVE_STRUCT_SIGACTION_SA_SIGACTION + +/* Define to 1 if the system has the type `struct sockaddr_in6'. */ +#undef HAVE_STRUCT_SOCKADDR_IN6 + +/* Define to 1 if `sa_len' is a member of `struct sockaddr'. */ +#undef HAVE_STRUCT_SOCKADDR_SA_LEN + +/* Define to 1 if the system has the type `struct sockaddr_storage'. */ +#undef HAVE_STRUCT_SOCKADDR_STORAGE + +/* Define to 1 if `ss_family' is a member of `struct sockaddr_storage'. */ +#undef HAVE_STRUCT_SOCKADDR_STORAGE_SS_FAMILY + +/* Define to 1 if `st_atimensec' is a member of `struct stat'. */ +#undef HAVE_STRUCT_STAT_ST_ATIMENSEC + +/* Define to 1 if `st_atimespec.tv_nsec' is a member of `struct stat'. */ +#undef HAVE_STRUCT_STAT_ST_ATIMESPEC_TV_NSEC + +/* Define to 1 if `st_atim.st__tim.tv_nsec' is a member of `struct stat'. */ +#undef HAVE_STRUCT_STAT_ST_ATIM_ST__TIM_TV_NSEC + +/* Define to 1 if `st_atim.tv_nsec' is a member of `struct stat'. */ +#undef HAVE_STRUCT_STAT_ST_ATIM_TV_NSEC + +/* Define to 1 if `st_birthtimensec' is a member of `struct stat'. */ +#undef HAVE_STRUCT_STAT_ST_BIRTHTIMENSEC + +/* Define to 1 if `st_birthtimespec.tv_nsec' is a member of `struct stat'. */ +#undef HAVE_STRUCT_STAT_ST_BIRTHTIMESPEC_TV_NSEC + +/* Define to 1 if `st_birthtim.tv_nsec' is a member of `struct stat'. */ +#undef HAVE_STRUCT_STAT_ST_BIRTHTIM_TV_NSEC + +/* Define to 1 if you have the `symlink' function. */ +#undef HAVE_SYMLINK + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_BITYPES_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_CDEFS_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_FILE_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_INTTYPES_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_IOCTL_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_MMAN_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_PARAM_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_RANDOM_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_SELECT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_SINGLE_THREADED_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_SOCKET_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_STAT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_TIME_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_TYPES_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_UIO_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_UTIME_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_WAIT_H + +/* Define to 1 if the system has the 'tcgetattr' function. */ +#undef HAVE_TCGETATTR + +/* Define to 1 if the system has the 'tcsetattr' function. */ +#undef HAVE_TCSETATTR + +/* Define to 1 if you have the header file. */ +#undef HAVE_TERMIOS_H + +/* Define to 1 if you have the `thrd_create' function. */ +#undef HAVE_THRD_CREATE + +/* Define to 1 if you have the header file. */ +#undef HAVE_THREADS_H + +/* Define to 1 if you have the `timegm' function. */ +#undef HAVE_TIMEGM + +/* Define if struct tm has the tm_gmtoff member. */ +#undef HAVE_TM_GMTOFF + +/* Define to 1 if you have the `towlower' function. */ +#undef HAVE_TOWLOWER + +/* Define to 1 if the system has the type `uint32_t'. */ +#undef HAVE_UINT32_T + +/* Define to 1 if the system has the type `uintptr_t'. */ +#undef HAVE_UINTPTR_T + +/* Define to 1 if you have the header file. */ +#undef HAVE_UNISTD_H + +/* Define to 1 if the system has the type 'unsigned long long int'. */ +#undef HAVE_UNSIGNED_LONG_LONG_INT + +/* Define to 1 if you have the `usleep' function. */ +#undef HAVE_USLEEP + +/* Define to 1 if you have the `utime' function. */ +#undef HAVE_UTIME + +/* Define to 1 if you have the `utimensat' function. */ +#undef HAVE_UTIMENSAT + +/* Define to 1 if you have the header file. */ +#undef HAVE_UTIME_H + +/* Define if uuid_create is available. */ +#undef HAVE_UUID_CREATE + +/* Define if you have a global __progname variable */ +#undef HAVE_VAR___PROGNAME + +/* Define to 1 if you have the `vasnprintf' function. */ +#undef HAVE_VASNPRINTF + +/* Define to 1 if you have the `vasprintf' function. */ +#undef HAVE_VASPRINTF + +/* Define to 1 if you have the `vfork' function. */ +#undef HAVE_VFORK + +/* Define to 1 or 0, depending whether the compiler supports simple visibility + declarations. */ +#undef HAVE_VISIBILITY + +/* Define to 1 if you have the `vsnprintf' function. */ +#undef HAVE_VSNPRINTF + +/* Define to 1 if you have the `waitid' function. */ +#undef HAVE_WAITID + +/* Define to 1 if you have the header file. */ +#undef HAVE_WCHAR_H + +/* Define if you have the 'wchar_t' type. */ +#undef HAVE_WCHAR_T + +/* Define to 1 if you have the `wcrtomb' function. */ +#undef HAVE_WCRTOMB + +/* Define to 1 if you have the `wcslen' function. */ +#undef HAVE_WCSLEN + +/* Define to 1 if you have the `wcsnlen' function. */ +#undef HAVE_WCSNLEN + +/* Define to 1 if you have the header file. */ +#undef HAVE_WCTYPE_H + +/* Define to 1 if you have the `wcwidth' function. */ +#undef HAVE_WCWIDTH + +/* Define to 1 if the compiler and linker support weak declarations of + symbols. */ +#undef HAVE_WEAK_SYMBOLS + +/* Define to 1 if you have the header file. */ +#undef HAVE_WINSOCK2_H + +/* Define if you have the 'wint_t' type. */ +#undef HAVE_WINT_T + +/* Define to 1 if you have the `wmempcpy' function. */ +#undef HAVE_WMEMPCPY + +/* Define to 1 if fstatat (..., 0) works. For example, it does not work in AIX + 7.1. */ +#undef HAVE_WORKING_FSTATAT_ZERO_FLAG + +/* Define to 1 if O_NOATIME works. */ +#undef HAVE_WORKING_O_NOATIME + +/* Define to 1 if O_NOFOLLOW works. */ +#undef HAVE_WORKING_O_NOFOLLOW + +/* Define if utimes works properly. */ +#undef HAVE_WORKING_UTIMES + +/* Define to 1 if you have the header file. */ +#undef HAVE_WS2TCPIP_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_XLOCALE_H + +/* Define to 1 if the system has the type `_Bool'. */ +#undef HAVE__BOOL + +/* Define to 1 if you have the `_fseeki64' function. */ +#undef HAVE__FSEEKI64 + +/* Define to 1 if you have the `_ftelli64' function. */ +#undef HAVE__FTELLI64 + +/* Define to 1 if you have the `_set_invalid_parameter_handler' function. */ +#undef HAVE__SET_INVALID_PARAMETER_HANDLER + +/* Define to 1 if the compiler supports __builtin_expect, + and to 2 if does. */ +#undef HAVE___BUILTIN_EXPECT +#ifndef HAVE___BUILTIN_EXPECT +# define __builtin_expect(e, c) (e) +#elif HAVE___BUILTIN_EXPECT == 2 +# include +#endif + + +/* Define to 1 if you have the `__fpurge' function. */ +#undef HAVE___FPURGE + +/* Define to 1 if you have the `__freading' function. */ +#undef HAVE___FREADING + +/* Define to 1 if you have the `__fsetlocking' function. */ +#undef HAVE___FSETLOCKING + +/* Define to 1 if the compiler supports the keyword '__inline'. */ +#undef HAVE___INLINE + +/* Define to 1 if you have the `__secure_getenv' function. */ +#undef HAVE___SECURE_GETENV + +/* Define to 1 if you have the `__xpg_strerror_r' function. */ +#undef HAVE___XPG_STRERROR_R + +/* Define as const if the declaration of iconv() needs const. */ +#undef ICONV_CONST + +/* Define to 1 if lseek does not detect pipes. */ +#undef LSEEK_PIPE_BROKEN + +/* Define to 1 if 'lstat' dereferences a symlink specified with a trailing + slash. */ +#undef LSTAT_FOLLOWS_SLASHED_SYMLINK + +/* If malloc(0) is != NULL, define this to 1. Otherwise define this to 0. */ +#undef MALLOC_0_IS_NONNULL + +/* Define to a substitute value for mmap()'s MAP_ANONYMOUS flag. */ +#undef MAP_ANONYMOUS + +/* Define if the mbrtowc function does not return (size_t) -2 for empty input. + */ +#undef MBRTOWC_EMPTY_INPUT_BUG + +/* Define if the mbrtowc function may signal encoding errors in the C locale. + */ +#undef MBRTOWC_IN_C_LOCALE_MAYBE_EILSEQ + +/* Define if the mbrtowc function has the NULL pwc argument bug. */ +#undef MBRTOWC_NULL_ARG1_BUG + +/* Define if the mbrtowc function has the NULL string argument bug. */ +#undef MBRTOWC_NULL_ARG2_BUG + +/* Define if the mbrtowc function does not return 0 for a NUL character. */ +#undef MBRTOWC_NUL_RETVAL_BUG + +/* Define if the mbrtowc function returns a wrong return value. */ +#undef MBRTOWC_RETVAL_BUG + +/* Define if the mbrtowc function stores a wide character when reporting + incomplete input. */ +#undef MBRTOWC_STORES_INCOMPLETE_BUG + +/* Use GNU style printf and scanf. */ +#ifndef __USE_MINGW_ANSI_STDIO +# undef __USE_MINGW_ANSI_STDIO +#endif + + +/* Define if the compilation of mktime.c should define 'mktime_internal'. */ +#undef NEED_MKTIME_INTERNAL + +/* Define if the compilation of mktime.c should define 'mktime' with the + native Windows TZ workaround. */ +#undef NEED_MKTIME_WINDOWS + +/* Define if the compilation of mktime.c should define 'mktime' with the + algorithmic workarounds. */ +#undef NEED_MKTIME_WORKING + +/* Define to 1 if nl_langinfo is multithread-safe. */ +#undef NL_LANGINFO_MTSAFE + +/* Define to 1 if open() fails to recognize a trailing slash. */ +#undef OPEN_TRAILING_SLASH_BUG + +/* Define to be the name of the operating system. */ +#undef OS_TYPE + +/* Name of package */ +#undef PACKAGE + +/* Define to the address where bug reports for this package should be sent. */ +#undef PACKAGE_BUGREPORT + +/* Define to the full name of this package. */ +#undef PACKAGE_NAME + +/* Define to the full name and version of this package. */ +#undef PACKAGE_STRING + +/* Define to the one symbol short name of this package. */ +#undef PACKAGE_TARNAME + +/* Define to the home page for this package. */ +#undef PACKAGE_URL + +/* Define to the version of this package. */ +#undef PACKAGE_VERSION + +/* Define to the type that is the result of default argument promotions of + type mode_t. */ +#undef PROMOTED_MODE_T + +/* Define if the pthread_in_use() detection is hard. */ +#undef PTHREAD_IN_USE_DETECTION_HARD + +/* Define to l, ll, u, ul, ull, etc., as suitable for constants of type + 'ptrdiff_t'. */ +#undef PTRDIFF_T_SUFFIX + +/* Define to 1 if readlink fails to recognize a trailing slash. */ +#undef READLINK_TRAILING_SLASH_BUG + +/* Define to 1 if readlink sets errno instead of truncating a too-long link. + */ +#undef READLINK_TRUNCATE_BUG + +/* Define to 1 if gnulib's dirfd() replacement is used. */ +#undef REPLACE_DIRFD + +/* Define to 1 if gnulib's fchdir() replacement is used. */ +#undef REPLACE_FCHDIR + +/* Define to 1 if stat needs help when passed a file name with a trailing + slash */ +#undef REPLACE_FUNC_STAT_FILE + +/* Define to 1 if utime needs help when passed a file name with a trailing + slash */ +#undef REPLACE_FUNC_UTIME_FILE + +/* Define if nl_langinfo exists but is overridden by gnulib. */ +#undef REPLACE_NL_LANGINFO + +/* Define to 1 if open() should work around the inability to open a directory. + */ +#undef REPLACE_OPEN_DIRECTORY + +/* Define if gnulib uses its own posix_spawn and posix_spawnp functions. */ +#undef REPLACE_POSIX_SPAWN + +/* Define to 1 if strerror(0) does not return a message implying success. */ +#undef REPLACE_STRERROR_0 + +/* Define if vasnprintf exists but is overridden by gnulib. */ +#undef REPLACE_VASNPRINTF + +/* Define to 1 if setlocale (LC_ALL, NULL) is multithread-safe. */ +#undef SETLOCALE_NULL_ALL_MTSAFE + +/* Define to 1 if setlocale (category, NULL) is multithread-safe. */ +#undef SETLOCALE_NULL_ONE_MTSAFE + +/* File name of the Bourne shell. */ +#if (defined _WIN32 && !defined __CYGWIN__) || defined __CYGWIN__ || defined __ANDROID__ +/* Omit the directory part because + - For native Windows programs in a Cygwin environment, the Cygwin mounts + are not visible. + - For 32-bit Cygwin programs in a 64-bit Cygwin environment, the Cygwin + mounts are not visible. + - On Android, /bin/sh does not exist. It's /system/bin/sh instead. */ +# define BOURNE_SHELL "sh" +#else +# define BOURNE_SHELL "/bin/sh" +#endif + +/* Define to l, ll, u, ul, ull, etc., as suitable for constants of type + 'sig_atomic_t'. */ +#undef SIG_ATOMIC_T_SUFFIX + +/* The size of `long', as computed by sizeof. */ +#undef SIZEOF_LONG + +/* The size of `off_t', as computed by sizeof. */ +#undef SIZEOF_OFF_T + +/* Define as the maximum value of type 'size_t', if the system doesn't define + it. */ +#ifndef SIZE_MAX +# undef SIZE_MAX +#endif + +/* Define to l, ll, u, ul, ull, etc., as suitable for constants of type + 'size_t'. */ +#undef SIZE_T_SUFFIX + +/* If using the C implementation of alloca, define if you know the + direction of stack growth for your system; otherwise it will be + automatically deduced at runtime. + STACK_DIRECTION > 0 => grows toward higher addresses + STACK_DIRECTION < 0 => grows toward lower addresses + STACK_DIRECTION = 0 => direction of growth unknown */ +#undef STACK_DIRECTION + +/* Define to 1 if the `S_IS*' macros in do not work properly. */ +#undef STAT_MACROS_BROKEN + +/* Define to 1 if all of the C90 standard headers exist (not just the ones + required in a freestanding environment). This macro is provided for + backward compatibility; new code need not use it. */ +#undef STDC_HEADERS + +/* Define to 1 if strerror_r returns char *. */ +#undef STRERROR_R_CHAR_P + +/* Define to 1 if time_t is signed. */ +#undef TIME_T_IS_SIGNED + +/* Define to 1 if the type of the st_atim member of a struct stat is struct + timespec. */ +#undef TYPEOF_STRUCT_STAT_ST_ATIM_IS_STRUCT_TIMESPEC + +/* Define to 1 if unlink() on a parent directory may succeed */ +#undef UNLINK_PARENT_BUG + +/* Define to the prefix of C symbols at the assembler and linker level, either + an underscore or empty. */ +#undef USER_LABEL_PREFIX + +/* Define if the combination of the ISO C and POSIX multithreading APIs can be + used. */ +#undef USE_ISOC_AND_POSIX_THREADS + +/* Define if the ISO C multithreading library can be used. */ +#undef USE_ISOC_THREADS + +/* Define to 1 if you want to use the Linux kernel cryptographic API. */ +#undef USE_LINUX_CRYPTO_API + +/* Define if the POSIX multithreading library can be used. */ +#undef USE_POSIX_THREADS + +/* Define if references to the POSIX multithreading library should be made + weak. */ +#undef USE_POSIX_THREADS_WEAK + +/* Enable extensions on AIX 3, Interix. */ +#ifndef _ALL_SOURCE +# undef _ALL_SOURCE +#endif +/* Enable general extensions on macOS. */ +#ifndef _DARWIN_C_SOURCE +# undef _DARWIN_C_SOURCE +#endif +/* Enable general extensions on Solaris. */ +#ifndef __EXTENSIONS__ +# undef __EXTENSIONS__ +#endif +/* Enable GNU extensions on systems that have them. */ +#ifndef _GNU_SOURCE +# undef _GNU_SOURCE +#endif +/* Enable X/Open compliant socket functions that do not require linking + with -lxnet on HP-UX 11.11. */ +#ifndef _HPUX_ALT_XOPEN_SOCKET_API +# undef _HPUX_ALT_XOPEN_SOCKET_API +#endif +/* Identify the host operating system as Minix. + This macro does not affect the system headers' behavior. + A future release of Autoconf may stop defining this macro. */ +#ifndef _MINIX +# undef _MINIX +#endif +/* Enable general extensions on NetBSD. + Enable NetBSD compatibility extensions on Minix. */ +#ifndef _NETBSD_SOURCE +# undef _NETBSD_SOURCE +#endif +/* Enable OpenBSD compatibility extensions on NetBSD. + Oddly enough, this does nothing on OpenBSD. */ +#ifndef _OPENBSD_SOURCE +# undef _OPENBSD_SOURCE +#endif +/* Define to 1 if needed for POSIX-compatible behavior. */ +#ifndef _POSIX_SOURCE +# undef _POSIX_SOURCE +#endif +/* Define to 2 if needed for POSIX-compatible behavior. */ +#ifndef _POSIX_1_SOURCE +# undef _POSIX_1_SOURCE +#endif +/* Enable POSIX-compatible threading on Solaris. */ +#ifndef _POSIX_PTHREAD_SEMANTICS +# undef _POSIX_PTHREAD_SEMANTICS +#endif +/* Enable extensions specified by ISO/IEC TS 18661-5:2014. */ +#ifndef __STDC_WANT_IEC_60559_ATTRIBS_EXT__ +# undef __STDC_WANT_IEC_60559_ATTRIBS_EXT__ +#endif +/* Enable extensions specified by ISO/IEC TS 18661-1:2014. */ +#ifndef __STDC_WANT_IEC_60559_BFP_EXT__ +# undef __STDC_WANT_IEC_60559_BFP_EXT__ +#endif +/* Enable extensions specified by ISO/IEC TS 18661-2:2015. */ +#ifndef __STDC_WANT_IEC_60559_DFP_EXT__ +# undef __STDC_WANT_IEC_60559_DFP_EXT__ +#endif +/* Enable extensions specified by ISO/IEC TS 18661-4:2015. */ +#ifndef __STDC_WANT_IEC_60559_FUNCS_EXT__ +# undef __STDC_WANT_IEC_60559_FUNCS_EXT__ +#endif +/* Enable extensions specified by ISO/IEC TS 18661-3:2015. */ +#ifndef __STDC_WANT_IEC_60559_TYPES_EXT__ +# undef __STDC_WANT_IEC_60559_TYPES_EXT__ +#endif +/* Enable extensions specified by ISO/IEC TR 24731-2:2010. */ +#ifndef __STDC_WANT_LIB_EXT2__ +# undef __STDC_WANT_LIB_EXT2__ +#endif +/* Enable extensions specified by ISO/IEC 24747:2009. */ +#ifndef __STDC_WANT_MATH_SPEC_FUNCS__ +# undef __STDC_WANT_MATH_SPEC_FUNCS__ +#endif +/* Enable extensions on HP NonStop. */ +#ifndef _TANDEM_SOURCE +# undef _TANDEM_SOURCE +#endif +/* Enable X/Open extensions. Define to 500 only if necessary + to make mbstate_t available. */ +#ifndef _XOPEN_SOURCE +# undef _XOPEN_SOURCE +#endif + + +/* Define to 1 if you want getc etc. to use unlocked I/O if available. + Unlocked I/O can improve performance in unithreaded apps, but it is not + safe for multithreaded apps. */ +#undef USE_UNLOCKED_IO + +/* Define if the native Windows multithreading API can be used. */ +#undef USE_WINDOWS_THREADS + +/* Version number of package */ +#undef VERSION + +/* Define to l, ll, u, ul, ull, etc., as suitable for constants of type + 'wchar_t'. */ +#undef WCHAR_T_SUFFIX + +/* Define if the wcrtomb function does not work in the C locale. */ +#undef WCRTOMB_C_LOCALE_BUG + +/* Define if the wcrtomb function has an incorrect return value. */ +#undef WCRTOMB_RETVAL_BUG + +/* Define if WSAStartup is needed. */ +#undef WINDOWS_SOCKETS + +/* Define to l, ll, u, ul, ull, etc., as suitable for constants of type + 'wint_t'. */ +#undef WINT_T_SUFFIX + +/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most + significant byte first (like Motorola and SPARC, unlike Intel). */ +#if defined AC_APPLE_UNIVERSAL_BUILD +# if defined __BIG_ENDIAN__ +# define WORDS_BIGENDIAN 1 +# endif +#else +# ifndef WORDS_BIGENDIAN +# undef WORDS_BIGENDIAN +# endif +#endif + +/* Define to 1 if `lex' declares `yytext' as a `char *' by default, not a + `char[]'. */ +#undef YYTEXT_POINTER + +/* Number of bits in a file offset, on hosts where this is settable. */ +#undef _FILE_OFFSET_BITS + +/* True if the compiler says it groks GNU C version MAJOR.MINOR. */ +#if defined __GNUC__ && defined __GNUC_MINOR__ +# define _GL_GNUC_PREREQ(major, minor) \ + ((major) < __GNUC__ + ((minor) <= __GNUC_MINOR__)) +#else +# define _GL_GNUC_PREREQ(major, minor) 0 +#endif + + +/* Define to 1 to make fseeko visible on some hosts (e.g. glibc 2.2). */ +#undef _LARGEFILE_SOURCE + +/* Define for large files, on AIX-style hosts. */ +#undef _LARGE_FILES + +/* Define to 1 on Solaris. */ +#undef _LCONV_C99 + +/* The _Noreturn keyword of C11. */ +#ifndef _Noreturn +# if (defined __cplusplus \ + && ((201103 <= __cplusplus && !(__GNUC__ == 4 && __GNUC_MINOR__ == 7)) \ + || (defined _MSC_VER && 1900 <= _MSC_VER)) \ + && 0) + /* [[noreturn]] is not practically usable, because with it the syntax + extern _Noreturn void func (...); + would not be valid; such a declaration would only be valid with 'extern' + and '_Noreturn' swapped, or without the 'extern' keyword. However, some + AIX system header files and several gnulib header files use precisely + this syntax with 'extern'. */ +# define _Noreturn [[noreturn]] +# elif ((!defined __cplusplus || defined __clang__) \ + && (201112 <= (defined __STDC_VERSION__ ? __STDC_VERSION__ : 0) \ + || _GL_GNUC_PREREQ (4, 7) \ + || (defined __apple_build_version__ \ + ? 6000000 <= __apple_build_version__ \ + : 3 < __clang_major__ + (5 <= __clang_minor__)))) + /* _Noreturn works as-is. */ +# elif _GL_GNUC_PREREQ (2, 8) || defined __clang__ || 0x5110 <= __SUNPRO_C +# define _Noreturn __attribute__ ((__noreturn__)) +# elif 1200 <= (defined _MSC_VER ? _MSC_VER : 0) +# define _Noreturn __declspec (noreturn) +# else +# define _Noreturn +# endif +#endif + + +/* Define to 1 in order to get the POSIX compatible declarations of socket + functions. */ +#undef _POSIX_PII_SOCKET + +/* Define if you want to include , so that it consistently + overrides 's RE_DUP_MAX. */ +#undef _REGEX_INCLUDE_LIMITS_H + +/* Define if you want regoff_t to be at least as wide POSIX requires. */ +#undef _REGEX_LARGE_OFFSETS + +/* For standard stat data types on VMS. */ +#undef _USE_STD_STAT + +/* Define to rpl_ if the getopt replacement functions and variables should be + used. */ +#undef __GETOPT_PREFIX + +/* Define to 1 if the system predates C++11. */ +#undef __STDC_CONSTANT_MACROS + +/* Define to 1 if the system predates C++11. */ +#undef __STDC_LIMIT_MACROS + +/* The _GL_ASYNC_SAFE marker should be attached to functions that are + signal handlers (for signals other than SIGABRT, SIGPIPE) or can be + invoked from such signal handlers. Such functions have some restrictions: + * All functions that it calls should be marked _GL_ASYNC_SAFE as well, + or should be listed as async-signal-safe in POSIX + + section 2.4.3. Note that malloc(), sprintf(), and fwrite(), in + particular, are NOT async-signal-safe. + * All memory locations (variables and struct fields) that these functions + access must be marked 'volatile'. This holds for both read and write + accesses. Otherwise the compiler might optimize away stores to and + reads from such locations that occur in the program, depending on its + data flow analysis. For example, when the program contains a loop + that is intended to inspect a variable set from within a signal handler + while (!signal_occurred) + ; + the compiler is allowed to transform this into an endless loop if the + variable 'signal_occurred' is not declared 'volatile'. + Additionally, recall that: + * A signal handler should not modify errno (except if it is a handler + for a fatal signal and ends by raising the same signal again, thus + provoking the termination of the process). If it invokes a function + that may clobber errno, it needs to save and restore the value of + errno. */ +#define _GL_ASYNC_SAFE + + +/* Attributes. */ +#ifdef __has_attribute +# define _GL_HAS_ATTRIBUTE(attr) __has_attribute (__##attr##__) +#else +# define _GL_HAS_ATTRIBUTE(attr) _GL_ATTR_##attr +# define _GL_ATTR_alloc_size _GL_GNUC_PREREQ (4, 3) +# define _GL_ATTR_always_inline _GL_GNUC_PREREQ (3, 2) +# define _GL_ATTR_artificial _GL_GNUC_PREREQ (4, 3) +# define _GL_ATTR_cold _GL_GNUC_PREREQ (4, 3) +# define _GL_ATTR_const _GL_GNUC_PREREQ (2, 95) +# define _GL_ATTR_deprecated _GL_GNUC_PREREQ (3, 1) +# define _GL_ATTR_diagnose_if 0 +# define _GL_ATTR_error _GL_GNUC_PREREQ (4, 3) +# define _GL_ATTR_externally_visible _GL_GNUC_PREREQ (4, 1) +# define _GL_ATTR_fallthrough _GL_GNUC_PREREQ (7, 0) +# define _GL_ATTR_format _GL_GNUC_PREREQ (2, 7) +# define _GL_ATTR_leaf _GL_GNUC_PREREQ (4, 6) +# ifdef _ICC +# define _GL_ATTR_may_alias 0 +# else +# define _GL_ATTR_may_alias _GL_GNUC_PREREQ (3, 3) +# endif +# define _GL_ATTR_malloc _GL_GNUC_PREREQ (3, 0) +# define _GL_ATTR_noinline _GL_GNUC_PREREQ (3, 1) +# define _GL_ATTR_nonnull _GL_GNUC_PREREQ (3, 3) +# define _GL_ATTR_nonstring _GL_GNUC_PREREQ (8, 0) +# define _GL_ATTR_nothrow _GL_GNUC_PREREQ (3, 3) +# define _GL_ATTR_packed _GL_GNUC_PREREQ (2, 7) +# define _GL_ATTR_pure _GL_GNUC_PREREQ (2, 96) +# define _GL_ATTR_returns_nonnull _GL_GNUC_PREREQ (4, 9) +# define _GL_ATTR_sentinel _GL_GNUC_PREREQ (4, 0) +# define _GL_ATTR_unused _GL_GNUC_PREREQ (2, 7) +# define _GL_ATTR_warn_unused_result _GL_GNUC_PREREQ (3, 4) +#endif + + +#if _GL_HAS_ATTRIBUTE (alloc_size) +# define _GL_ATTRIBUTE_ALLOC_SIZE(args) __attribute__ ((__alloc_size__ args)) +#else +# define _GL_ATTRIBUTE_ALLOC_SIZE(args) +#endif + +#if _GL_HAS_ATTRIBUTE (always_inline) +# define _GL_ATTRIBUTE_ALWAYS_INLINE __attribute__ ((__always_inline__)) +#else +# define _GL_ATTRIBUTE_ALWAYS_INLINE +#endif + +#if _GL_HAS_ATTRIBUTE (artificial) +# define _GL_ATTRIBUTE_ARTIFICIAL __attribute__ ((__artificial__)) +#else +# define _GL_ATTRIBUTE_ARTIFICIAL +#endif + +/* Avoid __attribute__ ((cold)) on MinGW; see thread starting at + . + Also, Oracle Studio 12.6 requires 'cold' not '__cold__'. */ +#if _GL_HAS_ATTRIBUTE (cold) && !defined __MINGW32__ +# ifndef __SUNPRO_C +# define _GL_ATTRIBUTE_COLD __attribute__ ((__cold__)) +# else +# define _GL_ATTRIBUTE_COLD __attribute__ ((cold)) +# endif +#else +# define _GL_ATTRIBUTE_COLD +#endif + +#if _GL_HAS_ATTRIBUTE (const) +# define _GL_ATTRIBUTE_CONST __attribute__ ((__const__)) +#else +# define _GL_ATTRIBUTE_CONST +#endif + +#if 201710L < __STDC_VERSION__ +# define _GL_ATTRIBUTE_DEPRECATED [[__deprecated__]] +#elif _GL_HAS_ATTRIBUTE (deprecated) +# define _GL_ATTRIBUTE_DEPRECATED __attribute__ ((__deprecated__)) +#else +# define _GL_ATTRIBUTE_DEPRECATED +#endif + +#if _GL_HAS_ATTRIBUTE (error) +# define _GL_ATTRIBUTE_ERROR(msg) __attribute__ ((__error__ (msg))) +# define _GL_ATTRIBUTE_WARNING(msg) __attribute__ ((__warning__ (msg))) +#elif _GL_HAS_ATTRIBUTE (diagnose_if) +# define _GL_ATTRIBUTE_ERROR(msg) __attribute__ ((__diagnose_if__ (1, msg, "error"))) +# define _GL_ATTRIBUTE_WARNING(msg) __attribute__ ((__diagnose_if__ (1, msg, "warning"))) +#else +# define _GL_ATTRIBUTE_ERROR(msg) +# define _GL_ATTRIBUTE_WARNING(msg) +#endif + +#if _GL_HAS_ATTRIBUTE (externally_visible) +# define _GL_ATTRIBUTE_EXTERNALLY_VISIBLE __attribute__ ((externally_visible)) +#else +# define _GL_ATTRIBUTE_EXTERNALLY_VISIBLE +#endif + +/* FALLTHROUGH is special, because it always expands to something. */ +#if 201710L < __STDC_VERSION__ +# define _GL_ATTRIBUTE_FALLTHROUGH [[__fallthrough__]] +#elif _GL_HAS_ATTRIBUTE (fallthrough) +# define _GL_ATTRIBUTE_FALLTHROUGH __attribute__ ((__fallthrough__)) +#else +# define _GL_ATTRIBUTE_FALLTHROUGH ((void) 0) +#endif + +#if _GL_HAS_ATTRIBUTE (format) +# define _GL_ATTRIBUTE_FORMAT(spec) __attribute__ ((__format__ spec)) +#else +# define _GL_ATTRIBUTE_FORMAT(spec) +#endif + +#if _GL_HAS_ATTRIBUTE (leaf) +# define _GL_ATTRIBUTE_LEAF __attribute__ ((__leaf__)) +#else +# define _GL_ATTRIBUTE_LEAF +#endif + +/* Oracle Studio 12.6 mishandles may_alias despite __has_attribute OK. */ +#if _GL_HAS_ATTRIBUTE (may_alias) && !defined __SUNPRO_C +# define _GL_ATTRIBUTE_MAY_ALIAS __attribute__ ((__may_alias__)) +#else +# define _GL_ATTRIBUTE_MAY_ALIAS +#endif + +#if 201710L < __STDC_VERSION__ +# define _GL_ATTRIBUTE_MAYBE_UNUSED [[__maybe_unused__]] +#elif _GL_HAS_ATTRIBUTE (unused) +# define _GL_ATTRIBUTE_MAYBE_UNUSED __attribute__ ((__unused__)) +#else +# define _GL_ATTRIBUTE_MAYBE_UNUSED +#endif +/* Earlier spellings of this macro. */ +#define _GL_UNUSED _GL_ATTRIBUTE_MAYBE_UNUSED +#define _UNUSED_PARAMETER_ _GL_ATTRIBUTE_MAYBE_UNUSED + +#if _GL_HAS_ATTRIBUTE (malloc) +# define _GL_ATTRIBUTE_MALLOC __attribute__ ((__malloc__)) +#else +# define _GL_ATTRIBUTE_MALLOC +#endif + +#if 201710L < __STDC_VERSION__ +# define _GL_ATTRIBUTE_NODISCARD [[__nodiscard__]] +#elif _GL_HAS_ATTRIBUTE (warn_unused_result) +# define _GL_ATTRIBUTE_NODISCARD __attribute__ ((__warn_unused_result__)) +#else +# define _GL_ATTRIBUTE_NODISCARD +#endif + +#if _GL_HAS_ATTRIBUTE (noinline) +# define _GL_ATTRIBUTE_NOINLINE __attribute__ ((__noinline__)) +#else +# define _GL_ATTRIBUTE_NOINLINE +#endif + +#if _GL_HAS_ATTRIBUTE (nonnull) +# define _GL_ATTRIBUTE_NONNULL(args) __attribute__ ((__nonnull__ args)) +#else +# define _GL_ATTRIBUTE_NONNULL(args) +#endif + +#if _GL_HAS_ATTRIBUTE (nonstring) +# define _GL_ATTRIBUTE_NONSTRING __attribute__ ((__nonstring__)) +#else +# define _GL_ATTRIBUTE_NONSTRING +#endif + +/* There is no _GL_ATTRIBUTE_NORETURN; use _Noreturn instead. */ + +#if _GL_HAS_ATTRIBUTE (nothrow) && !defined __cplusplus +# define _GL_ATTRIBUTE_NOTHROW __attribute__ ((__nothrow__)) +#else +# define _GL_ATTRIBUTE_NOTHROW +#endif + +#if _GL_HAS_ATTRIBUTE (packed) +# define _GL_ATTRIBUTE_PACKED __attribute__ ((__packed__)) +#else +# define _GL_ATTRIBUTE_PACKED +#endif + +#if _GL_HAS_ATTRIBUTE (pure) +# define _GL_ATTRIBUTE_PURE __attribute__ ((__pure__)) +#else +# define _GL_ATTRIBUTE_PURE +#endif + +#if _GL_HAS_ATTRIBUTE (returns_nonnull) +# define _GL_ATTRIBUTE_RETURNS_NONNULL __attribute__ ((__returns_nonnull__)) +#else +# define _GL_ATTRIBUTE_RETURNS_NONNULL +#endif + +#if _GL_HAS_ATTRIBUTE (sentinel) +# define _GL_ATTRIBUTE_SENTINEL(pos) __attribute__ ((__sentinel__ pos)) +#else +# define _GL_ATTRIBUTE_SENTINEL(pos) +#endif + + +/* To support C++ as well as C, use _GL_UNUSED_LABEL with trailing ';'. */ +#if !defined __cplusplus || _GL_GNUC_PREREQ (4, 5) +# define _GL_UNUSED_LABEL _GL_ATTRIBUTE_MAYBE_UNUSED +#else +# define _GL_UNUSED_LABEL +#endif + + +/* Define to empty if `const' does not conform to ANSI C. */ +#undef const + +/* Define as 'access' if you don't have the eaccess() function. */ +#undef eaccess + +/* Please see the Gnulib manual for how to use these macros. + + Suppress extern inline with HP-UX cc, as it appears to be broken; see + . + + Suppress extern inline with Sun C in standards-conformance mode, as it + mishandles inline functions that call each other. E.g., for 'inline void f + (void) { } inline void g (void) { f (); }', c99 incorrectly complains + 'reference to static identifier "f" in extern inline function'. + This bug was observed with Sun C 5.12 SunOS_i386 2011/11/16. + + Suppress extern inline (with or without __attribute__ ((__gnu_inline__))) + on configurations that mistakenly use 'static inline' to implement + functions or macros in standard C headers like . For example, + if isdigit is mistakenly implemented via a static inline function, + a program containing an extern inline function that calls isdigit + may not work since the C standard prohibits extern inline functions + from calling static functions. This bug is known to occur on: + + OS X 10.8 and earlier; see: + http://lists.gnu.org/archive/html/bug-gnulib/2012-12/msg00023.html + + DragonFly; see + http://muscles.dragonflybsd.org/bulk/bleeding-edge-potential/latest-per-pkg/ah-tty-0.3.12.log + + FreeBSD; see: + http://lists.gnu.org/archive/html/bug-gnulib/2014-07/msg00104.html + + OS X 10.9 has a macro __header_inline indicating the bug is fixed for C and + for clang but remains for g++; see . + Assume DragonFly and FreeBSD will be similar. */ +#if (((defined __APPLE__ && defined __MACH__) \ + || defined __DragonFly__ || defined __FreeBSD__) \ + && (defined __header_inline \ + ? (defined __cplusplus && defined __GNUC_STDC_INLINE__ \ + && ! defined __clang__) \ + : ((! defined _DONT_USE_CTYPE_INLINE_ \ + && (defined __GNUC__ || defined __cplusplus)) \ + || (defined _FORTIFY_SOURCE && 0 < _FORTIFY_SOURCE \ + && defined __GNUC__ && ! defined __cplusplus)))) +# define _GL_EXTERN_INLINE_STDHEADER_BUG +#endif +#if ((__GNUC__ \ + ? defined __GNUC_STDC_INLINE__ && __GNUC_STDC_INLINE__ \ + : (199901L <= __STDC_VERSION__ \ + && !defined __HP_cc \ + && !(defined __SUNPRO_C && __STDC__))) \ + && !defined _GL_EXTERN_INLINE_STDHEADER_BUG) +# define _GL_INLINE inline +# define _GL_EXTERN_INLINE extern inline +# define _GL_EXTERN_INLINE_IN_USE +#elif (2 < __GNUC__ + (7 <= __GNUC_MINOR__) && !defined __STRICT_ANSI__ \ + && !defined _GL_EXTERN_INLINE_STDHEADER_BUG) +# if defined __GNUC_GNU_INLINE__ && __GNUC_GNU_INLINE__ + /* __gnu_inline__ suppresses a GCC 4.2 diagnostic. */ +# define _GL_INLINE extern inline __attribute__ ((__gnu_inline__)) +# else +# define _GL_INLINE extern inline +# endif +# define _GL_EXTERN_INLINE extern +# define _GL_EXTERN_INLINE_IN_USE +#else +# define _GL_INLINE static _GL_UNUSED +# define _GL_EXTERN_INLINE static _GL_UNUSED +#endif + +#if 4 < __GNUC__ + (6 <= __GNUC_MINOR__) +# if defined __GNUC_STDC_INLINE__ && __GNUC_STDC_INLINE__ +# define _GL_INLINE_HEADER_CONST_PRAGMA +# else +# define _GL_INLINE_HEADER_CONST_PRAGMA \ + _Pragma ("GCC diagnostic ignored \"-Wsuggest-attribute=const\"") +# endif + /* Suppress GCC's bogus "no previous prototype for 'FOO'" + and "no previous declaration for 'FOO'" diagnostics, + when FOO is an inline function in the header; see + . */ +# define _GL_INLINE_HEADER_BEGIN \ + _Pragma ("GCC diagnostic push") \ + _Pragma ("GCC diagnostic ignored \"-Wmissing-prototypes\"") \ + _Pragma ("GCC diagnostic ignored \"-Wmissing-declarations\"") \ + _GL_INLINE_HEADER_CONST_PRAGMA +# define _GL_INLINE_HEADER_END \ + _Pragma ("GCC diagnostic pop") +#else +# define _GL_INLINE_HEADER_BEGIN +# define _GL_INLINE_HEADER_END +#endif + +/* Define to `int' if doesn't define. */ +#undef gid_t + +/* Define to `__inline__' or `__inline' if that's what the C compiler + calls it, or to nothing if 'inline' is not supported under any name. */ +#ifndef __cplusplus +#undef inline +#endif + +/* Define to long or long long if and don't define. */ +#undef intmax_t + +/* Work around a bug in Apple GCC 4.0.1 build 5465: In C99 mode, it supports + the ISO C 99 semantics of 'extern inline' (unlike the GNU C semantics of + earlier versions), but does not display it by setting __GNUC_STDC_INLINE__. + __APPLE__ && __MACH__ test for Mac OS X. + __APPLE_CC__ tests for the Apple compiler and its version. + __STDC_VERSION__ tests for the C99 mode. */ +#if defined __APPLE__ && defined __MACH__ && __APPLE_CC__ >= 5465 && !defined __cplusplus && __STDC_VERSION__ >= 199901L && !defined __GNUC_STDC_INLINE__ +# define __GNUC_STDC_INLINE__ 1 +#endif + +/* Define to a type if does not define. */ +#undef mbstate_t + +/* _GL_CMP (n1, n2) performs a three-valued comparison on n1 vs. n2, where + n1 and n2 are expressions without side effects, that evaluate to real + numbers (excluding NaN). + It returns + 1 if n1 > n2 + 0 if n1 == n2 + -1 if n1 < n2 + The naïve code (n1 > n2 ? 1 : n1 < n2 ? -1 : 0) produces a conditional + jump with nearly all GCC versions up to GCC 10. + This variant (n1 < n2 ? -1 : n1 > n2) produces a conditional with many + GCC versions up to GCC 9. + The better code (n1 > n2) - (n1 < n2) from Hacker's Delight § 2-9 + avoids conditional jumps in all GCC versions >= 3.4. */ +#define _GL_CMP(n1, n2) (((n1) > (n2)) - ((n1) < (n2))) + + +/* Define to the real name of the mktime_internal function. */ +#undef mktime_internal + +/* Define to `int' if does not define. */ +#undef mode_t + +/* Define to the type of st_nlink in struct stat, or a supertype. */ +#undef nlink_t + +/* Define as a signed integer type capable of holding a process identifier. */ +#undef pid_t + +/* Define as the type of the result of subtracting two pointers, if the system + doesn't define it. */ +#undef ptrdiff_t + +/* Define to rpl_re_comp if the replacement should be used. */ +#undef re_comp + +/* Define to rpl_re_compile_fastmap if the replacement should be used. */ +#undef re_compile_fastmap + +/* Define to rpl_re_compile_pattern if the replacement should be used. */ +#undef re_compile_pattern + +/* Define to rpl_re_exec if the replacement should be used. */ +#undef re_exec + +/* Define to rpl_re_match if the replacement should be used. */ +#undef re_match + +/* Define to rpl_re_match_2 if the replacement should be used. */ +#undef re_match_2 + +/* Define to rpl_re_search if the replacement should be used. */ +#undef re_search + +/* Define to rpl_re_search_2 if the replacement should be used. */ +#undef re_search_2 + +/* Define to rpl_re_set_registers if the replacement should be used. */ +#undef re_set_registers + +/* Define to rpl_re_set_syntax if the replacement should be used. */ +#undef re_set_syntax + +/* Define to rpl_re_syntax_options if the replacement should be used. */ +#undef re_syntax_options + +/* Define to rpl_regcomp if the replacement should be used. */ +#undef regcomp + +/* Define to rpl_regerror if the replacement should be used. */ +#undef regerror + +/* Define to rpl_regexec if the replacement should be used. */ +#undef regexec + +/* Define to rpl_regfree if the replacement should be used. */ +#undef regfree + +/* Define to the equivalent of the C99 'restrict' keyword, or to + nothing if this is not supported. Do not define if restrict is + supported only directly. */ +#undef restrict +/* Work around a bug in older versions of Sun C++, which did not + #define __restrict__ or support _Restrict or __restrict__ + even though the corresponding Sun C compiler ended up with + "#define restrict _Restrict" or "#define restrict __restrict__" + in the previous line. This workaround can be removed once + we assume Oracle Developer Studio 12.5 (2016) or later. */ +#if defined __SUNPRO_CC && !defined __RESTRICT && !defined __restrict__ +# define _Restrict +# define __restrict__ +#endif + +/* Define as an integer type suitable for memory locations that can be + accessed atomically even in the presence of asynchronous signals. */ +#undef sig_atomic_t + +/* Define to `unsigned int' if does not define. */ +#undef size_t + +/* type to use in place of socklen_t if not defined */ +#undef socklen_t + +/* Define as a signed type of the same size as size_t. */ +#undef ssize_t + +/* Define to `int' if doesn't define. */ +#undef uid_t + +/* Define to empty if the keyword `volatile' does not work. Warning: valid + code using `volatile' can become incorrect without. Disable with care. */ +#undef volatile diff --git a/src/connect.c b/src/connect.c new file mode 100644 index 0000000..ad7ba0b --- /dev/null +++ b/src/connect.c @@ -0,0 +1,1084 @@ +/* Establishing and handling network connections. + Copyright (C) 1995-2011, 2015, 2018-2020 Free Software Foundation, + Inc. + +This file is part of GNU Wget. + +GNU Wget is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + +GNU Wget 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 Wget. If not, see . + +Additional permission under GNU GPL version 3 section 7 + +If you modify this program, or any covered work, by linking or +combining it with the OpenSSL project's OpenSSL library (or a +modified version of that library), containing parts covered by the +terms of the OpenSSL or SSLeay licenses, the Free Software Foundation +grants you additional permission to convey the resulting work. +Corresponding Source for a non-source form of such a combination +shall include the source code for the parts of OpenSSL used as well +as that of the covered work. */ + +#include "wget.h" + +#include "exits.h" +#include +#include +#include +#include + +#include +#include + +#ifndef WINDOWS +# ifdef __VMS +# include "vms_ip.h" +# else /* def __VMS */ +# include +# endif /* def __VMS [else] */ +# include +# ifndef __BEOS__ +# include +# endif +#endif /* not WINDOWS */ + +#include +#include +#include + +#include "utils.h" +#include "host.h" +#include "connect.h" +#include "hash.h" + +#include + +/* Define sockaddr_storage where unavailable (presumably on IPv4-only + hosts). */ + +#ifndef ENABLE_IPV6 +# ifndef HAVE_STRUCT_SOCKADDR_STORAGE +# define sockaddr_storage sockaddr_in +# endif +#endif /* ENABLE_IPV6 */ + +/* Fill SA as per the data in IP and PORT. SA should point to struct + sockaddr_storage if ENABLE_IPV6 is defined, to struct sockaddr_in + otherwise. */ + +static void +sockaddr_set_data (struct sockaddr *sa, const ip_address *ip, int port) +{ + switch (ip->family) + { + case AF_INET: + { + struct sockaddr_in *sin = (struct sockaddr_in *)sa; + xzero (*sin); + sin->sin_family = AF_INET; + sin->sin_port = htons (port); + sin->sin_addr = ip->data.d4; + break; + } +#ifdef ENABLE_IPV6 + case AF_INET6: + { + struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)sa; + xzero (*sin6); + sin6->sin6_family = AF_INET6; + sin6->sin6_port = htons (port); + sin6->sin6_addr = ip->data.d6; +#ifdef HAVE_SOCKADDR_IN6_SCOPE_ID + sin6->sin6_scope_id = ip->ipv6_scope; +#endif + break; + } +#endif /* ENABLE_IPV6 */ + default: + abort (); + } +} + +/* Get the data of SA, specifically the IP address and the port. If + you're not interested in one or the other information, pass NULL as + the pointer. */ + +static void +sockaddr_get_data (const struct sockaddr *sa, ip_address *ip, int *port) +{ + switch (sa->sa_family) + { + case AF_INET: + { + struct sockaddr_in *sin = (struct sockaddr_in *)sa; + if (ip) + { + ip->family = AF_INET; + ip->data.d4 = sin->sin_addr; + } + if (port) + *port = ntohs (sin->sin_port); + break; + } +#ifdef ENABLE_IPV6 + case AF_INET6: + { + struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)sa; + if (ip) + { + ip->family = AF_INET6; + ip->data.d6 = sin6->sin6_addr; +#ifdef HAVE_SOCKADDR_IN6_SCOPE_ID + ip->ipv6_scope = sin6->sin6_scope_id; +#endif + } + if (port) + *port = ntohs (sin6->sin6_port); + break; + } +#endif + default: + abort (); + } +} + +/* Return the size of the sockaddr structure depending on its + family. */ + +static socklen_t +sockaddr_size (const struct sockaddr *sa) +{ + switch (sa->sa_family) + { + case AF_INET: + return sizeof (struct sockaddr_in); +#ifdef ENABLE_IPV6 + case AF_INET6: + return sizeof (struct sockaddr_in6); +#endif + default: + abort (); + } +} + +/* Resolve the bind address specified via --bind-address and store it + to SA. The resolved value is stored in a static variable and + reused after the first invocation of this function. + + Returns true on success, false on failure. */ + +static bool +resolve_bind_address (struct sockaddr *sa) +{ + struct address_list *al; + + /* Make sure this is called only once. opt.bind_address doesn't + change during a Wget run. */ + static bool called, should_bind; + static ip_address ip; + if (called) + { + if (should_bind) + sockaddr_set_data (sa, &ip, 0); + return should_bind; + } + called = true; + + al = lookup_host (opt.bind_address, LH_BIND | LH_SILENT); + if (!al) + { + /* #### We should be able to print the error message here. */ + logprintf (LOG_NOTQUIET, + _("%s: unable to resolve bind address %s; disabling bind.\n"), + exec_name, quote (opt.bind_address)); + should_bind = false; + return false; + } + + /* Pick the first address in the list and use it as bind address. + Perhaps we should try multiple addresses in succession, but I + don't think that's necessary in practice. */ + ip = *address_list_address_at (al, 0); + address_list_release (al); + + sockaddr_set_data (sa, &ip, 0); + should_bind = true; + return true; +} + +struct cwt_context { + int fd; + const struct sockaddr *addr; + socklen_t addrlen; + int result; +}; + +static void +connect_with_timeout_callback (void *arg) +{ + struct cwt_context *ctx = (struct cwt_context *)arg; + ctx->result = connect (ctx->fd, ctx->addr, ctx->addrlen); +} + +/* Like connect, but specifies a timeout. If connecting takes longer + than TIMEOUT seconds, -1 is returned and errno is set to + ETIMEDOUT. */ + +static int +connect_with_timeout (int fd, const struct sockaddr *addr, socklen_t addrlen, + double timeout) +{ + struct cwt_context ctx; + ctx.fd = fd; + ctx.addr = addr; + ctx.addrlen = addrlen; + + if (run_with_timeout (timeout, connect_with_timeout_callback, &ctx)) + { + errno = ETIMEDOUT; + return -1; + } + if (ctx.result == -1 && errno == EINTR) + errno = ETIMEDOUT; + return ctx.result; +} + +/* Connect via TCP to the specified address and port. + + If PRINT is non-NULL, it is the host name to print that we're + connecting to. */ + +int +connect_to_ip (const ip_address *ip, int port, const char *print) +{ + struct sockaddr_storage ss; + struct sockaddr *sa = (struct sockaddr *)&ss; + int sock; + + /* If PRINT is non-NULL, print the "Connecting to..." line, with + PRINT being the host name we're connecting to. */ + if (print) + { + const char *txt_addr = print_address (ip); + if (0 != strcmp (print, txt_addr)) + { + char *str = NULL, *name; + + if (opt.enable_iri && (name = idn_decode ((char *) print)) != NULL) + { + str = aprintf ("%s (%s)", name, print); + xfree (name); + } + + logprintf (LOG_VERBOSE, _("Connecting to %s|%s|:%d... "), + str ? str : escnonprint_uri (print), txt_addr, port); + + xfree (str); + } + else + { + if (ip->family == AF_INET) + logprintf (LOG_VERBOSE, _("Connecting to %s:%d... "), txt_addr, port); +#ifdef ENABLE_IPV6 + else if (ip->family == AF_INET6) + logprintf (LOG_VERBOSE, _("Connecting to [%s]:%d... "), txt_addr, port); +#endif + } + } + + /* Store the sockaddr info to SA. */ + sockaddr_set_data (sa, ip, port); + + /* Create the socket of the family appropriate for the address. */ + sock = socket (sa->sa_family, SOCK_STREAM, 0); + if (sock < 0) + goto err; + +#if defined(ENABLE_IPV6) && defined(IPV6_V6ONLY) + if (opt.ipv6_only) { + int on = 1; + /* In case of error, we will go on anyway... */ + int err = setsockopt (sock, IPPROTO_IPV6, IPV6_V6ONLY, &on, sizeof (on)); + IF_DEBUG + if (err < 0) + DEBUGP (("Failed setting IPV6_V6ONLY: %s", strerror (errno))); + } +#endif + + /* For very small rate limits, set the buffer size (and hence, + hopefully, the kernel's TCP window size) to the per-second limit. + That way we should never have to sleep for more than 1s between + network reads. */ + if (opt.limit_rate && opt.limit_rate < 8192) + { + int bufsize = opt.limit_rate; + if (bufsize < 512) + bufsize = 512; /* avoid pathologically small values */ +#ifdef SO_RCVBUF + if (setsockopt (sock, SOL_SOCKET, SO_RCVBUF, + (void *) &bufsize, (socklen_t) sizeof (bufsize))) + logprintf (LOG_NOTQUIET, _("setsockopt SO_RCVBUF failed: %s\n"), + strerror (errno)); +#endif + /* When we add limit_rate support for writing, which is useful + for POST, we should also set SO_SNDBUF here. */ + } + + if (opt.bind_address) + { + /* Bind the client side of the socket to the requested + address. */ + struct sockaddr_storage bind_ss; + struct sockaddr *bind_sa = (struct sockaddr *)&bind_ss; + if (resolve_bind_address (bind_sa)) + { + if (bind (sock, bind_sa, sockaddr_size (bind_sa)) < 0) + goto err; + } + } + + /* Connect the socket to the remote endpoint. */ + if (connect_with_timeout (sock, sa, sockaddr_size (sa), + opt.connect_timeout) < 0) + goto err; + + /* Success. */ + assert (sock >= 0); + if (print) + logprintf (LOG_VERBOSE, _("connected.\n")); + DEBUGP (("Created socket %d.\n", sock)); + return sock; + + err: + { + /* Protect errno from possible modifications by close and + logprintf. */ + int save_errno = errno; + if (sock >= 0) + { +#ifdef WIN32 + /* If the connection timed out, fd_close will hang in Gnulib's + close_fd_maybe_socket, inside the call to WSAEnumNetworkEvents. */ + if (errno != ETIMEDOUT) +#endif + fd_close (sock); + } + if (print) + logprintf (LOG_NOTQUIET, _("failed: %s.\n"), strerror (errno)); + errno = save_errno; + return -1; + } +} + +/* Connect via TCP to a remote host on the specified port. + + HOST is resolved as an Internet host name. If HOST resolves to + more than one IP address, they are tried in the order returned by + DNS until connecting to one of them succeeds. */ + +int +connect_to_host (const char *host, int port) +{ + int i, start, end; + int sock; + + struct address_list *al = lookup_host (host, 0); + + retry: + if (!al) + { + logprintf (LOG_NOTQUIET, + _("%s: unable to resolve host address %s\n"), + exec_name, quote (host)); + return E_HOST; + } + + address_list_get_bounds (al, &start, &end); + for (i = start; i < end; i++) + { + const ip_address *ip = address_list_address_at (al, i); + sock = connect_to_ip (ip, port, host); + if (sock >= 0) + { + /* Success. */ + address_list_set_connected (al); + address_list_release (al); + return sock; + } + + /* The attempt to connect has failed. Continue with the loop + and try next address. */ + + address_list_set_faulty (al, i); + } + + /* Failed to connect to any of the addresses in AL. */ + + if (address_list_connected_p (al)) + { + /* We connected to AL before, but cannot do so now. That might + indicate that our DNS cache entry for HOST has expired. */ + address_list_release (al); + al = lookup_host (host, LH_REFRESH); + goto retry; + } + address_list_release (al); + + return -1; +} + +/* Create a socket, bind it to local interface BIND_ADDRESS on port + *PORT, set up a listen backlog, and return the resulting socket, or + -1 in case of error. + + BIND_ADDRESS is the address of the interface to bind to. If it is + NULL, the socket is bound to the default address. PORT should + point to the port number that will be used for the binding. If + that number is 0, the system will choose a suitable port, and the + chosen value will be written to *PORT. + + Calling accept() on such a socket waits for and accepts incoming + TCP connections. */ + +int +bind_local (const ip_address *bind_address, int *port) +{ + int sock; + struct sockaddr_storage ss; + struct sockaddr *sa = (struct sockaddr *)&ss; + + /* For setting options with setsockopt. */ + int setopt_val = 1; + void *setopt_ptr = (void *)&setopt_val; + socklen_t setopt_size = sizeof (setopt_val); + + sock = socket (bind_address->family, SOCK_STREAM, 0); + if (sock < 0) + return -1; + +#ifdef SO_REUSEADDR + if (setsockopt (sock, SOL_SOCKET, SO_REUSEADDR, setopt_ptr, setopt_size)) + logprintf (LOG_NOTQUIET, _("setsockopt SO_REUSEADDR failed: %s\n"), + strerror (errno)); +#endif + + xzero (ss); + sockaddr_set_data (sa, bind_address, *port); + if (bind (sock, sa, sockaddr_size (sa)) < 0) + { + fd_close (sock); + return -1; + } + DEBUGP (("Local socket fd %d bound.\n", sock)); + + /* If *PORT is 0, find out which port we've bound to. */ + if (*port == 0) + { + socklen_t addrlen = sockaddr_size (sa); + if (getsockname (sock, sa, &addrlen) < 0) + { + /* If we can't find out the socket's local address ("name"), + something is seriously wrong with the socket, and it's + unusable for us anyway because we must know the chosen + port. */ + fd_close (sock); + return -1; + } + sockaddr_get_data (sa, NULL, port); + DEBUGP (("binding to address %s using port %i.\n", + print_address (bind_address), *port)); + } + if (listen (sock, 1) < 0) + { + fd_close (sock); + return -1; + } + return sock; +} + +/* Like a call to accept(), but with the added check for timeout. + + In other words, accept a client connection on LOCAL_SOCK, and + return the new socket used for communication with the client. + LOCAL_SOCK should have been bound, e.g. using bind_local(). + + The caller is blocked until a connection is established. If no + connection is established for opt.connect_timeout seconds, the + function exits with an error status. */ + +int +accept_connection (int local_sock) +{ + int sock; + + /* We don't need the values provided by accept, but accept + apparently requires them to be present. */ + struct sockaddr_storage ss; + struct sockaddr *sa = (struct sockaddr *)&ss; + socklen_t addrlen = sizeof (ss); + + if (opt.connect_timeout) + { + int test = select_fd (local_sock, opt.connect_timeout, WAIT_FOR_READ); + if (test == 0) + errno = ETIMEDOUT; + if (test <= 0) + return -1; + } + sock = accept (local_sock, sa, &addrlen); + DEBUGP (("Accepted client at socket %d.\n", sock)); + return sock; +} + +/* Get the IP address associated with the connection on FD and store + it to IP. Return true on success, false otherwise. + + If ENDPOINT is ENDPOINT_LOCAL, it returns the address of the local + (client) side of the socket. Else if ENDPOINT is ENDPOINT_PEER, it + returns the address of the remote (peer's) side of the socket. */ + +bool +socket_ip_address (int sock, ip_address *ip, int endpoint) +{ + struct sockaddr_storage storage; + struct sockaddr *sockaddr = (struct sockaddr *) &storage; + socklen_t addrlen = sizeof (storage); + int ret; + + memset (sockaddr, 0, addrlen); + if (endpoint == ENDPOINT_LOCAL) + ret = getsockname (sock, sockaddr, &addrlen); + else if (endpoint == ENDPOINT_PEER) + ret = getpeername (sock, sockaddr, &addrlen); + else + abort (); + if (ret < 0) + return false; + + memset(ip, 0, sizeof(ip_address)); + ip->family = sockaddr->sa_family; + switch (sockaddr->sa_family) + { +#ifdef ENABLE_IPV6 + case AF_INET6: + { + struct sockaddr_in6 *sa6 = (struct sockaddr_in6 *)&storage; + ip->data.d6 = sa6->sin6_addr; +#ifdef HAVE_SOCKADDR_IN6_SCOPE_ID + ip->ipv6_scope = sa6->sin6_scope_id; +#endif + DEBUGP (("conaddr is: %s\n", print_address (ip))); + return true; + } +#endif + case AF_INET: + { + struct sockaddr_in *sa = (struct sockaddr_in *)&storage; + ip->data.d4 = sa->sin_addr; + DEBUGP (("conaddr is: %s\n", print_address (ip))); + return true; + } + default: + abort (); + } +} + +/* Get the socket family of connection on FD and store + Return family type on success, -1 otherwise. + + If ENDPOINT is ENDPOINT_LOCAL, it returns the sock family of the local + (client) side of the socket. Else if ENDPOINT is ENDPOINT_PEER, it + returns the sock family of the remote (peer's) side of the socket. */ + +int +socket_family (int sock, int endpoint) +{ + struct sockaddr_storage storage; + struct sockaddr *sockaddr = (struct sockaddr *) &storage; + socklen_t addrlen = sizeof (storage); + int ret; + + memset (sockaddr, 0, addrlen); + + if (endpoint == ENDPOINT_LOCAL) + ret = getsockname (sock, sockaddr, &addrlen); + else if (endpoint == ENDPOINT_PEER) + ret = getpeername (sock, sockaddr, &addrlen); + else + abort (); + + if (ret < 0) + return -1; + + return sockaddr->sa_family; +} + +/* Return true if the error from the connect code can be considered + retryable. Wget normally retries after errors, but the exception + are the "unsupported protocol" type errors (possible on IPv4/IPv6 + dual family systems) and "connection refused". */ + +bool +retryable_socket_connect_error (int err) +{ + /* Have to guard against some of these values not being defined. + Cannot use a switch statement because some of the values might be + equal. */ + if (false +#ifdef EAFNOSUPPORT + || err == EAFNOSUPPORT +#endif +#ifdef EPFNOSUPPORT + || err == EPFNOSUPPORT +#endif +#ifdef ESOCKTNOSUPPORT /* no, "sockt" is not a typo! */ + || err == ESOCKTNOSUPPORT +#endif +#ifdef EPROTONOSUPPORT + || err == EPROTONOSUPPORT +#endif +#ifdef ENOPROTOOPT + || err == ENOPROTOOPT +#endif + /* Apparently, older versions of Linux and BSD used EINVAL + instead of EAFNOSUPPORT and such. */ + || err == EINVAL + ) + return false; + + if (!opt.retry_connrefused) + if (err == ECONNREFUSED +#ifdef ENETUNREACH + || err == ENETUNREACH /* network is unreachable */ +#endif +#ifdef EHOSTUNREACH + || err == EHOSTUNREACH /* host is unreachable */ +#endif + ) + return false; + + return true; +} + +/* Wait for a single descriptor to become available, timing out after + MAXTIME seconds. Returns 1 if FD is available, 0 for timeout and + -1 for error. The argument WAIT_FOR can be a combination of + WAIT_FOR_READ and WAIT_FOR_WRITE. + + This is a mere convenience wrapper around the select call, and + should be taken as such (for example, it doesn't implement Wget's + 0-timeout-means-no-timeout semantics.) */ + +static int +select_fd_internal (int fd, double maxtime, int wait_for, bool convert_back _GL_UNUSED) +{ + fd_set fdset; + fd_set *rd = NULL, *wr = NULL; + struct timeval tmout; + int result; + + if (fd < 0) + return -1; + + if (fd >= FD_SETSIZE) + { + logprintf (LOG_NOTQUIET, _("Too many fds open. Cannot use select on a fd >= %d\n"), FD_SETSIZE); + exit (WGET_EXIT_GENERIC_ERROR); + } + FD_ZERO (&fdset); + FD_SET (fd, &fdset); + if (wait_for & WAIT_FOR_READ) + rd = &fdset; + if (wait_for & WAIT_FOR_WRITE) + wr = &fdset; + + tmout.tv_sec = (long) maxtime; + tmout.tv_usec = 1000000 * (maxtime - (long) maxtime); + + do + { + result = select (fd + 1, rd, wr, NULL, &tmout); +#ifdef WINDOWS + /* gnulib select() converts blocking sockets to nonblocking in windows. + wget uses blocking sockets so we must convert them back to blocking. */ + if (convert_back) + set_windows_fd_as_blocking_socket (fd); +#endif + } + while (result < 0 && errno == EINTR); + + return result; +} + +int +select_fd (int fd, double maxtime, int wait_for) +{ + return select_fd_internal (fd, maxtime, wait_for, true); +} + +#ifdef WINDOWS +int +select_fd_nb (int fd, double maxtime, int wait_for) +{ + return select_fd_internal (fd, maxtime, wait_for, false); +} +#endif + +/* Return true if the connection to the remote site established + through SOCK is still open. + + Specifically, this function returns true if SOCK is not ready for + reading. This is because, when the connection closes, the socket + is ready for reading because EOF is about to be delivered. A side + effect of this method is that sockets that have pending data are + considered non-open. This is actually a good thing for callers of + this function, where such pending data can only be unwanted + leftover from a previous request. */ + +bool +test_socket_open (int sock) +{ + fd_set check_set; + struct timeval to; + int ret = 0; + + if (sock >= FD_SETSIZE) + { + logprintf (LOG_NOTQUIET, _("Too many fds open. Cannot use select on a fd >= %d\n"), FD_SETSIZE); + exit (WGET_EXIT_GENERIC_ERROR); + } + /* Check if we still have a valid (non-EOF) connection. From Andrew + * Maholski's code in the Unix Socket FAQ. */ + + FD_ZERO (&check_set); + FD_SET (sock, &check_set); + + /* Wait one microsecond */ + to.tv_sec = 0; + to.tv_usec = 1; + + ret = select (sock + 1, &check_set, NULL, NULL, &to); +#ifdef WINDOWS +/* gnulib select() converts blocking sockets to nonblocking in windows. +wget uses blocking sockets so we must convert them back to blocking +*/ + set_windows_fd_as_blocking_socket ( sock ); +#endif + + if ( !ret ) + /* We got a timeout, it means we're still connected. */ + return true; + else + /* Read now would not wait, it means we have either pending data + or EOF/error. */ + return false; +} + +/* Basic socket operations, mostly EINTR wrappers. */ + +static int +sock_read (int fd, char *buf, int bufsize) +{ + int res; + do + res = read (fd, buf, bufsize); + while (res == -1 && errno == EINTR); + return res; +} + +static int +sock_write (int fd, char *buf, int bufsize) +{ + int res; + do + res = write (fd, buf, bufsize); + while (res == -1 && errno == EINTR); + return res; +} + +static int +sock_poll (int fd, double timeout, int wait_for) +{ + return select_fd (fd, timeout, wait_for); +} + +static int +sock_peek (int fd, char *buf, int bufsize) +{ + int res; + do + res = recv (fd, buf, bufsize, MSG_PEEK); + while (res == -1 && errno == EINTR); + return res; +} + +static void +sock_close (int fd) +{ + close (fd); + DEBUGP (("Closed fd %d\n", fd)); +} +#undef read +#undef write +#undef close + +/* Reading and writing from the network. We build around the socket + (file descriptor) API, but support "extended" operations for things + that are not mere file descriptors under the hood, such as SSL + sockets. + + That way the user code can call fd_read(fd, ...) and we'll run read + or SSL_read or whatever is necessary. */ + +static struct hash_table *transport_map; +static unsigned int transport_map_modified_tick; + +struct transport_info { + struct transport_implementation *imp; + void *ctx; +}; + +/* Register the transport layer operations that will be used when + reading, writing, and polling FD. + + This should be used for transport layers like SSL that piggyback on + sockets. FD should otherwise be a real socket, on which you can + call getpeername, etc. */ + +void +fd_register_transport (int fd, struct transport_implementation *imp, void *ctx) +{ + struct transport_info *info; + + /* The file descriptor must be non-negative to be registered. + Negative values are ignored by fd_close(), and -1 cannot be used as + hash key. */ + assert (fd >= 0); + + info = xnew (struct transport_info); + info->imp = imp; + info->ctx = ctx; + if (!transport_map) + transport_map = hash_table_new (0, NULL, NULL); + hash_table_put (transport_map, (void *)(intptr_t) fd, info); + ++transport_map_modified_tick; +} + +/* Return context of the transport registered with + fd_register_transport. This assumes fd_register_transport was + previously called on FD. */ + +void * +fd_transport_context (int fd) +{ + struct transport_info *info = hash_table_get (transport_map, (void *)(intptr_t) fd); + return info ? info->ctx : NULL; +} + +/* When fd_read/fd_write are called multiple times in a loop, they should + remember the INFO pointer instead of fetching it every time. It is + not enough to compare FD to LAST_FD because FD might have been + closed and reopened. modified_tick ensures that changes to + transport_map will not be unnoticed. + + This is a macro because we want the static storage variables to be + per-function. */ + +#define LAZY_RETRIEVE_INFO(info) do { \ + static struct transport_info *last_info; \ + static int last_fd = -1; \ + static unsigned int last_tick; \ + if (!transport_map) \ + info = NULL; \ + else if (last_fd == fd && last_tick == transport_map_modified_tick) \ + info = last_info; \ + else \ + { \ + info = hash_table_get (transport_map, (void *)(intptr_t) fd); \ + last_fd = fd; \ + last_info = info; \ + last_tick = transport_map_modified_tick; \ + } \ +} while (0) + +static bool +poll_internal (int fd, struct transport_info *info, int wf, double timeout) +{ + if (timeout == -1) + timeout = opt.read_timeout; + if (timeout) + { + int test; + if (info && info->imp->poller) + test = info->imp->poller (fd, timeout, wf, info->ctx); + else + test = sock_poll (fd, timeout, wf); + if (test == 0) + errno = ETIMEDOUT; + if (test <= 0) + return false; + } + return true; +} + +/* Read no more than BUFSIZE bytes of data from FD, storing them to + BUF. If TIMEOUT is non-zero, the operation aborts if no data is + received after that many seconds. If TIMEOUT is -1, the value of + opt.timeout is used for TIMEOUT. */ + +int +fd_read (int fd, char *buf, int bufsize, double timeout) +{ + struct transport_info *info; + LAZY_RETRIEVE_INFO (info); + + /* let imp->reader take care about timeout. + (or in worst case timeout can be 2*timeout) */ + if (info && info->imp->reader) + return info->imp->reader (fd, buf, bufsize, info->ctx, timeout); + + if (!poll_internal (fd, info, WAIT_FOR_READ, timeout)) + return -1; + return sock_read (fd, buf, bufsize); +} + +/* Like fd_read, except it provides a "preview" of the data that will + be read by subsequent calls to fd_read. Specifically, it copies no + more than BUFSIZE bytes of the currently available data to BUF and + returns the number of bytes copied. Return values and timeout + semantics are the same as those of fd_read. + + CAVEAT: Do not assume that the first subsequent call to fd_read + will retrieve the same amount of data. Reading can return more or + less data, depending on the TCP implementation and other + circumstances. However, barring an error, it can be expected that + all the peeked data will eventually be read by fd_read. */ + +int +fd_peek (int fd, char *buf, int bufsize, double timeout) +{ + struct transport_info *info; + LAZY_RETRIEVE_INFO (info); + + if (info && info->imp->peeker) + return info->imp->peeker (fd, buf, bufsize, info->ctx, timeout); + + if (!poll_internal (fd, info, WAIT_FOR_READ, timeout)) + return -1; + return sock_peek (fd, buf, bufsize); +} + +/* Write the entire contents of BUF to FD. If TIMEOUT is non-zero, + the operation aborts if no data is received after that many + seconds. If TIMEOUT is -1, the value of opt.timeout is used for + TIMEOUT. */ + +int +fd_write (int fd, char *buf, int bufsize, double timeout) +{ + int res; + struct transport_info *info; + LAZY_RETRIEVE_INFO (info); + + /* `write' may write less than LEN bytes, thus the loop keeps trying + it until all was written, or an error occurred. */ + res = 0; + while (bufsize > 0) + { + if (!poll_internal (fd, info, WAIT_FOR_WRITE, timeout)) + return -1; + if (info && info->imp->writer) + res = info->imp->writer (fd, buf, bufsize, info->ctx); + else + res = sock_write (fd, buf, bufsize); + if (res <= 0) + break; + buf += res; + bufsize -= res; + } + return res; +} + +/* Report the most recent error(s) on FD. This should only be called + after fd_* functions, such as fd_read and fd_write, and only if + they return a negative result. For errors coming from other calls + such as setsockopt or fopen, strerror should continue to be + used. + + If the transport doesn't support error messages or doesn't supply + one, strerror(errno) is returned. The returned error message + should not be used after fd_close has been called. */ + +const char * +fd_errstr (int fd) +{ + /* Don't bother with LAZY_RETRIEVE_INFO, as this will only be called + in case of error, never in a tight loop. */ + struct transport_info *info = NULL; + + if (transport_map) + info = hash_table_get (transport_map, (void *)(intptr_t) fd); + + if (info && info->imp->errstr) + { + const char *err = info->imp->errstr (fd, info->ctx); + if (err) + return err; + /* else, fall through and print the system error. */ + } + return strerror (errno); +} + +/* Close the file descriptor FD. */ + +void +fd_close (int fd) +{ + struct transport_info *info; + if (fd < 0) + return; + + /* Don't use LAZY_RETRIEVE_INFO because fd_close() is only called once + per socket, so that particular optimization wouldn't work. */ + info = NULL; + if (transport_map) + info = hash_table_get (transport_map, (void *)(intptr_t) fd); + + if (info && info->imp->closer) + info->imp->closer (fd, info->ctx); + else + sock_close (fd); + + if (info) + { + hash_table_remove (transport_map, (void *)(intptr_t) fd); + xfree (info); + ++transport_map_modified_tick; + } +} + +#if defined DEBUG_MALLOC || defined TESTING +void +connect_cleanup(void) +{ + if (transport_map) + { + hash_table_iterator iter; + for (hash_table_iterate (transport_map, &iter); hash_table_iter_next (&iter); ) + { + xfree (iter.value); + } + hash_table_destroy (transport_map); + transport_map = NULL; + } +} +#endif diff --git a/src/connect.h b/src/connect.h new file mode 100644 index 0000000..8453559 --- /dev/null +++ b/src/connect.h @@ -0,0 +1,89 @@ +/* Declarations for connect. + Copyright (C) 1996-2011, 2015, 2018-2020 Free Software Foundation, + Inc. + +This file is part of GNU Wget. + +GNU Wget is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + +GNU Wget 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 Wget. If not, see . + +Additional permission under GNU GPL version 3 section 7 + +If you modify this program, or any covered work, by linking or +combining it with the OpenSSL project's OpenSSL library (or a +modified version of that library), containing parts covered by the +terms of the OpenSSL or SSLeay licenses, the Free Software Foundation +grants you additional permission to convey the resulting work. +Corresponding Source for a non-source form of such a combination +shall include the source code for the parts of OpenSSL used as well +as that of the covered work. */ + +#ifndef CONNECT_H +#define CONNECT_H + +#include "host.h" /* for definition of ip_address */ + +/* Function declarations */ + +/* Returned by connect_to_host when host name cannot be resolved. */ +enum { + E_HOST = -100 +}; +int connect_to_host (const char *, int); +int connect_to_ip (const ip_address *, int, const char *); + +int bind_local (const ip_address *, int *); +int accept_connection (int); + +enum { + ENDPOINT_LOCAL, + ENDPOINT_PEER +}; +bool socket_ip_address (int, ip_address *, int); +int socket_family (int sock, int endpoint); + +bool retryable_socket_connect_error (int); + +/* Flags for select_fd's WAIT_FOR argument. */ +enum { + WAIT_FOR_READ = 1, + WAIT_FOR_WRITE = 2 +}; +int select_fd (int, double, int); +bool test_socket_open (int); + +struct transport_implementation { + int (*reader) (int, char *, int, void *, double); + int (*writer) (int, char *, int, void *); + int (*poller) (int, double, int, void *); + int (*peeker) (int, char *, int, void *, double); + const char *(*errstr) (int, void *); + void (*closer) (int, void *); +}; + +void fd_register_transport (int, struct transport_implementation *, void *); +void *fd_transport_context (int); +int fd_read (int, char *, int, double); +int fd_write (int, char *, int, double); +int fd_peek (int, char *, int, double); +const char *fd_errstr (int); +void fd_close (int); +void connect_cleanup (void); + +#ifdef WINDOWS +int select_fd_nb (int, double, int); +#else +#define select_fd_nb select_fd +#endif + +#endif /* CONNECT_H */ diff --git a/src/convert.c b/src/convert.c new file mode 100644 index 0000000..f422178 --- /dev/null +++ b/src/convert.c @@ -0,0 +1,1230 @@ +/* Conversion of links to local files. + Copyright (C) 2003-2011, 2014-2015, 2018-2020 Free Software + Foundation, Inc. + +This file is part of GNU Wget. + +GNU Wget is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + +GNU Wget 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 Wget. If not, see . + +Additional permission under GNU GPL version 3 section 7 + +If you modify this program, or any covered work, by linking or +combining it with the OpenSSL project's OpenSSL library (or a +modified version of that library), containing parts covered by the +terms of the OpenSSL or SSLeay licenses, the Free Software Foundation +grants you additional permission to convey the resulting work. +Corresponding Source for a non-source form of such a combination +shall include the source code for the parts of OpenSSL used as well +as that of the covered work. */ + +#include "wget.h" + +#include +#include +#include +#include +#include +#include +#include "convert.h" +#include "url.h" +#include "recur.h" +#include "utils.h" +#include "hash.h" +#include "ptimer.h" +#include "res.h" +#include "html-url.h" +#include "css-url.h" +#include "iri.h" +#include "xstrndup.h" + +static struct hash_table *dl_file_url_map; +struct hash_table *dl_url_file_map; + +/* Set of HTML/CSS files downloaded in this Wget run, used for link + conversion after Wget is done. */ +struct hash_table *downloaded_html_set; +struct hash_table *downloaded_css_set; + +static void convert_links (const char *, struct urlpos *); + + +static void +convert_links_in_hashtable (struct hash_table *downloaded_set, + int is_css, + int *file_count) +{ + int i, cnt = 0; + char *arr[1024], **file_array; + + if (!downloaded_set || (cnt = hash_table_count (downloaded_set)) == 0) + return; + + if (cnt <= (int) countof (arr)) + file_array = arr; + else + file_array = xmalloc (cnt * sizeof (arr[0])); + + string_set_to_array (downloaded_set, file_array); + + for (i = 0; i < cnt; i++) + { + struct urlpos *urls, *cur_url; + char *url; + char *file = file_array[i]; + + /* Determine the URL of the file. get_urls_{html,css} will need + it. */ + url = hash_table_get (dl_file_url_map, file); + if (!url) + { + DEBUGP (("Apparently %s has been removed.\n", file)); + continue; + } + + DEBUGP (("Scanning %s (from %s)\n", file, url)); + + /* Parse the file... */ + urls = is_css ? get_urls_css_file (file, url) : + get_urls_html (file, url, NULL, NULL); + + /* We don't respect meta_disallow_follow here because, even if + the file is not followed, we might still want to convert the + links that have been followed from other files. */ + + for (cur_url = urls; cur_url; cur_url = cur_url->next) + { + char *local_name; + struct url *u; + struct iri *pi; + + if (cur_url->link_base_p) + { + /* Base references have been resolved by our parser, so + we turn the base URL into an empty string. (Perhaps + we should remove the tag entirely?) */ + cur_url->convert = CO_NULLIFY_BASE; + continue; + } + + /* We decide the direction of conversion according to whether + a URL was downloaded. Downloaded URLs will be converted + ABS2REL, whereas non-downloaded will be converted REL2ABS. */ + + pi = iri_new (); + set_uri_encoding (pi, opt.locale, true); + + u = url_parse (cur_url->url->url, NULL, pi, true); + if (!u) + continue; + + local_name = hash_table_get (dl_url_file_map, u->url); + + /* Decide on the conversion type. */ + if (local_name) + { + /* We've downloaded this URL. Convert it to relative + form. We do this even if the URL already is in + relative form, because our directory structure may + not be identical to that on the server (think `-nd', + `--cut-dirs', etc.). If --convert-file-only was passed, + we only convert the basename portion of the URL. */ + cur_url->convert = (opt.convert_file_only ? CO_CONVERT_BASENAME_ONLY : CO_CONVERT_TO_RELATIVE); + cur_url->local_name = xstrdup (local_name); + DEBUGP (("will convert url %s to local %s\n", u->url, local_name)); + } + else + { + /* We haven't downloaded this URL. If it's not already + complete (including a full host name), convert it to + that form, so it can be reached while browsing this + HTML locally. */ + if (!cur_url->link_complete_p) + cur_url->convert = CO_CONVERT_TO_COMPLETE; + cur_url->local_name = NULL; + DEBUGP (("will convert url %s to complete\n", u->url)); + } + + url_free (u); + iri_free (pi); + } + + /* Convert the links in the file. */ + convert_links (file, urls); + ++*file_count; + + /* Free the data. */ + free_urlpos (urls); + } + + if (file_array != arr) + xfree (file_array); +} + +/* This function is called when the retrieval is done to convert the + links that have been downloaded. It has to be called at the end of + the retrieval, because only then does Wget know conclusively which + URLs have been downloaded, and which not, so it can tell which + direction to convert to. + + The "direction" means that the URLs to the files that have been + downloaded get converted to the relative URL which will point to + that file. And the other URLs get converted to the remote URL on + the server. + + All the downloaded HTMLs are kept in downloaded_html_files, and + downloaded URLs in urls_downloaded. All the information is + extracted from these two lists. */ + +void +convert_all_links (void) +{ + double secs; + int file_count = 0; + + struct ptimer *timer = ptimer_new (); + + convert_links_in_hashtable (downloaded_html_set, 0, &file_count); + convert_links_in_hashtable (downloaded_css_set, 1, &file_count); + + secs = ptimer_measure (timer); + logprintf (LOG_VERBOSE, _("Converted links in %d files in %s seconds.\n"), + file_count, print_decimal (secs)); + + ptimer_destroy (timer); +} + +static void write_backup_file (const char *, downloaded_file_t); +static const char *replace_plain (const char*, int, FILE*, const char *); +static const char *replace_attr (const char *, int, FILE *, const char *); +static const char *replace_attr_refresh_hack (const char *, int, FILE *, + const char *, int); +static char *local_quote_string (const char *, bool); +static char *construct_relative (const char *, const char *); +static char *convert_basename (const char *, const struct urlpos *); + +/* Change the links in one file. LINKS is a list of links in the + document, along with their positions and the desired direction of + the conversion. */ +static void +convert_links (const char *file, struct urlpos *links) +{ + struct file_memory *fm; + FILE *fp; + const char *p; + downloaded_file_t downloaded_file_return; + + struct urlpos *link; + int to_url_count = 0, to_file_count = 0; + + logprintf (LOG_VERBOSE, _("Converting links in %s... "), file); + + { + /* First we do a "dry run": go through the list L and see whether + any URL needs to be converted in the first place. If not, just + leave the file alone. */ + int dry_count = 0; + struct urlpos *dry; + for (dry = links; dry; dry = dry->next) + if (dry->convert != CO_NOCONVERT) + ++dry_count; + if (!dry_count) + { + logputs (LOG_VERBOSE, _("nothing to do.\n")); + return; + } + logprintf (LOG_VERBOSE, _("%d.\n"), dry_count); + } + + fm = wget_read_file (file); + if (!fm) + { + logprintf (LOG_NOTQUIET, _("Cannot convert links in %s: %s\n"), + file, strerror (errno)); + return; + } + + downloaded_file_return = downloaded_file (CHECK_FOR_FILE, file); + if (opt.backup_converted && downloaded_file_return) + write_backup_file (file, downloaded_file_return); + + /* Before opening the file for writing, unlink the file. This is + important if the data in FM is mapped. In such case, nulling the + file, which is what fopen() below does, would make us read all + zeroes from the mapped region. */ + if (unlink (file) < 0 && errno != ENOENT) + { + logprintf (LOG_NOTQUIET, _("Unable to delete %s: %s\n"), + quote (file), strerror (errno)); + wget_read_file_free (fm); + return; + } + /* Now open the file for writing. */ + fp = fopen (file, "wb"); + if (!fp) + { + logprintf (LOG_NOTQUIET, _("Cannot convert links in %s: %s\n"), + file, strerror (errno)); + wget_read_file_free (fm); + return; + } + + /* Here we loop through all the URLs in file, replacing those of + them that are downloaded with relative references. */ + p = fm->content; + for (link = links; link; link = link->next) + { + char *url_start = fm->content + link->pos; + + if (link->pos >= fm->length) + { + DEBUGP (("Something strange is going on. Please investigate.")); + break; + } + /* If the URL is not to be converted, skip it. */ + if (link->convert == CO_NOCONVERT) + { + DEBUGP (("Skipping %s at position %d.\n", link->url->url, link->pos)); + continue; + } + + /* Echo the file contents, up to the offending URL's opening + quote, to the outfile. */ + fwrite (p, 1, url_start - p, fp); + p = url_start; + + switch (link->convert) + { + case CO_CONVERT_TO_RELATIVE: + /* Convert absolute URL to relative. */ + if (link->local_name) { + char *newname = construct_relative (file, link->local_name); + char *quoted_newname = local_quote_string (newname, + link->link_css_p); + + if (link->link_css_p || link->link_noquote_html_p) + p = replace_plain (p, link->size, fp, quoted_newname); + else if (!link->link_refresh_p) + p = replace_attr (p, link->size, fp, quoted_newname); + else + p = replace_attr_refresh_hack (p, link->size, fp, quoted_newname, + link->refresh_timeout); + + DEBUGP (("TO_RELATIVE: %s to %s at position %d in %s.\n", + link->url->url, newname, link->pos, file)); + + xfree (newname); + xfree (quoted_newname); + ++to_file_count; + } + break; + case CO_CONVERT_BASENAME_ONLY: + { + char *newname = convert_basename (p, link); + char *quoted_newname = local_quote_string (newname, link->link_css_p); + + if (link->link_css_p || link->link_noquote_html_p) + p = replace_plain (p, link->size, fp, quoted_newname); + else if (!link->link_refresh_p) + p = replace_attr (p, link->size, fp, quoted_newname); + else + p = replace_attr_refresh_hack (p, link->size, fp, quoted_newname, + link->refresh_timeout); + + DEBUGP (("Converted file part only: %s to %s at position %d in %s.\n", + link->url->url, newname, link->pos, file)); + + xfree (newname); + xfree (quoted_newname); + ++to_file_count; + + break; + } + case CO_CONVERT_TO_COMPLETE: + /* Convert the link to absolute URL. */ + { + char *newlink = link->url->url; + char *quoted_newlink = html_quote_string (newlink); + + if (link->link_css_p || link->link_noquote_html_p) + p = replace_plain (p, link->size, fp, newlink); + else if (!link->link_refresh_p) + p = replace_attr (p, link->size, fp, quoted_newlink); + else + p = replace_attr_refresh_hack (p, link->size, fp, quoted_newlink, + link->refresh_timeout); + + DEBUGP (("TO_COMPLETE: to %s at position %d in %s.\n", + newlink, link->pos, file)); + + xfree (quoted_newlink); + ++to_url_count; + break; + } + case CO_NULLIFY_BASE: + /* Change the base href to "". */ + p = replace_attr (p, link->size, fp, ""); + break; + case CO_NOCONVERT: + abort (); + break; + } + } + + /* Output the rest of the file. */ + if (p - fm->content < fm->length) + fwrite (p, 1, fm->length - (p - fm->content), fp); + fclose (fp); + wget_read_file_free (fm); + + logprintf (LOG_VERBOSE, "%d-%d\n", to_file_count, to_url_count); +} + +/* Construct and return a link that points from BASEFILE to LINKFILE. + Both files should be local file names, BASEFILE of the referrering + file, and LINKFILE of the referred file. + + Examples: + + cr("foo", "bar") -> "bar" + cr("A/foo", "A/bar") -> "bar" + cr("A/foo", "A/B/bar") -> "B/bar" + cr("A/X/foo", "A/Y/bar") -> "../Y/bar" + cr("X/", "Y/bar") -> "../Y/bar" (trailing slash does matter in BASE) + + Both files should be absolute or relative, otherwise strange + results might ensue. The function makes no special efforts to + handle "." and ".." in links, so make sure they're not there + (e.g. using path_simplify). */ + +static char * +construct_relative (const char *basefile, const char *linkfile) +{ + char *link; + int basedirs; + const char *b, *l; + int i, start; + + /* First, skip the initial directory components common to both + files. */ + start = 0; + for (b = basefile, l = linkfile; *b == *l && *b != '\0'; ++b, ++l) + { + if (*b == '/') + start = (b - basefile) + 1; + } + basefile += start; + linkfile += start; + + /* With common directories out of the way, the situation we have is + as follows: + b - b1/b2/[...]/bfile + l - l1/l2/[...]/lfile + + The link we're constructing needs to be: + lnk - ../../l1/l2/[...]/lfile + + Where the number of ".."'s equals the number of bN directory + components in B. */ + + /* Count the directory components in B. */ + basedirs = 0; + for (b = basefile; *b; b++) + { + if (*b == '/') + ++basedirs; + } + + if (!basedirs && (b = strpbrk (linkfile, "/:")) && *b == ':') + { + link = xmalloc (2 + strlen (linkfile) + 1); + memcpy (link, "./", 2); + strcpy (link + 2, linkfile); + } + else + { + /* Construct LINK as explained above. */ + link = xmalloc (3 * basedirs + strlen (linkfile) + 1); + for (i = 0; i < basedirs; i++) + memcpy (link + 3 * i, "../", 3); + strcpy (link + 3 * i, linkfile); + } + + return link; +} + +/* Construct and return a "transparent proxy" URL + reflecting changes made by --adjust-extension to the file component + (i.e., "basename") of the original URL, but leaving the "dirname" + of the URL (protocol://hostname... portion) untouched. + + Think: populating a squid cache via a recursive wget scrape, where + changing URLs to work locally with "file://..." is NOT desirable. + + Example: + + if + p = "//foo.com/bar.cgi?xyz" + and + link->local_name = "docroot/foo.com/bar.cgi?xyz.css" + then + + new_construct_func(p, link); + will return + "//foo.com/bar.cgi?xyz.css" + + Essentially, we do s/$(basename orig_url)/$(basename link->local_name)/ +*/ +static char * +convert_basename (const char *p, const struct urlpos *link) +{ + int len = link->size; + char *url = NULL; + char *org_basename = NULL, *local_basename; + char *result = NULL; + + if (*p == '"' || *p == '\'') + { + len -= 2; + p++; + } + + url = xstrndup (p, len); + + org_basename = strrchr (url, '/'); + if (org_basename) + org_basename++; + else + org_basename = url; + + local_basename = link->local_name ? strrchr (link->local_name, '/') : NULL; + if (local_basename) + local_basename++; + else + local_basename = url; + + /* + * If the basenames differ, graft the adjusted basename (local_basename) + * onto the original URL. + */ + if (strcmp (org_basename, local_basename) == 0) + result = url; + else + { + result = uri_merge (url, local_basename); + xfree (url); + } + + return result; +} + +/* Used by write_backup_file to remember which files have been + written. */ +static struct hash_table *converted_files; + +static void +write_backup_file (const char *file, downloaded_file_t downloaded_file_return) +{ + /* Rather than just writing over the original .html file with the + converted version, save the former to *.orig. Note we only do + this for files we've _successfully_ downloaded, so we don't + clobber .orig files sitting around from previous invocations. + On VMS, use "_orig" instead of ".orig". See "wget.h". */ + + if (!converted_files) + converted_files = make_string_hash_table (0); + + /* We can get called twice on the same URL thanks to the + convert_all_links() call in main. If we write the .orig file + each time in such a case, it'll end up containing the first-pass + conversion, not the original file. So, see if we've already been + called on this file. */ + if (!string_set_contains (converted_files, file)) + { + /* Construct the backup filename as the original name plus ".orig". */ + char buf[1024]; + size_t filename_len = strlen (file); + char *filename_plus_orig_suffix; + + if (filename_len < sizeof (buf) - 5) + filename_plus_orig_suffix = buf; + else + filename_plus_orig_suffix = xmalloc (filename_len + 5 + 1); + + /* TODO: hack this to work with css files */ + if (downloaded_file_return == FILE_DOWNLOADED_AND_HTML_EXTENSION_ADDED) + { + /* Just write "orig" over "html". We need to do it this way + because when we're checking to see if we've downloaded the + file before (to see if we can skip downloading it), we don't + know if it's a text/html file. Therefore we don't know yet + at that stage that -E is going to cause us to tack on + ".html", so we need to compare vs. the original URL plus + ".orig", not the original URL plus ".html.orig". */ + memcpy (filename_plus_orig_suffix, file, filename_len - 4); + memcpy (filename_plus_orig_suffix + filename_len - 4, "orig", 5); + } + else /* downloaded_file_return == FILE_DOWNLOADED_NORMALLY */ + { + /* Append ".orig" to the name. */ + memcpy (filename_plus_orig_suffix, file, filename_len); + strcpy (filename_plus_orig_suffix + filename_len, ORIG_SFX); + } + + /* Rename to .orig before former gets written over. */ + if (rename (file, filename_plus_orig_suffix) != 0) + logprintf (LOG_NOTQUIET, _("Cannot back up %s as %s: %s\n"), + file, filename_plus_orig_suffix, strerror (errno)); + + if (filename_plus_orig_suffix != buf) + xfree (filename_plus_orig_suffix); + + /* Remember that we've already written a .orig backup for this file. + Note that we never free this memory since we need it till the + convert_all_links() call, which is one of the last things the + program does before terminating. BTW, I'm not sure if it would be + safe to just set 'converted_file_ptr->string' to 'file' below, + rather than making a copy of the string... Another note is that I + thought I could just add a field to the urlpos structure saying + that we'd written a .orig file for this URL, but that didn't work, + so I had to make this separate list. + -- Dan Harkless + + This [adding a field to the urlpos structure] didn't work + because convert_file() is called from convert_all_links at + the end of the retrieval with a freshly built new urlpos + list. + -- Hrvoje Niksic + */ + string_set_add (converted_files, file); + } +} + +static bool find_fragment (const char *, int, const char **, const char **); + +/* Replace a string with NEW_TEXT. Ignore quoting. */ +static const char * +replace_plain (const char *p, int size, FILE *fp, const char *new_text) +{ + fputs (new_text, fp); + p += size; + return p; +} + +/* Replace an attribute's original text with NEW_TEXT. */ + +static const char * +replace_attr (const char *p, int size, FILE *fp, const char *new_text) +{ + bool quote_flag = false; + char quote_char = '\"'; /* use "..." for quoting, unless the + original value is quoted, in which + case reuse its quoting char. */ + const char *frag_beg, *frag_end; + + /* Structure of our string is: + "...old-contents..." + <--- size ---> (with quotes) + OR: + ...old-contents... + <--- size --> (no quotes) */ + + if (*p == '\"' || *p == '\'') + { + quote_char = *p; + quote_flag = true; + ++p; + size -= 2; /* disregard opening and closing quote */ + } + putc (quote_char, fp); + fputs (new_text, fp); + + /* Look for fragment identifier, if any. */ + if (find_fragment (p, size, &frag_beg, &frag_end)) + fwrite (frag_beg, 1, frag_end - frag_beg, fp); + p += size; + if (quote_flag) + ++p; + putc (quote_char, fp); + + return p; +} + +/* The same as REPLACE_ATTR, but used when replacing + because we need to + append "timeout_value; URL=" before the next_text. */ + +static const char * +replace_attr_refresh_hack (const char *p, int size, FILE *fp, + const char *new_text, int timeout) +{ + /* "0; URL=..." */ + char new_with_timeout[1024]; + + if (((unsigned) snprintf ( + new_with_timeout, sizeof (new_with_timeout), + "%d; URL=%s", timeout, new_text)) >= sizeof (new_with_timeout)) + { + // very unlikely fallback using heap memory + char *tmp = aprintf("%d; URL=%s", timeout, new_text); + const char *res = replace_attr (p, size, fp, tmp); + xfree (tmp); + return res; + } + + return replace_attr (p, size, fp, new_with_timeout); +} + +/* Find the first occurrence of '#' in [BEG, BEG+SIZE) that is not + preceded by '&'. If the character is not found, return zero. If + the character is found, return true and set BP and EP to point to + the beginning and end of the region. + + This is used for finding the fragment indentifiers in URLs. */ + +static bool +find_fragment (const char *beg, int size, const char **bp, const char **ep) +{ + const char *end = beg + size; + bool saw_amp = false; + for (; beg < end; beg++) + { + switch (*beg) + { + case '&': + saw_amp = true; + break; + case '#': + if (!saw_amp) + { + *bp = beg; + *ep = end; + return true; + } + /* fallthrough */ + default: + saw_amp = false; + } + } + return false; +} + +/* Quote FILE for use as local reference to an HTML file. + + We quote ? as %3F to avoid passing part of the file name as the + parameter when browsing the converted file through HTTP. However, + it is safe to do this only when `--adjust-extension' is turned on. + This is because converting "index.html?foo=bar" to + "index.html%3Ffoo=bar" would break local browsing, as the latter + isn't even recognized as an HTML file! However, converting + "index.html?foo=bar.html" to "index.html%3Ffoo=bar.html" should be + safe for both local and HTTP-served browsing. + + We always quote "#" as "%23", "%" as "%25" and ";" as "%3B" + because those characters have special meanings in URLs. */ + +static char * +local_quote_string (const char *file, bool no_html_quote) +{ + const char *from; + char *newname, *to, *res; + char buf[1024]; + size_t tolen; + + char *any = strpbrk (file, "?#%;"); + if (!any) + return no_html_quote ? strdup (file) : html_quote_string (file); + + /* Allocate space assuming the worst-case scenario, each character + having to be quoted. */ + tolen = 3 * strlen (file); + if (tolen < sizeof (buf)) + to = newname = buf; + else + to = newname = xmalloc (tolen + 1); + + for (from = file; *from; from++) + switch (*from) + { + case '%': + *to++ = '%'; + *to++ = '2'; + *to++ = '5'; + break; + case '#': + *to++ = '%'; + *to++ = '2'; + *to++ = '3'; + break; + case ';': + *to++ = '%'; + *to++ = '3'; + *to++ = 'B'; + break; + case '?': + if (opt.adjust_extension) + { + *to++ = '%'; + *to++ = '3'; + *to++ = 'F'; + break; + } + /* fallthrough */ + default: + *to++ = *from; + } + *to = '\0'; + + if (newname == buf) + return no_html_quote ? strdup (newname) : html_quote_string (newname); + + if (no_html_quote) + return newname; + + res = html_quote_string (newname); + xfree (newname); + return res; +} + +/* Book-keeping code for dl_file_url_map, dl_url_file_map, + downloaded_html_list, and downloaded_html_set. Other code calls + these functions to let us know that a file has been downloaded. */ + +#define ENSURE_TABLES_EXIST do { \ + if (!dl_file_url_map) \ + dl_file_url_map = make_string_hash_table (0); \ + if (!dl_url_file_map) \ + dl_url_file_map = make_string_hash_table (0); \ +} while (0) + +/* Return true if S1 and S2 are the same, except for "/index.html". + The three cases in which it returns one are (substitute any + substring for "foo"): + + m("foo/index.html", "foo/") ==> 1 + m("foo/", "foo/index.html") ==> 1 + m("foo", "foo/index.html") ==> 1 + m("foo", "foo/" ==> 1 + m("foo", "foo") ==> 1 */ + +static bool +match_except_index (const char *s1, const char *s2) +{ + int i; + const char *lng; + + /* Skip common substring. */ + for (i = 0; *s1 && *s2 && *s1 == *s2; s1++, s2++, i++) + ; + if (i == 0) + /* Strings differ at the very beginning -- bail out. We need to + check this explicitly to avoid `lng - 1' reading outside the + array. */ + return false; + + if (!*s1 && !*s2) + /* Both strings hit EOF -- strings are equal. */ + return true; + else if (*s1 && *s2) + /* Strings are randomly different, e.g. "/foo/bar" and "/foo/qux". */ + return false; + else if (*s1) + /* S1 is the longer one. */ + lng = s1; + else + /* S2 is the longer one. */ + lng = s2; + + /* foo */ /* foo/ */ + /* foo/index.html */ /* or */ /* foo/index.html */ + /* ^ */ /* ^ */ + + if (*lng != '/') + /* The right-hand case. */ + --lng; + + if (*lng == '/' && *(lng + 1) == '\0') + /* foo */ + /* foo/ */ + return true; + + return 0 == strcmp (lng, "/index.html"); +} + +static int +dissociate_urls_from_file_mapper (void *key, void *value, void *arg) +{ + char *mapping_url = (char *)key; + char *mapping_file = (char *)value; + char *file = (char *)arg; + + if (0 == strcmp (mapping_file, file)) + { + hash_table_remove (dl_url_file_map, mapping_url); + xfree (mapping_url); + xfree (mapping_file); + } + + /* Continue mapping. */ + return 0; +} + +/* Remove all associations from various URLs to FILE from dl_url_file_map. */ + +static void +dissociate_urls_from_file (const char *file) +{ + /* Can't use hash_table_iter_* because the table mutates while mapping. */ + hash_table_for_each (dl_url_file_map, dissociate_urls_from_file_mapper, + (char *) file); +} + +/* Register that URL has been successfully downloaded to FILE. This + is used by the link conversion code to convert references to URLs + to references to local files. It is also being used to check if a + URL has already been downloaded. */ + +void +register_download (const char *url, const char *file) +{ + char *old_file, *old_url; + + ENSURE_TABLES_EXIST; + + /* With some forms of retrieval, it is possible, although not likely + or particularly desirable. If both are downloaded, the second + download will override the first one. When that happens, + dissociate the old file name from the URL. */ + + if (hash_table_get_pair (dl_file_url_map, file, &old_file, &old_url)) + { + if (0 == strcmp (url, old_url)) + /* We have somehow managed to download the same URL twice. + Nothing to do. */ + return; + + if (match_except_index (url, old_url) + && !hash_table_contains (dl_url_file_map, url)) + /* The two URLs differ only in the "index.html" ending. For + example, one is "http://www.server.com/", and the other is + "http://www.server.com/index.html". Don't remove the old + one, just add the new one as a non-canonical entry. */ + goto url_only; + + hash_table_remove (dl_file_url_map, file); + xfree (old_file); + xfree (old_url); + + /* Remove all the URLs that point to this file. Yes, there can + be more than one such URL, because we store redirections as + multiple entries in dl_url_file_map. For example, if URL1 + redirects to URL2 which gets downloaded to FILE, we map both + URL1 and URL2 to FILE in dl_url_file_map. (dl_file_url_map + only points to URL2.) When another URL gets loaded to FILE, + we want both URL1 and URL2 dissociated from it. + + This is a relatively expensive operation because it performs + a linear search of the whole hash table, but it should be + called very rarely, only when two URLs resolve to the same + file name, *and* the ".1" extensions are turned off. + In other words, almost never. */ + dissociate_urls_from_file (file); + } + + hash_table_put (dl_file_url_map, xstrdup (file), xstrdup (url)); + + url_only: + /* A URL->FILE mapping is not possible without a FILE->URL mapping. + If the latter were present, it should have been removed by the + above `if'. So we could write: + + assert (!hash_table_contains (dl_url_file_map, url)); + + The above is correct when running in recursive mode where the + same URL always resolves to the same file. But if you do + something like: + + wget URL URL + + then the first URL will resolve to "FILE", and the other to + "FILE.1". In that case, FILE.1 will not be found in + dl_file_url_map, but URL will still point to FILE in + dl_url_file_map. */ + if (hash_table_get_pair (dl_url_file_map, url, &old_url, &old_file)) + { + hash_table_remove (dl_url_file_map, url); + xfree (old_url); + xfree (old_file); + } + + hash_table_put (dl_url_file_map, xstrdup (url), xstrdup (file)); +} + +/* Register that FROM has been redirected to "TO". This assumes that TO + is successfully downloaded and already registered using + register_download() above. */ + +void +register_redirection (const char *from, const char *to) +{ + char *file; + + ENSURE_TABLES_EXIST; + + file = hash_table_get (dl_url_file_map, to); + assert (file != NULL); + if (!hash_table_contains (dl_url_file_map, from)) + hash_table_put (dl_url_file_map, xstrdup (from), xstrdup (file)); +} + +/* Register that the file has been deleted. */ + +void +register_delete_file (const char *file) +{ + char *old_url, *old_file; + + ENSURE_TABLES_EXIST; + + if (!hash_table_get_pair (dl_file_url_map, file, &old_file, &old_url)) + return; + + hash_table_remove (dl_file_url_map, file); + xfree (old_file); + xfree (old_url); + dissociate_urls_from_file (file); +} + +/* Register that FILE is an HTML file that has been downloaded. */ + +void +register_html (const char *file) +{ + if (!downloaded_html_set) + downloaded_html_set = make_string_hash_table (0); + string_set_add (downloaded_html_set, file); +} + +/* Register that FILE is a CSS file that has been downloaded. */ + +void +register_css (const char *file) +{ + if (!downloaded_css_set) + downloaded_css_set = make_string_hash_table (0); + string_set_add (downloaded_css_set, file); +} + +/* Cleanup the data structures associated with this file. */ + +#if defined DEBUG_MALLOC || defined TESTING +static void downloaded_files_free (void); + +void +convert_cleanup (void) +{ + if (dl_file_url_map) + { + free_keys_and_values (dl_file_url_map); + hash_table_destroy (dl_file_url_map); + dl_file_url_map = NULL; + } + if (dl_url_file_map) + { + free_keys_and_values (dl_url_file_map); + hash_table_destroy (dl_url_file_map); + dl_url_file_map = NULL; + } + if (downloaded_html_set) + string_set_free (downloaded_html_set); + if (downloaded_css_set) + string_set_free (downloaded_css_set); + downloaded_files_free (); + if (converted_files) + string_set_free (converted_files); +} +#endif + +/* Book-keeping code for downloaded files that enables extension + hacks. */ + +/* This table should really be merged with dl_file_url_map and + downloaded_html_files. This was originally a list, but I changed + it to a hash table because it was actually taking a lot of time to + find things in it. */ + +static struct hash_table *downloaded_files_hash; + +/* We're storing "modes" of type downloaded_file_t in the hash table. + However, our hash tables only accept pointers for keys and values. + So when we need a pointer, we use the address of a + downloaded_file_t variable of static storage. */ + +static downloaded_file_t * +downloaded_mode_to_ptr (downloaded_file_t mode) +{ + static downloaded_file_t + v1 = FILE_NOT_ALREADY_DOWNLOADED, + v2 = FILE_DOWNLOADED_NORMALLY, + v3 = FILE_DOWNLOADED_AND_HTML_EXTENSION_ADDED, + v4 = CHECK_FOR_FILE; + + switch (mode) + { + case FILE_NOT_ALREADY_DOWNLOADED: + return &v1; + case FILE_DOWNLOADED_NORMALLY: + return &v2; + case FILE_DOWNLOADED_AND_HTML_EXTENSION_ADDED: + return &v3; + case CHECK_FOR_FILE: + return &v4; + } + return NULL; +} + +/* Remembers which files have been downloaded. In the standard case, + should be called with mode == FILE_DOWNLOADED_NORMALLY for each + file we actually download successfully (i.e. not for ones we have + failures on or that we skip due to -N). + + When we've downloaded a file and tacked on a ".html" extension due + to -E, call this function with + FILE_DOWNLOADED_AND_HTML_EXTENSION_ADDED rather than + FILE_DOWNLOADED_NORMALLY. + + If you just want to check if a file has been previously added + without adding it, call with mode == CHECK_FOR_FILE. Please be + sure to call this function with local filenames, not remote + URLs. */ + +downloaded_file_t +downloaded_file (downloaded_file_t mode, const char *file) +{ + downloaded_file_t *ptr; + + if (mode == CHECK_FOR_FILE) + { + if (!downloaded_files_hash) + return FILE_NOT_ALREADY_DOWNLOADED; + ptr = hash_table_get (downloaded_files_hash, file); + if (!ptr) + return FILE_NOT_ALREADY_DOWNLOADED; + return *ptr; + } + + if (!downloaded_files_hash) + downloaded_files_hash = make_string_hash_table (0); + + ptr = hash_table_get (downloaded_files_hash, file); + if (ptr) + return *ptr; + + ptr = downloaded_mode_to_ptr (mode); + hash_table_put (downloaded_files_hash, xstrdup (file), ptr); + + return FILE_NOT_ALREADY_DOWNLOADED; +} + +#if defined DEBUG_MALLOC || defined TESTING +static void +downloaded_files_free (void) +{ + if (downloaded_files_hash) + { + hash_table_iterator iter; + for (hash_table_iterate (downloaded_files_hash, &iter); + hash_table_iter_next (&iter); + ) + xfree (iter.key); + hash_table_destroy (downloaded_files_hash); + downloaded_files_hash = NULL; + } +} +#endif + +/* The function returns the pointer to the malloc-ed quoted version of + string s. It will recognize and quote numeric and special graphic + entities, as per RFC1866: + + `&' -> `&' + `<' -> `<' + `>' -> `>' + `"' -> `"' + SP -> ` ' + + No other entities are recognized or replaced. */ +char * +html_quote_string (const char *s) +{ + const char *b = s; + char *p, *res; + int i; + + /* Pass through the string, and count the new size. */ + for (i = 0; *s; s++, i++) + { + if (*s == '&') + i += 4; /* `amp;' */ + else if (*s == '<' || *s == '>') + i += 3; /* `lt;' and `gt;' */ + else if (*s == '\"') + i += 5; /* `quot;' */ + else if (*s == ' ') + i += 4; /* #32; */ + } + res = xmalloc (i + 1); + s = b; + for (p = res; *s; s++) + { + switch (*s) + { + case '&': + *p++ = '&'; + *p++ = 'a'; + *p++ = 'm'; + *p++ = 'p'; + *p++ = ';'; + break; + case '<': case '>': + *p++ = '&'; + *p++ = (*s == '<' ? 'l' : 'g'); + *p++ = 't'; + *p++ = ';'; + break; + case '\"': + *p++ = '&'; + *p++ = 'q'; + *p++ = 'u'; + *p++ = 'o'; + *p++ = 't'; + *p++ = ';'; + break; + case ' ': + *p++ = '&'; + *p++ = '#'; + *p++ = '3'; + *p++ = '2'; + *p++ = ';'; + break; + default: + *p++ = *s; + } + } + *p = '\0'; + return res; +} + +/* + * vim: et ts=2 sw=2 + */ diff --git a/src/convert.h b/src/convert.h new file mode 100644 index 0000000..531afbd --- /dev/null +++ b/src/convert.h @@ -0,0 +1,115 @@ +/* Declarations for convert.c + Copyright (C) 2003-2006, 2009-2011, 2015, 2018-2020 Free Software + Foundation, Inc. + +This file is part of GNU Wget. + +GNU Wget is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + +GNU Wget 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 Wget. If not, see . + +Additional permission under GNU GPL version 3 section 7 + +If you modify this program, or any covered work, by linking or +combining it with the OpenSSL project's OpenSSL library (or a +modified version of that library), containing parts covered by the +terms of the OpenSSL or SSLeay licenses, the Free Software Foundation +grants you additional permission to convey the resulting work. +Corresponding Source for a non-source form of such a combination +shall include the source code for the parts of OpenSSL used as well +as that of the covered work. */ + +#ifndef CONVERT_H +#define CONVERT_H + +struct hash_table; /* forward decl */ +extern struct hash_table *dl_url_file_map; +extern struct hash_table *downloaded_html_set; +extern struct hash_table *downloaded_css_set; + +enum convert_options { + CO_NOCONVERT = 0, /* don't convert this URL */ + CO_CONVERT_TO_RELATIVE, /* convert to relative, e.g. to + "../../otherdir/foo.gif" */ + CO_CONVERT_BASENAME_ONLY, /* convert the file portion only (basename) + leaving the rest of the URL unchanged */ + CO_CONVERT_TO_COMPLETE, /* convert to absolute, e.g. to + "http://orighost/somedir/bar.jpg". */ + CO_NULLIFY_BASE /* change to empty string. */ +}; + +struct url; + +/* A structure that defines the whereabouts of a URL, i.e. its + position in an HTML document, etc. */ + +struct urlpos { + struct url *url; /* the URL of the link, after it has + been merged with the base */ + char *local_name; /* local file to which it was saved + (used by convert_links) */ + + /* reserved for special links such as which are + used when converting links, but ignored when downloading. */ + unsigned int ignore_when_downloading :1; + + /* Information about the original link: */ + + unsigned int link_relative_p :1; /* the link was relative */ + unsigned int link_complete_p :1; /* the link was complete (had host name) */ + unsigned int link_base_p :1; /* the url came from */ + unsigned int link_inline_p :1; /* needed to render the page */ + unsigned int link_css_p :1; /* the url came from CSS */ + unsigned int link_noquote_html_p :1; /* from HTML, but doesn't need " */ + unsigned int link_expect_html :1; /* expected to contain HTML */ + unsigned int link_expect_css :1; /* expected to contain CSS */ + + unsigned int link_refresh_p :1; /* link was received from + */ + int refresh_timeout; /* for reconstructing the refresh. */ + + /* Conversion requirements: */ + enum convert_options convert; /* is conversion required? */ + + /* URL's position in the buffer. */ + int pos, size; + + struct urlpos *next; /* next list element */ +}; + +/* downloaded_file() takes a parameter of this type and returns this type. */ +typedef enum +{ + /* Return enumerators: */ + FILE_NOT_ALREADY_DOWNLOADED = 0, + + /* Return / parameter enumerators: */ + FILE_DOWNLOADED_NORMALLY, + FILE_DOWNLOADED_AND_HTML_EXTENSION_ADDED, + + /* Parameter enumerators: */ + CHECK_FOR_FILE +} downloaded_file_t; + +downloaded_file_t downloaded_file (downloaded_file_t, const char *); + +void register_download (const char *, const char *); +void register_redirection (const char *, const char *); +void register_html (const char *); +void register_css (const char *); +void register_delete_file (const char *); +void convert_all_links (void); +void convert_cleanup (void); + +char *html_quote_string (const char *); + +#endif /* CONVERT_H */ diff --git a/src/cookies.c b/src/cookies.c new file mode 100644 index 0000000..6ddb931 --- /dev/null +++ b/src/cookies.c @@ -0,0 +1,1539 @@ +/* Support for cookies. + Copyright (C) 2001-2011, 2015, 2018-2020 Free Software Foundation, + Inc. + +This file is part of GNU Wget. + +GNU Wget is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 3 of the License, or (at +your option) any later version. + +GNU Wget 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 Wget. If not, see . + +Additional permission under GNU GPL version 3 section 7 + +If you modify this program, or any covered work, by linking or +combining it with the OpenSSL project's OpenSSL library (or a +modified version of that library), containing parts covered by the +terms of the OpenSSL or SSLeay licenses, the Free Software Foundation +grants you additional permission to convey the resulting work. +Corresponding Source for a non-source form of such a combination +shall include the source code for the parts of OpenSSL used as well +as that of the covered work. */ + +/* Written by Hrvoje Niksic. Parts are loosely inspired by the + cookie patch submitted by Tomasz Wegrzanowski. + + This implements the client-side cookie support, as specified + (loosely) by Netscape's "preliminary specification", currently + available at: + + http://wp.netscape.com/newsref/std/cookie_spec.html + + rfc2109 is not supported because of its incompatibilities with the + above widely-used specification. rfc2965 is entirely ignored, + since popular client software doesn't implement it, and even the + sites that do send Set-Cookie2 also emit Set-Cookie for + compatibility. */ + +#include "wget.h" + +#include +#include +#include +#include +#include +#include +#include +#ifdef HAVE_LIBPSL +# include +#endif +#include "utils.h" +#include "hash.h" +#include "cookies.h" +#include "http.h" /* for http_atotm */ +#include "c-strcase.h" + + +/* Declarations of `struct cookie' and the most basic functions. */ + +/* Cookie jar serves as cookie storage and a means of retrieving + cookies efficiently. All cookies with the same domain are stored + in a linked list called "chain". A cookie chain can be reached by + looking up the domain in the cookie jar's chains_by_domain table. + + For example, to reach all the cookies under google.com, one must + execute hash_table_get(jar->chains_by_domain, "google.com"). Of + course, when sending a cookie to `www.google.com', one must search + for cookies that belong to either `www.google.com' or `google.com' + -- but the point is that the code doesn't need to go through *all* + the cookies. */ + +struct cookie_jar { + /* Cookie chains indexed by domain. */ + struct hash_table *chains; + + int cookie_count; /* number of cookies in the jar. */ +}; + +/* Value set by entry point functions, so that the low-level + routines don't need to call time() all the time. */ +static time_t cookies_now; + +struct cookie_jar * +cookie_jar_new (void) +{ + struct cookie_jar *jar = xnew (struct cookie_jar); + jar->chains = make_nocase_string_hash_table (0); + jar->cookie_count = 0; + return jar; +} + +struct cookie { + char *domain; /* domain of the cookie */ + int port; /* port number */ + char *path; /* path prefix of the cookie */ + + unsigned discard_requested :1;/* whether cookie was created to + request discarding another + cookie. */ + + unsigned secure :1; /* whether cookie should be + transmitted over non-https + connections. */ + unsigned domain_exact :1; /* whether DOMAIN must match as a + whole. */ + + unsigned permanent :1; /* whether the cookie should outlive + the session. */ + time_t expiry_time; /* time when the cookie expires, 0 + means undetermined. */ + + char *attr; /* cookie attribute name */ + char *value; /* cookie attribute value */ + + struct cookie *next; /* used for chaining of cookies in the + same domain. */ +}; + +#define PORT_ANY (-1) + +/* Allocate and return a new, empty cookie structure. */ + +static struct cookie * +cookie_new (void) +{ + struct cookie *cookie = xnew0 (struct cookie); + + /* Both cookie->permanent and cookie->expiry_time are now 0. This + means that the cookie doesn't expire, but is only valid for this + session (i.e. not written out to disk). */ + + cookie->port = PORT_ANY; + return cookie; +} + +/* Non-zero if the cookie has expired. Assumes cookies_now has been + set by one of the entry point functions. */ + +static bool +cookie_expired_p (const struct cookie *c) +{ + return c->expiry_time != 0 && c->expiry_time < cookies_now; +} + +/* Deallocate COOKIE and its components. */ + +static void +delete_cookie (struct cookie *cookie) +{ + xfree (cookie->domain); + xfree (cookie->path); + xfree (cookie->attr); + xfree (cookie->value); + xfree (cookie); +} + +/* Functions for storing cookies. + + All cookies can be reached beginning with jar->chains. The key in + that table is the domain name, and the value is a linked list of + all cookies from that domain. Every new cookie is placed on the + head of the list. */ + +/* Find and return a cookie in JAR whose domain, path, and attribute + name correspond to COOKIE. If found, PREVPTR will point to the + location of the cookie previous in chain, or NULL if the found + cookie is the head of a chain. + + If no matching cookie is found, return NULL. */ + +static struct cookie * +find_matching_cookie (struct cookie_jar *jar, struct cookie *cookie, + struct cookie **prevptr) +{ + struct cookie *chain, *prev; + + chain = hash_table_get (jar->chains, cookie->domain); + if (!chain) + goto nomatch; + + prev = NULL; + for (; chain; prev = chain, chain = chain->next) + if (0 == strcmp (cookie->path, chain->path) + && 0 == strcmp (cookie->attr, chain->attr) + && cookie->port == chain->port) + { + *prevptr = prev; + return chain; + } + + nomatch: + *prevptr = NULL; + return NULL; +} + +/* Store COOKIE to the jar. + + This is done by placing COOKIE at the head of its chain. However, + if COOKIE matches a cookie already in memory, as determined by + find_matching_cookie, the old cookie is unlinked and destroyed. + + The key of each chain's hash table entry is allocated only the + first time; next hash_table_put's reuse the same key. */ + +static void +store_cookie (struct cookie_jar *jar, struct cookie *cookie) +{ + struct cookie *chain_head; + char *chain_key; + + if (hash_table_get_pair (jar->chains, cookie->domain, + &chain_key, &chain_head)) + { + /* A chain of cookies in this domain already exists. Check for + duplicates -- if an extant cookie exactly matches our domain, + port, path, and name, replace it. */ + struct cookie *prev; + struct cookie *victim = find_matching_cookie (jar, cookie, &prev); + + if (victim) + { + /* Remove VICTIM from the chain. COOKIE will be placed at + the head. */ + if (prev) + { + prev->next = victim->next; + cookie->next = chain_head; + } + else + { + /* prev is NULL; apparently VICTIM was at the head of + the chain. This place will be taken by COOKIE, so + all we need to do is: */ + cookie->next = victim->next; + } + delete_cookie (victim); + --jar->cookie_count; + DEBUGP (("Deleted old cookie (to be replaced.)\n")); + } + else + cookie->next = chain_head; + } + else + { + /* We are now creating the chain. Use a copy of cookie->domain + as the key for the life-time of the chain. Using + cookie->domain would be unsafe because the life-time of the + chain may exceed the life-time of the cookie. (Cookies may + be deleted from the chain by this very function.) */ + cookie->next = NULL; + chain_key = xstrdup (cookie->domain); + } + + hash_table_put (jar->chains, chain_key, cookie); + ++jar->cookie_count; + + IF_DEBUG + { + time_t exptime = cookie->expiry_time; + DEBUGP (("\nStored cookie %s %d%s %s <%s> <%s> [expiry %s] %s %s\n", + cookie->domain, cookie->port, + cookie->port == PORT_ANY ? " (ANY)" : "", + cookie->path, + cookie->permanent ? "permanent" : "session", + cookie->secure ? "secure" : "insecure", + cookie->expiry_time ? datetime_str (exptime) : "none", + cookie->attr, cookie->value)); + } +} + +/* Discard a cookie matching COOKIE's domain, port, path, and + attribute name. This gets called when we encounter a cookie whose + expiry date is in the past, or whose max-age is set to 0. The + former corresponds to netscape cookie spec, while the latter is + specified by rfc2109. */ + +static void +discard_matching_cookie (struct cookie_jar *jar, struct cookie *cookie) +{ + struct cookie *prev, *victim; + + if (!hash_table_count (jar->chains)) + /* No elements == nothing to discard. */ + return; + + victim = find_matching_cookie (jar, cookie, &prev); + if (victim) + { + if (prev) + /* Simply unchain the victim. */ + prev->next = victim->next; + else + { + /* VICTIM was head of its chain. We need to place a new + cookie at the head. */ + char *chain_key = NULL; + int res; + + res = hash_table_get_pair (jar->chains, victim->domain, + &chain_key, NULL); + + if (res == 0) + { + logprintf (LOG_VERBOSE, _("Unable to get cookie for %s\n"), + victim->domain); + } + if (!victim->next) + { + /* VICTIM was the only cookie in the chain. Destroy the + chain and deallocate the chain key. */ + hash_table_remove (jar->chains, victim->domain); + xfree (chain_key); + } + else + hash_table_put (jar->chains, chain_key, victim->next); + } + delete_cookie (victim); + DEBUGP (("Discarded old cookie.\n")); + } +} + +/* Functions for parsing the `Set-Cookie' header, and creating new + cookies from the wire. */ + +#define TOKEN_IS(token, string_literal) \ + BOUNDED_EQUAL_NO_CASE (token.b, token.e, string_literal) + +#define TOKEN_NON_EMPTY(token) (token.b != NULL && token.b != token.e) + +/* Parse the contents of the `Set-Cookie' header. The header looks + like this: + + name1=value1; name2=value2; ... + + Trailing semicolon is optional; spaces are allowed between all + tokens. Additionally, values may be quoted. + + A new cookie is returned upon success, NULL otherwise. + + The first name-value pair will be used to set the cookie's + attribute name and value. Subsequent parameters will be checked + against field names such as `domain', `path', etc. Recognized + fields will be parsed and the corresponding members of COOKIE + filled. */ + +static struct cookie * +parse_set_cookie (const char *set_cookie, bool silent) +{ + const char *ptr = set_cookie; + struct cookie *cookie = cookie_new (); + param_token name, value; + + if (!extract_param (&ptr, &name, &value, ';', NULL)) + goto error; + if (!value.b) + goto error; + + /* If the value is quoted, do not modify it. */ + if (*(value.b - 1) == '"') + value.b--; + if (*value.e == '"') + value.e++; + + cookie->attr = strdupdelim (name.b, name.e); + cookie->value = strdupdelim (value.b, value.e); + + while (extract_param (&ptr, &name, &value, ';', NULL)) + { + if (TOKEN_IS (name, "domain")) + { + if (!TOKEN_NON_EMPTY (value)) + goto error; + xfree (cookie->domain); + /* Strictly speaking, we should set cookie->domain_exact if the + domain doesn't begin with a dot. But many sites set the + domain to "foo.com" and expect "subhost.foo.com" to get the + cookie, and it apparently works in browsers. */ + if (*value.b == '.') + ++value.b; + cookie->domain = strdupdelim (value.b, value.e); + } + else if (TOKEN_IS (name, "path")) + { + if (!TOKEN_NON_EMPTY (value)) + goto error; + xfree (cookie->path); + cookie->path = strdupdelim (value.b, value.e); + } + else if (TOKEN_IS (name, "expires")) + { + char value_copy[128]; + size_t value_len = value.e - value.b; + time_t expires; + + if (!TOKEN_NON_EMPTY (value) || value_len >= sizeof (value_copy)) + goto error; + + memcpy (value_copy, value.b, value_len); + value_copy[value_len] = 0; + + /* Check if expiration spec is valid. + If not, assume default (cookie doesn't expire, but valid only for + this session.) */ + expires = http_atotm (value_copy); + if (expires != (time_t) -1) + { + cookie->permanent = 1; + cookie->expiry_time = expires; + /* According to netscape's specification, expiry time in + the past means that discarding of a matching cookie + is requested. */ + if (cookie->expiry_time < cookies_now) + cookie->discard_requested = 1; + } + } + else if (TOKEN_IS (name, "max-age")) + { + double maxage = -1; + char value_copy[32]; + size_t value_len = value.e - value.b; + + if (!TOKEN_NON_EMPTY (value) || value_len >= sizeof (value_copy)) + goto error; + + memcpy (value_copy, value.b, value_len); + value_copy[value_len] = 0; + + sscanf (value_copy, "%lf", &maxage); + if (maxage == -1) + /* something went wrong. */ + goto error; + cookie->permanent = 1; + cookie->expiry_time = cookies_now + (time_t) maxage; + + /* According to rfc2109, a cookie with max-age of 0 means that + discarding of a matching cookie is requested. */ + if (maxage == 0) + cookie->discard_requested = 1; + } + else if (TOKEN_IS (name, "secure")) + { + /* ignore value completely */ + cookie->secure = 1; + } + /* else: Ignore unrecognized attribute. */ + } + if (*ptr) + /* extract_param has encountered a syntax error */ + goto error; + + /* The cookie has been successfully constructed; return it. */ + return cookie; + + error: + if (!silent) + logprintf (LOG_NOTQUIET, + _("Syntax error in Set-Cookie: %s at position %d.\n"), + quotearg_style (escape_quoting_style, set_cookie), + (int) (ptr - set_cookie)); + delete_cookie (cookie); + return NULL; +} + +#undef TOKEN_IS +#undef TOKEN_NON_EMPTY + +/* Sanity checks. These are important, otherwise it is possible for + mailcious attackers to destroy important cookie information and/or + violate your privacy. */ + + +#define REQUIRE_DIGITS(p) do { \ + if (!c_isdigit (*p)) \ + return false; \ + for (++p; c_isdigit (*p); p++) \ + ; \ +} while (0) + +#define REQUIRE_DOT(p) do { \ + if (*p++ != '.') \ + return false; \ +} while (0) + +/* Check whether ADDR matches .... + + We don't want to call network functions like inet_addr() because + all we need is a check, preferably one that is small, fast, and + well-defined. */ + +static bool +numeric_address_p (const char *addr) +{ + const char *p = addr; + + REQUIRE_DIGITS (p); /* A */ + REQUIRE_DOT (p); /* . */ + REQUIRE_DIGITS (p); /* B */ + REQUIRE_DOT (p); /* . */ + REQUIRE_DIGITS (p); /* C */ + REQUIRE_DOT (p); /* . */ + REQUIRE_DIGITS (p); /* D */ + + if (*p != '\0') + return false; + return true; +} + +/* Check whether COOKIE_DOMAIN is an appropriate domain for HOST. + Originally I tried to make the check compliant with rfc2109, but + the sites deviated too often, so I had to fall back to "tail + matching", as defined by the original Netscape's cookie spec. + + Wget now uses libpsl to check domain names against a public suffix + list to see if they are valid. However, since we don't provide a + psl on our own, if libpsl is compiled without a public suffix list, + fall back to using the original "tail matching" heuristic. Also if + libpsl is unable to convert the domain to lowercase, which means that + it doesn't have any runtime conversion support, we again fall back to + "tail matching" since libpsl states the results are unpredictable with + upper case strings. + */ + +#ifdef HAVE_LIBPSL +static psl_ctx_t *psl; +#endif + +static bool +check_domain_match (const char *cookie_domain, const char *host) +{ +#ifdef HAVE_LIBPSL + static int init_psl; + char *cookie_domain_lower = NULL; + char *host_lower = NULL; + int is_acceptable; + + DEBUGP (("cdm: 1\n")); + if (!init_psl) + { + init_psl = 1; + +#ifdef HAVE_PSL_LATEST + if ((psl = psl_latest (NULL))) + goto have_psl; + + DEBUGP (("\nPSL: Failed to load any PSL data. " + "Falling back to insecure heuristics.\n")); +#else + if ((psl = psl_builtin ()) && !psl_builtin_outdated ()) + goto have_psl; + + DEBUGP (("\nPSL: built-in data outdated. " + "Trying to load data from %s.\n", + quote (psl_builtin_filename ()))); + + if ((psl = psl_load_file (psl_builtin_filename ()))) + goto have_psl; + + DEBUGP (("\nPSL: %s not found or not readable. " + "Falling back to built-in data.\n", + quote (psl_builtin_filename ()))); + + if (!(psl = psl_builtin ())) + { + DEBUGP (("\nPSL: libpsl not built with a public suffix list. " + "Falling back to insecure heuristics.\n")); + goto no_psl; + } +#endif + } + else if (!psl) + goto no_psl; + +have_psl: + if (psl_str_to_utf8lower (cookie_domain, NULL, NULL, &cookie_domain_lower) == PSL_SUCCESS && + psl_str_to_utf8lower (host, NULL, NULL, &host_lower) == PSL_SUCCESS) + { + is_acceptable = psl_is_cookie_domain_acceptable (psl, host_lower, cookie_domain_lower); + } + else + { + DEBUGP (("libpsl unable to parse domain name. " + "Falling back to simple heuristics.\n")); + goto no_psl; + } + + xfree (cookie_domain_lower); + xfree (host_lower); + + return is_acceptable == 1; + +no_psl: + /* Cleanup the PSL pointers first */ + xfree (cookie_domain_lower); + xfree (host_lower); +#endif + + /* For efficiency make some elementary checks first */ + DEBUGP (("cdm: 2\n")); + + /* For the sake of efficiency, check for exact match first. */ + if (0 == strcasecmp (cookie_domain, host)) + return true; + + DEBUGP (("cdm: 3\n")); + + /* HOST must match the tail of cookie_domain. */ + if (!match_tail (host, cookie_domain, true)) + return false; + + /* We know that COOKIE_DOMAIN is a subset of HOST; however, we must + make sure that somebody is not trying to set the cookie for a + subdomain shared by many entities. For example, "company.co.uk" + must not be allowed to set a cookie for ".co.uk". On the other + hand, "sso.redhat.de" should be able to set a cookie for + ".redhat.de". + + The only marginally sane way to handle this I can think of is to + reject on the basis of the length of the second-level domain name + (but when the top-level domain is unknown), with the assumption + that those of three or less characters could be reserved. For + example: + + .co.org -> works because the TLD is known + .co.uk -> doesn't work because "co" is only two chars long + .com.au -> doesn't work because "com" is only 3 chars long + .cnn.uk -> doesn't work because "cnn" is also only 3 chars long (ugh) + .cnn.de -> doesn't work for the same reason (ugh!!) + .abcd.de -> works because "abcd" is 4 chars long + .img.cnn.de -> works because it's not trying to set the 2nd level domain + .cnn.co.uk -> works for the same reason + + That should prevent misuse, while allowing reasonable usage. If + someone knows of a better way to handle this, please let me + know. */ + { + const char *p = cookie_domain; + int dccount = 1; /* number of domain components */ + int ldcl = 0; /* last domain component length */ + int nldcl = 0; /* next to last domain component length */ + int out; + if (*p == '.') + /* Ignore leading period in this calculation. */ + ++p; + DEBUGP (("cdm: 4\n")); + for (out = 0; !out; p++) + switch (*p) + { + case '\0': + out = 1; + break; + case '.': + if (ldcl == 0) + /* Empty domain component found -- the domain is invalid. */ + return false; + if (*(p + 1) == '\0') + { + /* Tolerate trailing '.' by not treating the domain as + one ending with an empty domain component. */ + out = 1; + break; + } + nldcl = ldcl; + ldcl = 0; + ++dccount; + break; + default: + ++ldcl; + } + + DEBUGP (("cdm: 5\n")); + + if (dccount < 2) + return false; + + DEBUGP (("cdm: 6\n")); + + if (dccount == 2) + { + size_t i; + int known_toplevel = false; + static const char *known_toplevel_domains[] = { + ".com", ".edu", ".net", ".org", ".gov", ".mil", ".int" + }; + for (i = 0; i < countof (known_toplevel_domains); i++) + if (match_tail (cookie_domain, known_toplevel_domains[i], true)) + { + known_toplevel = true; + break; + } + if (!known_toplevel && nldcl <= 3) + return false; + } + } + + DEBUGP (("cdm: 7\n")); + + /* Don't allow the host "foobar.com" to set a cookie for domain + "bar.com". */ + if (*cookie_domain != '.') + { + int dlen = strlen (cookie_domain); + int hlen = strlen (host); + /* cookie host: hostname.foobar.com */ + /* desired domain: bar.com */ + /* '.' must be here in host-> ^ */ + if (hlen > dlen && host[hlen - dlen - 1] != '.') + return false; + } + + DEBUGP (("cdm: 8\n")); + + return true; +} + +static int path_matches (const char *, const char *); + +/* Check whether PATH begins with COOKIE_PATH. */ + +static bool +check_path_match (const char *cookie_path, const char *path) +{ + return path_matches (path, cookie_path) != 0; +} + +/* Process the HTTP `Set-Cookie' header. This results in storing the + cookie or discarding a matching one, or ignoring it completely, all + depending on the contents. */ + +void +cookie_handle_set_cookie (struct cookie_jar *jar, + const char *host, int port, + const char *path, const char *set_cookie) +{ + struct cookie *cookie; + cookies_now = time (NULL); + char buf[1024], *tmp; + size_t pathlen = strlen(path); + + /* Wget's paths don't begin with '/' (blame rfc1808), but cookie + usage assumes /-prefixed paths. Until the rest of Wget is fixed, + simply prepend slash to PATH. */ + if (pathlen < sizeof (buf) - 1) + tmp = buf; + else + tmp = xmalloc (pathlen + 2); + + *tmp = '/'; + memcpy (tmp + 1, path, pathlen + 1); + path = tmp; + + cookie = parse_set_cookie (set_cookie, false); + if (!cookie) + goto out; + + /* Sanitize parts of cookie. */ + + if (!cookie->domain) + { + cookie->domain = xstrdup (host); + cookie->domain_exact = 1; + /* Set the port, but only if it's non-default. */ + if (port != 80 && port != 443) + cookie->port = port; + } + else + { + if (!check_domain_match (cookie->domain, host)) + { + logprintf (LOG_NOTQUIET, + _("Cookie coming from %s attempted to set domain to "), + quotearg_style (escape_quoting_style, host)); + logprintf (LOG_NOTQUIET, + _("%s\n"), + quotearg_style (escape_quoting_style, cookie->domain)); + cookie->discard_requested = true; + } + } + + if (!cookie->path) + { + /* The cookie doesn't set path: set it to the URL path, sans the + file part ("/dir/file" truncated to "/dir/"). */ + char *trailing_slash = strrchr (path, '/'); + if (trailing_slash) + cookie->path = strdupdelim (path, trailing_slash + 1); + else + /* no slash in the string -- can this even happen? */ + cookie->path = xstrdup (path); + } + else + { + /* The cookie sets its own path; verify that it is legal. */ + if (!check_path_match (cookie->path, path)) + { + DEBUGP (("Attempt to fake the path: %s, %s\n", + cookie->path, path)); + goto out; + } + } + + /* Now store the cookie, or discard an existing cookie, if + discarding was requested. */ + + if (cookie->discard_requested) + { + discard_matching_cookie (jar, cookie); + goto out; + } + + store_cookie (jar, cookie); + if (tmp != buf) + xfree (tmp); + return; + + out: + if (cookie) + delete_cookie (cookie); + if (tmp != buf) + xfree (tmp); +} + +/* Support for sending out cookies in HTTP requests, based on + previously stored cookies. Entry point is + `build_cookies_request'. */ + +/* Return a count of how many times CHR occurs in STRING. */ + +static int +count_char (const char *string, char chr) +{ + const char *p; + int count = 0; + for (p = string; *p; p++) + if (*p == chr) + ++count; + return count; +} + +/* Find the cookie chains whose domains match HOST and store them to + DEST. + + A cookie chain is the head of a list of cookies that belong to a + host/domain. Given HOST "img.search.xemacs.org", this function + will return the chains for "img.search.xemacs.org", + "search.xemacs.org", and "xemacs.org" -- those of them that exist + (if any), that is. + + DEST should be large enough to accept (in the worst case) as many + elements as there are domain components of HOST. */ + +static int +find_chains_of_host (struct cookie_jar *jar, const char *host, + struct cookie *dest[]) +{ + int dest_count = 0; + int passes, passcnt; + + /* Bail out quickly if there are no cookies in the jar. */ + if (!hash_table_count (jar->chains)) + return 0; + + if (numeric_address_p (host)) + /* If host is an IP address, only check for the exact match. */ + passes = 1; + else + /* Otherwise, check all the subdomains except the top-level (last) + one. As a domain with N components has N-1 dots, the number of + passes equals the number of dots. */ + passes = count_char (host, '.'); + + passcnt = 0; + + /* Find chains that match HOST, starting with exact match and + progressing to less specific domains. For instance, given HOST + fly.srk.fer.hr, first look for fly.srk.fer.hr's chain, then + srk.fer.hr's, then fer.hr's. */ + while (1) + { + struct cookie *chain = hash_table_get (jar->chains, host); + if (chain) + dest[dest_count++] = chain; + if (++passcnt >= passes) + break; + host = strchr (host, '.') + 1; + } + + return dest_count; +} + +/* If FULL_PATH begins with PREFIX, return the length of PREFIX, zero + otherwise. */ + +static int +path_matches (const char *full_path, const char *prefix) +{ + int len = strlen (prefix); + + if (0 != strncmp (full_path, prefix, len)) + /* FULL_PATH doesn't begin with PREFIX. */ + return 0; + + /* Length of PREFIX determines the quality of the match. */ + return len + 1; +} + +/* Return true if COOKIE matches the provided parameters of the URL + being downloaded: HOST, PORT, PATH, and SECFLAG. + + If PATH_GOODNESS is non-NULL, store the "path goodness" value + there. That value is a measure of how closely COOKIE matches PATH, + used for ordering cookies. */ + +static bool +cookie_matches_url (const struct cookie *cookie, + const char *host, int port, const char *path, + bool secflag, int *path_goodness) +{ + int pg; + + if (cookie_expired_p (cookie)) + /* Ignore stale cookies. Don't bother unchaining the cookie at + this point -- Wget is a relatively short-lived application, and + stale cookies will not be saved by `save_cookies'. On the + other hand, this function should be as efficient as + possible. */ + return false; + + if (cookie->secure && !secflag) + /* Don't transmit secure cookies over insecure connections. */ + return false; + if (cookie->port != PORT_ANY && cookie->port != port) + return false; + + /* If exact domain match is required, verify that cookie's domain is + equal to HOST. If not, assume success on the grounds of the + cookie's chain having been found by find_chains_of_host. */ + if (cookie->domain_exact + && 0 != strcasecmp (host, cookie->domain)) + return false; + + pg = path_matches (path, cookie->path); + if (pg == 0) + return false; + + if (path_goodness) + /* If the caller requested path_goodness, we return it. This is + an optimization, so that the caller doesn't need to call + path_matches() again. */ + *path_goodness = pg; + return true; +} + +/* A structure that points to a cookie, along with the additional + information about the cookie's "goodness". This allows us to sort + the cookies when returning them to the server, as required by the + spec. */ + +struct weighed_cookie { + struct cookie *cookie; + int domain_goodness; + int path_goodness; +}; + +/* Comparator used for uniquifying the list. */ + +static int +equality_comparator (const void *p1, const void *p2) +{ + struct weighed_cookie *wc1 = (struct weighed_cookie *)p1; + struct weighed_cookie *wc2 = (struct weighed_cookie *)p2; + + int namecmp = strcmp (wc1->cookie->attr, wc2->cookie->attr); + int valuecmp = strcmp (wc1->cookie->value, wc2->cookie->value); + + /* We only really care whether both name and value are equal. We + return them in this order only for consistency... */ + return namecmp ? namecmp : valuecmp; +} + +/* Eliminate duplicate cookies. "Duplicate cookies" are any two + cookies with the same attr name and value. Whenever a duplicate + pair is found, one of the cookies is removed. */ + +static int +eliminate_dups (struct weighed_cookie *outgoing, int count) +{ + struct weighed_cookie *h; /* hare */ + struct weighed_cookie *t; /* tortoise */ + struct weighed_cookie *end = outgoing + count; + + /* We deploy a simple uniquify algorithm: first sort the array + according to our sort criteria, then copy it to itself, comparing + each cookie to its neighbor and ignoring the duplicates. */ + + qsort (outgoing, count, sizeof (struct weighed_cookie), equality_comparator); + + /* "Hare" runs through all the entries in the array, followed by + "tortoise". If a duplicate is found, the hare skips it. + Non-duplicate entries are copied to the tortoise ptr. */ + + for (h = t = outgoing; h < end; h++) + { + if (h != end - 1) + { + struct cookie *c0 = h[0].cookie; + struct cookie *c1 = h[1].cookie; + if (!strcmp (c0->attr, c1->attr) && !strcmp (c0->value, c1->value)) + continue; /* ignore the duplicate */ + } + + /* If the hare has advanced past the tortoise (because of + previous dups), make sure the values get copied. Otherwise, + no copying is necessary. */ + if (h != t) + *t++ = *h; + else + t++; + } + return t - outgoing; +} + +/* Comparator used for sorting by quality. */ + +static int +goodness_comparator (const void *p1, const void *p2) +{ + struct weighed_cookie *wc1 = (struct weighed_cookie *)p1; + struct weighed_cookie *wc2 = (struct weighed_cookie *)p2; + + /* Subtractions take `wc2' as the first argument becauase we want a + sort in *decreasing* order of goodness. */ + int dgdiff = wc2->domain_goodness - wc1->domain_goodness; + int pgdiff = wc2->path_goodness - wc1->path_goodness; + + /* Sort by domain goodness; if these are the same, sort by path + goodness. (The sorting order isn't really specified; maybe it + should be the other way around.) */ + return dgdiff ? dgdiff : pgdiff; +} + +/* Generate a `Cookie' header for a request that goes to HOST:PORT and + requests PATH from the server. The resulting string is allocated + with `malloc', and the caller is responsible for freeing it. If no + cookies pertain to this request, i.e. no cookie header should be + generated, NULL is returned. */ + +char * +cookie_header (struct cookie_jar *jar, const char *host, + int port, const char *path, bool secflag) +{ + struct cookie *chains[32]; + int chain_count; + + struct cookie *cookie; + struct weighed_cookie *outgoing; + size_t count, i, ocnt; + char *result = NULL; + int result_size, pos; + char pathbuf[1024]; + + /* First, find the cookie chains whose domains match HOST. */ + + /* Allocate room for find_chains_of_host to write to. The number of + chains can at most equal the number of subdomains, hence + 1+. We ignore cookies with more than 32 labels. */ + chain_count = 1 + count_char (host, '.'); + if (chain_count > (int) countof (chains)) + return NULL; + chain_count = find_chains_of_host (jar, host, chains); + + /* No cookies for this host. */ + if (chain_count <= 0) + return NULL; + + /* Wget's paths don't begin with '/' (blame rfc1808), but cookie + usage assumes /-prefixed paths. Until the rest of Wget is fixed, + simply prepend slash to PATH. */ + { + char *tmp; + size_t pathlen = strlen(path); + + if (pathlen < sizeof (pathbuf) - 1) + tmp = pathbuf; + else + tmp = xmalloc (pathlen + 2); + + *tmp = '/'; + memcpy (tmp + 1, path, pathlen + 1); + path = tmp; + } + + cookies_now = time (NULL); + + /* Now extract from the chains those cookies that match our host + (for domain_exact cookies), port (for cookies with port other + than PORT_ANY), etc. See matching_cookie for details. */ + + /* Count the number of matching cookies. */ + count = 0; + for (i = 0; i < (unsigned) chain_count; i++) + for (cookie = chains[i]; cookie; cookie = cookie->next) + if (cookie_matches_url (cookie, host, port, path, secflag, NULL)) + ++count; + if (!count) + goto out; /* no cookies matched */ + + /* Allocate the array. */ + if (count > SIZE_MAX / sizeof (struct weighed_cookie)) + goto out; /* unable to process so many cookies */ + outgoing = xmalloc (count * sizeof (struct weighed_cookie)); + + /* Fill the array with all the matching cookies from the chains that + match HOST. */ + ocnt = 0; + for (i = 0; i < (unsigned) chain_count; i++) + for (cookie = chains[i]; cookie; cookie = cookie->next) + { + int pg; + if (!cookie_matches_url (cookie, host, port, path, secflag, &pg)) + continue; + outgoing[ocnt].cookie = cookie; + outgoing[ocnt].domain_goodness = strlen (cookie->domain); + outgoing[ocnt].path_goodness = pg; + ++ocnt; + } + assert (ocnt == count); + + /* Eliminate duplicate cookies; that is, those whose name and value + are the same. */ + count = eliminate_dups (outgoing, count); + + /* Sort the array so that best-matching domains come first, and + that, within one domain, best-matching paths come first. */ + qsort (outgoing, count, sizeof (struct weighed_cookie), goodness_comparator); + + /* Count the space the name=value pairs will take. */ + result_size = 0; + for (i = 0; i < count; i++) + { + struct cookie *c = outgoing[i].cookie; + /* name=value */ + result_size += strlen (c->attr) + 1 + strlen (c->value); + } + + /* Allocate output buffer: + name=value pairs -- result_size + "; " separators -- (count - 1) * 2 + \0 terminator -- 1 */ + result_size = result_size + (count - 1) * 2 + 1; + result = xmalloc (result_size); + pos = 0; + for (i = 0; i < count; i++) + { + struct cookie *c = outgoing[i].cookie; + int namlen = strlen (c->attr); + int vallen = strlen (c->value); + + memcpy (result + pos, c->attr, namlen); + pos += namlen; + result[pos++] = '='; + memcpy (result + pos, c->value, vallen); + pos += vallen; + if (i < count - 1) + { + result[pos++] = ';'; + result[pos++] = ' '; + } + } + result[pos++] = '\0'; + xfree (outgoing); + assert (pos == result_size); + +out: + if (path != pathbuf) + xfree (path); + +return result; +} + +/* Support for loading and saving cookies. The format used for + loading and saving should be the format of the `cookies.txt' file + used by Netscape and Mozilla, at least the Unix versions. + (Apparently IE can export cookies in that format as well.) The + format goes like this: + + DOMAIN DOMAIN-FLAG PATH SECURE-FLAG TIMESTAMP ATTR-NAME ATTR-VALUE + + DOMAIN -- cookie domain, optionally followed by :PORT + DOMAIN-FLAG -- whether all hosts in the domain match + PATH -- cookie path + SECURE-FLAG -- whether cookie requires secure connection + TIMESTAMP -- expiry timestamp, number of seconds since epoch + ATTR-NAME -- name of the cookie attribute + ATTR-VALUE -- value of the cookie attribute (empty if absent) + + The fields are separated by TABs. All fields are mandatory, except + for ATTR-VALUE. The `-FLAG' fields are boolean, their legal values + being "TRUE" and "FALSE'. Empty lines, lines consisting of + whitespace only, and comment lines (beginning with # optionally + preceded by whitespace) are ignored. + + Example line from cookies.txt (split in two lines for readability): + + .google.com TRUE / FALSE 2147368447 \ + PREF ID=34bb47565bbcd47b:LD=en:NR=20:TM=985172580:LM=985739012 + +*/ + +/* If the region [B, E) ends with :, parse the number, return + it, and store new boundary (location of the `:') to DOMAIN_E_PTR. + If port is not specified, return 0. */ + +static int +domain_port (const char *domain_b, const char *domain_e, + const char **domain_e_ptr) +{ + int port = 0; + const char *p; + const char *colon = memchr (domain_b, ':', domain_e - domain_b); + if (!colon) + return 0; + for (p = colon + 1; p < domain_e && c_isdigit (*p); p++) + port = 10 * port + (*p - '0'); + if (p < domain_e) + /* Garbage following port number. */ + return 0; + *domain_e_ptr = colon; + return port; +} + +#define GET_WORD(p, b, e) do { \ + b = p; \ + while (*p && *p != '\t') \ + ++p; \ + e = p; \ + if (b == e || !*p) \ + goto next; \ + ++p; \ +} while (0) + +/* Load cookies from FILE. */ + +void +cookie_jar_load (struct cookie_jar *jar, const char *file) +{ + char *line = NULL; + size_t bufsize = 0; + + FILE *fp = fopen (file, "r"); + if (!fp) + { + logprintf (LOG_NOTQUIET, _("Cannot open cookies file %s: %s\n"), + quote (file), strerror (errno)); + return; + } + + cookies_now = time (NULL); + + while (getline (&line, &bufsize, fp) > 0) + { + struct cookie *cookie; + char *p = line; + + double expiry; + int port; + + char *domain_b = NULL, *domain_e = NULL; + char *domflag_b = NULL, *domflag_e = NULL; + char *path_b = NULL, *path_e = NULL; + char *secure_b = NULL, *secure_e = NULL; + char *expires_b = NULL, *expires_e = NULL; + char *name_b = NULL, *name_e = NULL; + char *value_b = NULL, *value_e = NULL; + + /* Skip leading white-space. */ + while (*p && c_isspace (*p)) + ++p; + /* Ignore empty lines. */ + if (!*p || *p == '#') + continue; + + GET_WORD (p, domain_b, domain_e); + GET_WORD (p, domflag_b, domflag_e); + GET_WORD (p, path_b, path_e); + GET_WORD (p, secure_b, secure_e); + GET_WORD (p, expires_b, expires_e); + GET_WORD (p, name_b, name_e); + + /* Don't use GET_WORD for value because it ends with newline, + not TAB. */ + value_b = p; + value_e = p + strlen (p); + if (value_e > value_b && value_e[-1] == '\n') + --value_e; + if (value_e > value_b && value_e[-1] == '\r') + --value_e; + /* Empty values are legal (I think), so don't bother checking. */ + + cookie = cookie_new (); + + cookie->attr = strdupdelim (name_b, name_e); + cookie->value = strdupdelim (value_b, value_e); + cookie->path = strdupdelim (path_b, path_e); + cookie->secure = BOUNDED_EQUAL (secure_b, secure_e, "TRUE"); + + /* Curl source says, quoting Andre Garcia: "flag: A TRUE/FALSE + value indicating if all machines within a given domain can + access the variable. This value is set automatically by the + browser, depending on the value set for the domain." */ + cookie->domain_exact = !BOUNDED_EQUAL (domflag_b, domflag_e, "TRUE"); + + /* DOMAIN needs special treatment because we might need to + extract the port. */ + port = domain_port (domain_b, domain_e, (const char **)&domain_e); + if (port) + cookie->port = port; + + if (*domain_b == '.') + ++domain_b; /* remove leading dot internally */ + cookie->domain = strdupdelim (domain_b, domain_e); + + /* safe default in case EXPIRES field is garbled. */ + expiry = (double)cookies_now - 1; + + /* I don't like changing the line, but it's safe here. (line is + malloced.) */ + *expires_e = '\0'; + sscanf (expires_b, "%lf", &expiry); + + if (expiry == 0) + { + /* EXPIRY can be 0 for session cookies saved because the + user specified `--keep-session-cookies' in the past. + They remain session cookies, and will be saved only if + the user has specified `keep-session-cookies' again. */ + } + else + { + if (expiry < cookies_now) + goto abort_cookie; /* ignore stale cookie. */ + cookie->expiry_time = (time_t) expiry; + cookie->permanent = 1; + } + + store_cookie (jar, cookie); + + next: + continue; + + abort_cookie: + delete_cookie (cookie); + } + + xfree(line); + fclose (fp); +} + +/* Save cookies, in format described above, to FILE. */ + +void +cookie_jar_save (struct cookie_jar *jar, const char *file) +{ + FILE *fp; + hash_table_iterator iter; + + DEBUGP (("Saving cookies to %s.\n", file)); + + cookies_now = time (NULL); + + fp = fopen (file, "w"); + if (!fp) + { + logprintf (LOG_NOTQUIET, _("Cannot open cookies file %s: %s\n"), + quote (file), strerror (errno)); + return; + } + + fputs ("# HTTP Cookie File\n", fp); + fprintf (fp, "# Generated by Wget on %s.\n", datetime_str (cookies_now)); + fputs ("# Edit at your own risk.\n\n", fp); + + for (hash_table_iterate (jar->chains, &iter); + hash_table_iter_next (&iter); + ) + { + const char *domain = iter.key; + struct cookie *cookie = iter.value; + for (; cookie; cookie = cookie->next) + { + if (!cookie->permanent && !opt.keep_session_cookies) + continue; + if (cookie_expired_p (cookie)) + continue; + if (!cookie->domain_exact) + fputc ('.', fp); + fputs (domain, fp); + if (cookie->port != PORT_ANY) + fprintf (fp, ":%d", cookie->port); + fprintf (fp, "\t%s\t%s\t%s\t%.0f\t%s\t%s\n", + cookie->domain_exact ? "FALSE" : "TRUE", + cookie->path, cookie->secure ? "TRUE" : "FALSE", + (double)cookie->expiry_time, + cookie->attr, cookie->value); + if (ferror (fp)) + goto out; + } + } + out: + if (ferror (fp)) + logprintf (LOG_NOTQUIET, _("Error writing to %s: %s\n"), + quote (file), strerror (errno)); + if (fclose (fp) < 0) + logprintf (LOG_NOTQUIET, _("Error closing %s: %s\n"), + quote (file), strerror (errno)); + + DEBUGP (("Done saving cookies.\n")); +} + +/* Clean up cookie-related data. */ + +void +cookie_jar_delete (struct cookie_jar *jar) +{ + /* Iterate over chains (indexed by domain) and free them. */ + hash_table_iterator iter; + for (hash_table_iterate (jar->chains, &iter); hash_table_iter_next (&iter); ) + { + struct cookie *chain = iter.value; + xfree (iter.key); + /* Then all cookies in this chain. */ + while (chain) + { + struct cookie *next = chain->next; + delete_cookie (chain); + chain = next; + } + } + hash_table_destroy (jar->chains); + xfree (jar); + +#ifdef HAVE_LIBPSL + psl_free (psl); + psl = NULL; +#endif +} + +/* Test cases. Currently this is only tests parse_set_cookies. To + use, recompile Wget with -DTEST_COOKIES and call test_cookies() + from main. */ + +#ifdef TEST_COOKIES +void +test_cookies (void) +{ + /* Tests expected to succeed: */ + static struct { + const char *data; + const char *results[10]; + } tests_succ[] = { + { "arg=value", {"arg", "value", NULL} }, + { "arg1=value1;arg2=value2", {"arg1", "value1", "arg2", "value2", NULL} }, + { "arg1=value1; arg2=value2", {"arg1", "value1", "arg2", "value2", NULL} }, + { "arg1=value1; arg2=value2;", {"arg1", "value1", "arg2", "value2", NULL} }, + { "arg1=value1; arg2=value2; ", {"arg1", "value1", "arg2", "value2", NULL} }, + { "arg1=\"value1\"; arg2=\"\"", {"arg1", "value1", "arg2", "", NULL} }, + { "arg=", {"arg", "", NULL} }, + { "arg1=; arg2=", {"arg1", "", "arg2", "", NULL} }, + { "arg1 = ; arg2= ", {"arg1", "", "arg2", "", NULL} }, + }; + + /* Tests expected to fail: */ + static char *tests_fail[] = { + ";", + "arg=\"unterminated", + "=empty-name", + "arg1=;=another-empty-name", + }; + int i; + + for (i = 0; i < countof (tests_succ); i++) + { + int ind; + const char *data = tests_succ[i].data; + const char **expected = tests_succ[i].results; + struct cookie *c; + + c = parse_set_cookie (data, true); + if (!c) + { + printf ("NULL cookie returned for valid data: %s\n", data); + continue; + } + + /* Test whether extract_param handles these cases correctly. */ + { + param_token name, value; + const char *ptr = data; + int j = 0; + while (extract_param (&ptr, &name, &value, ';', NULL)) + { + char *n = strdupdelim (name.b, name.e); + char *v = strdupdelim (value.b, value.e); + if (!expected[j]) + { + printf ("Too many parameters for '%s'\n", data); + break; + } + if (0 != strcmp (expected[j], n)) + printf ("Invalid name %d for '%s' (expected '%s', got '%s')\n", + j / 2 + 1, data, expected[j], n); + if (0 != strcmp (expected[j + 1], v)) + printf ("Invalid value %d for '%s' (expected '%s', got '%s')\n", + j / 2 + 1, data, expected[j + 1], v); + j += 2; + xfree (n); + xfree (v); + } + if (expected[j]) + printf ("Too few parameters for '%s'\n", data); + } + } + + for (i = 0; i < countof (tests_fail); i++) + { + struct cookie *c; + char *data = tests_fail[i]; + c = parse_set_cookie (data, true); + if (c) + printf ("Failed to report error on invalid data: %s\n", data); + } +} +#endif /* TEST_COOKIES */ diff --git a/src/cookies.h b/src/cookies.h new file mode 100644 index 0000000..903db32 --- /dev/null +++ b/src/cookies.h @@ -0,0 +1,47 @@ +/* Support for cookies. + Copyright (C) 2001-2011, 2015, 2018-2020 Free Software Foundation, + Inc. + +This file is part of GNU Wget. + +GNU Wget is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 3 of the License, or (at +your option) any later version. + +GNU Wget 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 Wget. If not, see . + +Additional permission under GNU GPL version 3 section 7 + +If you modify this program, or any covered work, by linking or +combining it with the OpenSSL project's OpenSSL library (or a +modified version of that library), containing parts covered by the +terms of the OpenSSL or SSLeay licenses, the Free Software Foundation +grants you additional permission to convey the resulting work. +Corresponding Source for a non-source form of such a combination +shall include the source code for the parts of OpenSSL used as well +as that of the covered work. */ + +#ifndef COOKIES_H +#define COOKIES_H + +struct cookie_jar; + +struct cookie_jar *cookie_jar_new (void); +void cookie_jar_delete (struct cookie_jar *); + +void cookie_handle_set_cookie (struct cookie_jar *, const char *, int, + const char *, const char *); +char *cookie_header (struct cookie_jar *, const char *, int, + const char *, bool); + +void cookie_jar_load (struct cookie_jar *, const char *); +void cookie_jar_save (struct cookie_jar *, const char *); + +#endif /* COOKIES_H */ diff --git a/src/css-tokens.h b/src/css-tokens.h new file mode 100644 index 0000000..40307ff --- /dev/null +++ b/src/css-tokens.h @@ -0,0 +1,65 @@ +/* Declarations for css.lex + Copyright (C) 2006, 2009-2011, 2015, 2018-2020 Free Software + Foundation, Inc. + +This file is part of GNU Wget. + +GNU Wget is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 3 of the License, or (at +your option) any later version. + +GNU Wget 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 Wget. If not, see . + +Additional permission under GNU GPL version 3 section 7 + +If you modify this program, or any covered work, by linking or +combining it with the OpenSSL project's OpenSSL library (or a +modified version of that library), containing parts covered by the +terms of the OpenSSL or SSLeay licenses, the Free Software Foundation +grants you additional permission to convey the resulting work. +Corresponding Source for a non-source form of such a combination +shall include the source code for the parts of OpenSSL used as well +as that of the covered work. */ + +#ifndef CSS_TOKENS_H +#define CSS_TOKENS_H + +enum { + CSSEOF = 0, + S = 1, + CDO = 2, + CDC = 3, + INCLUDES = 4, + DASHMATCH = 5, + STRING = 6, + BAD_STRING = 7, + IDENT = 8, + HASH = 9, + IMPORT_SYM = 10, + PAGE_SYM = 11, + MEDIA_SYM = 12, + CHARSET_SYM = 13, + IMPORTANT_SYM = 14, + EMS = 15, + EXS = 16, + LENGTH = 17, + ANGLE = 18, + TIME = 19, + FREQ = 20, + DIMENSION = 21, + PERCENTAGE = 22, + NUMBER = 23, + URI = 24, + BAD_URI = 25, + FUNCTION = 26, + COMMENT = 27 +}; + +#endif /* CSS_TOKENS_H */ diff --git a/src/css-url.c b/src/css-url.c new file mode 100644 index 0000000..eacd926 --- /dev/null +++ b/src/css-url.c @@ -0,0 +1,236 @@ +/* Collect URLs from CSS source. + Copyright (C) 1998, 2000-2003, 2009-2011, 2014-2015, 2018-2020 Free + Software Foundation, Inc. + +This file is part of GNU Wget. + +GNU Wget is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 3 of the License, or (at +your option) any later version. + +GNU Wget 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 Wget. If not, see . + +Additional permission under GNU GPL version 3 section 7 + +If you modify this program, or any covered work, by linking or +combining it with the OpenSSL project's OpenSSL library (or a +modified version of that library), containing parts covered by the +terms of the OpenSSL or SSLeay licenses, the Free Software Foundation +grants you additional permission to convey the resulting work. +Corresponding Source for a non-source form of such a combination +shall include the source code for the parts of OpenSSL used as well +as that of the covered work. */ + +/* + Note that this is not an actual CSS parser, but just a lexical + scanner with a tiny bit more smarts bolted on top. A full parser + is somewhat overkill for this job. The only things we're interested + in are @import rules and url() tokens, so it's easy enough to + grab those without truly understanding the input. The only downside + to this is that we might be coerced into downloading files that + a browser would ignore. That might merit some more investigation. + */ + +#include + +#include +#include +#include +#include +#include + +#include "wget.h" +#include "utils.h" +#include "convert.h" +#include "html-url.h" +#include "css-tokens.h" +#include "css-url.h" +#include "xstrndup.h" + +/* from lex.yy.c */ +extern char *yytext; +extern int yyleng; +typedef struct yy_buffer_state *YY_BUFFER_STATE; +extern YY_BUFFER_STATE yy_scan_bytes (const char *bytes,int len ); +extern void yy_delete_buffer (YY_BUFFER_STATE b); +extern int yylex (void); +extern void yylex_destroy(void); + +/* + Given a detected URI token, get only the URI specified within. + Also adjust the starting position and length of the string. + + A URI can be specified with or without quotes, and the quotes + can be single or double quotes. In addition there can be + whitespace after the opening parenthesis and before the closing + parenthesis. +*/ +static char * +get_uri_string (const char *at, int *pos, int *length) +{ + if (*length < 4) + return NULL; + + if (0 != strncasecmp (at + *pos, "url(", 4)) + return NULL; + + *pos += 4; + *length -= 5; /* url() */ + + /* skip leading space */ + while (*length > 0 && isspace (at[*pos])) + { + (*pos)++; + if (--(*length) == 0) + return NULL; + } + + /* skip trailing space */ + while (*length > 0 && isspace (at[*pos + *length - 1])) + { + (*length)--; + } + + /* trim off quotes */ + if (*length >= 2 && (at[*pos] == '\'' || at[*pos] == '"')) + { + (*pos)++; + *length -= 2; + } + + if (*length <= 0) + return NULL; + + return xstrndup (at + *pos, *length); +} + +void +get_urls_css (struct map_context *ctx, int offset, int buf_length) +{ + int token; + /*char tmp[2048];*/ + int buffer_pos = 0; + int pos, length; + char *uri; + YY_BUFFER_STATE b; + + /* tell flex to scan from this buffer */ + b = yy_scan_bytes (ctx->text + offset, buf_length); + + while((token = yylex()) != CSSEOF) + { + /*DEBUGP (("%s ", token_names[token]));*/ + /* @import "foo.css" + or @import url(foo.css) + */ + if(token == IMPORT_SYM) + { + do { + buffer_pos += yyleng; + } while((token = yylex()) == S); + + /*DEBUGP (("%s ", token_names[token]));*/ + + if (token == STRING || token == URI) + { + /*DEBUGP (("Got URI "));*/ + pos = buffer_pos + offset; + length = yyleng; + + if (token == URI) + { + uri = get_uri_string (ctx->text, &pos, &length); + } + else if (length >= 2) + { + /* cut out quote characters */ + pos++; + length -= 2; + uri = xmalloc (length + 1); + memcpy (uri, yytext + 1, length); + uri[length] = '\0'; + } + else + uri = NULL; + + if (uri) + { + struct urlpos *up = append_url (uri, pos, length, ctx); + DEBUGP (("Found @import: [%s] at %d [%s]\n", yytext, buffer_pos, uri)); + + if (up) + { + up->link_inline_p = 1; + up->link_css_p = 1; + up->link_expect_css = 1; + } + + xfree(uri); + } + } + } + /* background-image: url(foo.png) + note that we don't care what + property this is actually on. + */ + else if(token == URI) + { + pos = buffer_pos + offset; + length = yyleng; + uri = get_uri_string (ctx->text, &pos, &length); + + if (uri) + { + struct urlpos *up = append_url (uri, pos, length, ctx); + DEBUGP (("Found URI: [%s] at %d [%s]\n", yytext, buffer_pos, uri)); + if (up) + { + up->link_inline_p = 1; + up->link_css_p = 1; + } + + xfree (uri); + } + } + buffer_pos += yyleng; + } + + yy_delete_buffer(b); + yylex_destroy(); + + DEBUGP (("\n")); +} + +struct urlpos * +get_urls_css_file (const char *file, const char *url) +{ + struct file_memory *fm; + struct map_context ctx; + + /* Load the file. */ + fm = wget_read_file (file); + if (!fm) + { + logprintf (LOG_NOTQUIET, "%s: %s\n", file, strerror (errno)); + return NULL; + } + DEBUGP (("Loaded %s (size %s).\n", file, number_to_static_string (fm->length))); + + ctx.text = fm->content; + ctx.head = NULL; + ctx.base = NULL; + ctx.parent_base = url ? url : opt.base_href; + ctx.document_file = file; + ctx.nofollow = 0; + + get_urls_css (&ctx, 0, fm->length); + wget_read_file_free (fm); + return ctx.head; +} diff --git a/src/css-url.h b/src/css-url.h new file mode 100644 index 0000000..e8d7d1f --- /dev/null +++ b/src/css-url.h @@ -0,0 +1,37 @@ +/* Declarations for css-url.c. + Copyright (C) 2006, 2009-2011, 2015, 2018-2020 Free Software + Foundation, Inc. + +This file is part of GNU Wget. + +GNU Wget is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 3 of the License, or (at +your option) any later version. + +GNU Wget 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 Wget. If not, see . + +Additional permission under GNU GPL version 3 section 7 + +If you modify this program, or any covered work, by linking or +combining it with the OpenSSL project's OpenSSL library (or a +modified version of that library), containing parts covered by the +terms of the OpenSSL or SSLeay licenses, the Free Software Foundation +grants you additional permission to convey the resulting work. +Corresponding Source for a non-source form of such a combination +shall include the source code for the parts of OpenSSL used as well +as that of the covered work. */ + +#ifndef CSS_URL_H +#define CSS_URL_H + +void get_urls_css (struct map_context *, int, int); +struct urlpos *get_urls_css_file (const char *, const char *); + +#endif /* CSS_URL_H */ diff --git a/src/css.c b/src/css.c new file mode 100644 index 0000000..7f51801 --- /dev/null +++ b/src/css.c @@ -0,0 +1,3932 @@ +#line 1 "css.c" +/* config.h must precede flex's inclusion of + in order for its _GNU_SOURCE definition to take effect. */ +#include + +#line 6 "css.c" + +#define YY_INT_ALIGNED short int + +/* A lexical scanner generated by flex */ + +#define FLEX_SCANNER +#define YY_FLEX_MAJOR_VERSION 2 +#define YY_FLEX_MINOR_VERSION 6 +#define YY_FLEX_SUBMINOR_VERSION 4 +#if YY_FLEX_SUBMINOR_VERSION > 0 +#define FLEX_BETA +#endif + +/* First, we deal with platform-specific or compiler-specific issues. */ + +/* begin standard C headers. */ +#include +#include +#include +#include + +/* end standard C headers. */ + +/* flex integer type definitions */ + +#ifndef FLEXINT_H +#define FLEXINT_H + +/* C99 systems have . Non-C99 systems may or may not. */ + +#if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L + +/* C99 says to define __STDC_LIMIT_MACROS before including stdint.h, + * if you want the limit (max/min) macros for int types. + */ +#ifndef __STDC_LIMIT_MACROS +#define __STDC_LIMIT_MACROS 1 +#endif + +#include +typedef int8_t flex_int8_t; +typedef uint8_t flex_uint8_t; +typedef int16_t flex_int16_t; +typedef uint16_t flex_uint16_t; +typedef int32_t flex_int32_t; +typedef uint32_t flex_uint32_t; +#else +typedef signed char flex_int8_t; +typedef short int flex_int16_t; +typedef int flex_int32_t; +typedef unsigned char flex_uint8_t; +typedef unsigned short int flex_uint16_t; +typedef unsigned int flex_uint32_t; + +/* Limits of integral types. */ +#ifndef INT8_MIN +#define INT8_MIN (-128) +#endif +#ifndef INT16_MIN +#define INT16_MIN (-32767-1) +#endif +#ifndef INT32_MIN +#define INT32_MIN (-2147483647-1) +#endif +#ifndef INT8_MAX +#define INT8_MAX (127) +#endif +#ifndef INT16_MAX +#define INT16_MAX (32767) +#endif +#ifndef INT32_MAX +#define INT32_MAX (2147483647) +#endif +#ifndef UINT8_MAX +#define UINT8_MAX (255U) +#endif +#ifndef UINT16_MAX +#define UINT16_MAX (65535U) +#endif +#ifndef UINT32_MAX +#define UINT32_MAX (4294967295U) +#endif + +#ifndef SIZE_MAX +#define SIZE_MAX (~(size_t)0) +#endif + +#endif /* ! C99 */ + +#endif /* ! FLEXINT_H */ + +/* begin standard C++ headers. */ + +/* TODO: this is always defined, so inline it */ +#define yyconst const + +#if defined(__GNUC__) && __GNUC__ >= 3 +#define yynoreturn __attribute__((__noreturn__)) +#else +#define yynoreturn +#endif + +/* Returned upon end-of-file. */ +#define YY_NULL 0 + +/* Promotes a possibly negative, possibly signed char to an + * integer in range [0..255] for use as an array index. + */ +#define YY_SC_TO_UI(c) ((YY_CHAR) (c)) + +/* Enter a start condition. This macro really ought to take a parameter, + * but we do it the disgusting crufty way forced on us by the ()-less + * definition of BEGIN. + */ +#define BEGIN (yy_start) = 1 + 2 * +/* Translate the current start state into a value that can be later handed + * to BEGIN to return to the state. The YYSTATE alias is for lex + * compatibility. + */ +#define YY_START (((yy_start) - 1) / 2) +#define YYSTATE YY_START +/* Action number for EOF rule of a given start state. */ +#define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1) +/* Special action meaning "start processing a new file". */ +#define YY_NEW_FILE yyrestart( yyin ) +#define YY_END_OF_BUFFER_CHAR 0 + +/* Size of default input buffer. */ +#ifndef YY_BUF_SIZE +#ifdef __ia64__ +/* On IA-64, the buffer size is 16k, not 8k. + * Moreover, YY_BUF_SIZE is 2*YY_READ_BUF_SIZE in the general case. + * Ditto for the __ia64__ case accordingly. + */ +#define YY_BUF_SIZE 32768 +#else +#define YY_BUF_SIZE 16384 +#endif /* __ia64__ */ +#endif + +/* The state buf must be large enough to hold one state per character in the main buffer. + */ +#define YY_STATE_BUF_SIZE ((YY_BUF_SIZE + 2) * sizeof(yy_state_type)) + +#ifndef YY_TYPEDEF_YY_BUFFER_STATE +#define YY_TYPEDEF_YY_BUFFER_STATE +typedef struct yy_buffer_state *YY_BUFFER_STATE; +#endif + +#ifndef YY_TYPEDEF_YY_SIZE_T +#define YY_TYPEDEF_YY_SIZE_T +typedef size_t yy_size_t; +#endif + +extern int yyleng; + +extern FILE *yyin, *yyout; + +#define EOB_ACT_CONTINUE_SCAN 0 +#define EOB_ACT_END_OF_FILE 1 +#define EOB_ACT_LAST_MATCH 2 + + #define YY_LESS_LINENO(n) + #define YY_LINENO_REWIND_TO(ptr) + +/* Return all but the first "n" matched characters back to the input stream. */ +#define yyless(n) \ + do \ + { \ + /* Undo effects of setting up yytext. */ \ + int yyless_macro_arg = (n); \ + YY_LESS_LINENO(yyless_macro_arg);\ + *yy_cp = (yy_hold_char); \ + YY_RESTORE_YY_MORE_OFFSET \ + (yy_c_buf_p) = yy_cp = yy_bp + yyless_macro_arg - YY_MORE_ADJ; \ + YY_DO_BEFORE_ACTION; /* set up yytext again */ \ + } \ + while ( 0 ) +#define unput(c) yyunput( c, (yytext_ptr) ) + +#ifndef YY_STRUCT_YY_BUFFER_STATE +#define YY_STRUCT_YY_BUFFER_STATE +struct yy_buffer_state + { + FILE *yy_input_file; + + char *yy_ch_buf; /* input buffer */ + char *yy_buf_pos; /* current position in input buffer */ + + /* Size of input buffer in bytes, not including room for EOB + * characters. + */ + int yy_buf_size; + + /* Number of characters read into yy_ch_buf, not including EOB + * characters. + */ + int yy_n_chars; + + /* Whether we "own" the buffer - i.e., we know we created it, + * and can realloc() it to grow it, and should free() it to + * delete it. + */ + int yy_is_our_buffer; + + /* Whether this is an "interactive" input source; if so, and + * if we're using stdio for input, then we want to use getc() + * instead of fread(), to make sure we stop fetching input after + * each newline. + */ + int yy_is_interactive; + + /* Whether we're considered to be at the beginning of a line. + * If so, '^' rules will be active on the next match, otherwise + * not. + */ + int yy_at_bol; + + int yy_bs_lineno; /**< The line count. */ + int yy_bs_column; /**< The column count. */ + + /* Whether to try to fill the input buffer when we reach the + * end of it. + */ + int yy_fill_buffer; + + int yy_buffer_status; + +#define YY_BUFFER_NEW 0 +#define YY_BUFFER_NORMAL 1 + /* When an EOF's been seen but there's still some text to process + * then we mark the buffer as YY_EOF_PENDING, to indicate that we + * shouldn't try reading from the input source any more. We might + * still have a bunch of tokens to match, though, because of + * possible backing-up. + * + * When we actually see the EOF, we change the status to "new" + * (via yyrestart()), so that the user can continue scanning by + * just pointing yyin at a new input file. + */ +#define YY_BUFFER_EOF_PENDING 2 + + }; +#endif /* !YY_STRUCT_YY_BUFFER_STATE */ + +/* Stack of input buffers. */ +static size_t yy_buffer_stack_top = 0; /**< index of top of stack. */ +static size_t yy_buffer_stack_max = 0; /**< capacity of stack. */ +static YY_BUFFER_STATE * yy_buffer_stack = NULL; /**< Stack as an array. */ + +/* We provide macros for accessing buffer states in case in the + * future we want to put the buffer states in a more general + * "scanner state". + * + * Returns the top of the stack, or NULL. + */ +#define YY_CURRENT_BUFFER ( (yy_buffer_stack) \ + ? (yy_buffer_stack)[(yy_buffer_stack_top)] \ + : NULL) +/* Same as previous macro, but useful when we know that the buffer stack is not + * NULL or when we need an lvalue. For internal use only. + */ +#define YY_CURRENT_BUFFER_LVALUE (yy_buffer_stack)[(yy_buffer_stack_top)] + +/* yy_hold_char holds the character lost when yytext is formed. */ +static char yy_hold_char; +static int yy_n_chars; /* number of characters read into yy_ch_buf */ +int yyleng; + +/* Points to current character in buffer. */ +static char *yy_c_buf_p = NULL; +static int yy_init = 0; /* whether we need to initialize */ +static int yy_start = 0; /* start state number */ + +/* Flag which is used to allow yywrap()'s to do buffer switches + * instead of setting up a fresh yyin. A bit of a hack ... + */ +static int yy_did_buffer_switch_on_eof; + +void yyrestart ( FILE *input_file ); +void yy_switch_to_buffer ( YY_BUFFER_STATE new_buffer ); +YY_BUFFER_STATE yy_create_buffer ( FILE *file, int size ); +void yy_delete_buffer ( YY_BUFFER_STATE b ); +void yy_flush_buffer ( YY_BUFFER_STATE b ); +void yypush_buffer_state ( YY_BUFFER_STATE new_buffer ); +void yypop_buffer_state ( void ); + +static void yyensure_buffer_stack ( void ); +static void yy_load_buffer_state ( void ); +static void yy_init_buffer ( YY_BUFFER_STATE b, FILE *file ); +#define YY_FLUSH_BUFFER yy_flush_buffer( YY_CURRENT_BUFFER ) + +YY_BUFFER_STATE yy_scan_buffer ( char *base, yy_size_t size ); +YY_BUFFER_STATE yy_scan_string ( const char *yy_str ); +YY_BUFFER_STATE yy_scan_bytes ( const char *bytes, int len ); + +void *yyalloc ( yy_size_t ); +void *yyrealloc ( void *, yy_size_t ); +void yyfree ( void * ); + +#define yy_new_buffer yy_create_buffer +#define yy_set_interactive(is_interactive) \ + { \ + if ( ! YY_CURRENT_BUFFER ){ \ + yyensure_buffer_stack (); \ + YY_CURRENT_BUFFER_LVALUE = \ + yy_create_buffer( yyin, YY_BUF_SIZE ); \ + } \ + YY_CURRENT_BUFFER_LVALUE->yy_is_interactive = is_interactive; \ + } +#define yy_set_bol(at_bol) \ + { \ + if ( ! YY_CURRENT_BUFFER ){\ + yyensure_buffer_stack (); \ + YY_CURRENT_BUFFER_LVALUE = \ + yy_create_buffer( yyin, YY_BUF_SIZE ); \ + } \ + YY_CURRENT_BUFFER_LVALUE->yy_at_bol = at_bol; \ + } +#define YY_AT_BOL() (YY_CURRENT_BUFFER_LVALUE->yy_at_bol) + +/* Begin user sect3 */ + +#define yywrap() (/*CONSTCOND*/1) +#define YY_SKIP_YYWRAP +typedef flex_uint8_t YY_CHAR; + +FILE *yyin = NULL, *yyout = NULL; + +typedef int yy_state_type; + +extern int yylineno; +int yylineno = 1; + +extern char *yytext; +#ifdef yytext_ptr +#undef yytext_ptr +#endif +#define yytext_ptr yytext + +static yy_state_type yy_get_previous_state ( void ); +static yy_state_type yy_try_NUL_trans ( yy_state_type current_state ); +static int yy_get_next_buffer ( void ); +static void yynoreturn yy_fatal_error ( const char* msg ); + +/* Done after the current pattern has been matched and before the + * corresponding action - sets up yytext. + */ +#define YY_DO_BEFORE_ACTION \ + (yytext_ptr) = yy_bp; \ + yyleng = (int) (yy_cp - yy_bp); \ + (yy_hold_char) = *yy_cp; \ + *yy_cp = '\0'; \ + (yy_c_buf_p) = yy_cp; +#define YY_NUM_RULES 41 +#define YY_END_OF_BUFFER 42 +/* This struct is not used in this scanner, + but its presence is necessary. */ +struct yy_trans_info + { + flex_int32_t yy_verify; + flex_int32_t yy_nxt; + }; +static const flex_int16_t yy_accept[1103] = + { 0, + 0, 0, 42, 40, 1, 1, 40, 10, 40, 10, + 40, 40, 40, 35, 40, 40, 11, 11, 40, 40, + 40, 1, 0, 0, 0, 0, 10, 9, 10, 12, + 0, 0, 10, 10, 0, 11, 0, 35, 4, 34, + 0, 0, 35, 33, 33, 33, 33, 33, 33, 33, + 33, 33, 33, 33, 30, 0, 0, 0, 0, 0, + 0, 0, 39, 11, 0, 11, 11, 11, 8, 7, + 0, 0, 0, 0, 0, 0, 0, 10, 10, 10, + 0, 12, 12, 10, 10, 10, 6, 4, 4, 0, + 33, 0, 21, 0, 33, 0, 18, 19, 0, 33, + + 0, 31, 0, 23, 0, 33, 0, 22, 29, 0, + 25, 24, 20, 0, 33, 0, 33, 33, 33, 33, + 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, + 30, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 11, 11, 11, + 11, 11, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 10, 10, 10, 0, 0, 12, 12, 10, + 10, 10, 4, 2, 33, 33, 33, 33, 33, 21, + 26, 0, 33, 33, 33, 33, 33, 33, 33, 33, + 18, 19, 33, 0, 33, 33, 33, 33, 33, 33, + + 33, 31, 33, 33, 33, 23, 32, 0, 33, 33, + 33, 33, 33, 33, 33, 33, 33, 22, 29, 33, + 33, 33, 33, 33, 24, 20, 27, 0, 33, 33, + 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, + 33, 33, 33, 33, 33, 33, 33, 33, 30, 33, + 33, 5, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 11, 11, 38, 11, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 10, 0, 3, 12, 10, 4, 4, 33, + + 33, 33, 33, 33, 21, 21, 33, 33, 33, 26, + 33, 33, 33, 33, 33, 33, 33, 33, 33, 18, + 19, 18, 28, 0, 33, 33, 33, 33, 33, 33, + 33, 33, 33, 33, 31, 31, 33, 33, 33, 23, + 23, 33, 33, 33, 32, 33, 33, 33, 33, 33, + 33, 33, 33, 33, 22, 29, 22, 33, 33, 33, + 33, 33, 25, 24, 20, 33, 33, 33, 33, 33, + 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, + 33, 33, 33, 33, 33, 33, 33, 33, 30, 33, + 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, + + 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, + 25, 33, 33, 33, 30, 30, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 14, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 11, 38, + 38, 38, 38, 37, 0, 11, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 10, 0, 0, 12, 10, 33, 33, 33, 33, 21, + 21, 21, 21, 33, 33, 33, 26, 33, 33, 33, + 33, 33, 33, 33, 33, 33, 33, 33, 18, 19, + + 18, 18, 18, 19, 19, 33, 33, 33, 33, 33, + 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, + 33, 33, 31, 31, 31, 31, 33, 33, 33, 23, + 23, 23, 23, 33, 33, 33, 32, 32, 33, 33, + 33, 33, 33, 33, 33, 33, 33, 33, 33, 22, + 29, 22, 22, 22, 29, 29, 33, 33, 33, 33, + 33, 25, 24, 20, 25, 25, 24, 24, 20, 20, + 33, 33, 33, 27, 33, 33, 33, 33, 33, 33, + 27, 33, 33, 33, 33, 33, 33, 33, 33, 33, + 33, 33, 33, 33, 33, 33, 33, 30, 33, 33, + + 33, 25, 33, 27, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 11, 38, 38, 38, + 38, 38, 38, 38, 38, 0, 38, 37, 38, 38, + 11, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 10, 12, 10, 33, 33, 33, + 33, 21, 21, 33, 33, 33, 26, 26, 26, 33, + 33, 33, 33, 33, 33, 33, 33, 33, 18, 19, + 18, 33, 33, 33, 28, 33, 33, 33, 33, 33, + + 33, 28, 33, 33, 33, 33, 33, 28, 33, 33, + 33, 31, 31, 33, 33, 33, 23, 23, 33, 33, + 33, 32, 32, 32, 32, 33, 33, 33, 33, 33, + 33, 33, 33, 33, 22, 29, 22, 33, 33, 33, + 33, 33, 25, 24, 20, 33, 33, 33, 27, 27, + 27, 33, 33, 33, 33, 27, 33, 33, 33, 33, + 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, + 33, 30, 33, 33, 33, 25, 33, 27, 0, 13, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + + 0, 0, 14, 0, 0, 0, 0, 11, 38, 36, + 38, 38, 38, 38, 38, 38, 38, 38, 38, 0, + 38, 38, 37, 38, 0, 11, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 10, 12, + 10, 33, 33, 33, 21, 21, 33, 33, 33, 26, + 33, 33, 33, 33, 33, 33, 33, 18, 19, 18, + 33, 33, 33, 28, 28, 28, 33, 33, 33, 33, + 33, 33, 33, 33, 28, 33, 33, 31, 31, 33, + 33, 23, 23, 33, 33, 33, 32, 32, 33, 33, + 33, 33, 33, 33, 33, 22, 29, 22, 33, 33, + + 33, 33, 25, 24, 20, 33, 33, 33, 27, 33, + 33, 33, 27, 33, 33, 33, 33, 33, 33, 33, + 33, 33, 33, 33, 30, 33, 33, 33, 25, 33, + 27, 0, 0, 0, 0, 13, 0, 0, 0, 0, + 0, 0, 0, 15, 0, 0, 0, 0, 0, 14, + 14, 0, 11, 38, 38, 38, 38, 38, 38, 38, + 0, 0, 38, 38, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 33, 21, 21, 33, 33, + 26, 33, 18, 19, 18, 33, 33, 33, 28, 33, + 33, 33, 33, 33, 28, 31, 31, 23, 23, 33, + + 33, 32, 32, 33, 22, 29, 22, 25, 24, 20, + 33, 33, 27, 33, 27, 16, 0, 13, 0, 0, + 0, 0, 0, 15, 15, 0, 0, 38, 38, 38, + 0, 0, 0, 0, 38, 17, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 26, 33, 33, + 28, 33, 32, 32, 27, 0, 13, 13, 0, 0, + 38, 38, 38, 0, 0, 38, 0, 0, 0, 17, + 0, 0, 0, 0, 0, 0, 0, 28, 0, 38, + 38, 38, 0, 38, 0, 17, 0, 0, 0, 0, + 38, 38, 0, 38, 0, 17, 17, 0, 0, 0, + + 0, 0 + } ; + +static const YY_CHAR yy_ec[256] = + { 0, + 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, + 1, 4, 5, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 6, 7, 8, 9, 10, 11, 10, 12, 13, + 14, 15, 10, 10, 16, 17, 18, 19, 20, 21, + 22, 23, 24, 25, 26, 27, 28, 10, 10, 29, + 30, 31, 10, 32, 33, 34, 35, 36, 37, 38, + 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, + 42, 49, 50, 51, 52, 42, 42, 53, 42, 54, + 10, 55, 10, 10, 42, 10, 56, 57, 58, 59, + + 60, 61, 62, 63, 64, 42, 65, 66, 67, 68, + 69, 70, 42, 71, 72, 73, 74, 42, 42, 75, + 42, 76, 10, 77, 10, 78, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 79, + 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, + 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, + 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, + 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, + + 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, + 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, + 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, + 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, + 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, + 79, 79, 79, 79, 79 + } ; + +static const YY_CHAR yy_meta[80] = + { 0, + 1, 2, 3, 3, 3, 2, 2, 4, 2, 2, + 2, 4, 5, 2, 2, 6, 2, 7, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 2, 2, + 2, 2, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 2, 2, 9 + } ; + +static const flex_int16_t yy_base[1137] = + { 0, + 0, 0, 4195, 7110, 78, 83, 88, 87, 78, 85, + 82, 88, 4161, 142, 4151, 90, 86, 206, 259, 4118, + 4083, 98, 234, 4083, 72, 109, 116, 7110, 318, 100, + 4082, 361, 208, 420, 4017, 92, 463, 205, 4024, 7110, + 3977, 222, 0, 3974, 209, 89, 257, 202, 180, 245, + 248, 259, 355, 272, 3955, 524, 3987, 83, 280, 311, + 274, 585, 7110, 117, 637, 348, 210, 697, 7110, 7110, + 3963, 302, 382, 243, 3940, 3933, 371, 251, 356, 757, + 3945, 101, 817, 246, 357, 877, 7110, 3938, 252, 920, + 3894, 974, 3886, 1017, 397, 447, 3861, 3860, 661, 376, + + 904, 3850, 721, 3841, 448, 451, 1040, 3840, 3825, 1045, + 3813, 3796, 3787, 1063, 569, 600, 3784, 1137, 484, 1180, + 613, 1221, 748, 380, 566, 347, 591, 907, 654, 462, + 3767, 3789, 118, 559, 779, 633, 593, 588, 628, 782, + 654, 3776, 775, 3775, 802, 772, 682, 336, 1279, 345, + 447, 1322, 3754, 254, 695, 837, 658, 581, 632, 656, + 806, 1012, 456, 862, 1365, 3744, 256, 903, 1408, 278, + 964, 1451, 3730, 7110, 3689, 1511, 839, 751, 790, 3655, + 3633, 1086, 865, 3648, 3645, 868, 812, 3627, 850, 3599, + 3559, 3554, 895, 897, 344, 3587, 3580, 885, 900, 892, + + 922, 3526, 1001, 929, 943, 3484, 3483, 1165, 1002, 3500, + 3499, 1037, 1074, 945, 3485, 969, 3476, 3439, 3424, 1096, + 3450, 410, 3442, 438, 3403, 3397, 3396, 1109, 1104, 3416, + 3396, 745, 1554, 1126, 1597, 1199, 1638, 1237, 1696, 1591, + 1451, 1224, 1636, 1495, 1673, 1680, 1762, 1836, 1318, 1740, + 1703, 7110, 573, 1049, 1161, 1158, 970, 987, 1131, 1017, + 1192, 1245, 3385, 3371, 1046, 1269, 1252, 3369, 3358, 1342, + 1600, 1403, 1552, 1788, 1263, 1891, 1796, 1934, 3362, 1868, + 1238, 1307, 1248, 3350, 3304, 1055, 1352, 1779, 1931, 1391, + 1392, 1393, 1983, 3284, 7110, 2026, 2069, 3253, 347, 892, + + 2112, 1392, 1108, 1110, 1248, 1488, 1500, 3239, 3204, 3174, + 1541, 3194, 3177, 2112, 1624, 1119, 3145, 1176, 3142, 1861, + 1873, 1878, 3104, 1704, 1607, 3071, 2999, 1394, 2951, 2939, + 1979, 1503, 1180, 1209, 1896, 1901, 1669, 1259, 1273, 1936, + 1971, 1707, 1278, 1296, 2904, 1691, 2927, 2900, 2022, 1731, + 1336, 2867, 1403, 2856, 1994, 2027, 2063, 1753, 2851, 716, + 2848, 950, 2068, 2106, 2117, 1786, 2836, 2831, 1793, 2833, + 2795, 2150, 2191, 1807, 2234, 2138, 2275, 2156, 2333, 2228, + 2237, 2273, 2344, 2358, 2367, 2378, 2449, 2523, 2189, 2433, + 2413, 1498, 2121, 2020, 2269, 2451, 1769, 2278, 1797, 2271, + + 1426, 1684, 1625, 2322, 1465, 2311, 2342, 2464, 2148, 2457, + 2261, 1528, 2388, 2423, 2759, 1179, 1347, 2149, 2296, 2245, + 2683, 2676, 1875, 1831, 2535, 2548, 1910, 2480, 2177, 2645, + 2637, 2383, 2555, 7110, 2446, 2468, 2600, 2595, 2508, 2546, + 2570, 2561, 2456, 2552, 2533, 2540, 1981, 2561, 2614, 2651, + 2674, 741, 457, 7110, 2729, 2807, 2597, 661, 2134, 2596, + 2579, 1548, 1591, 2330, 2405, 2814, 2604, 1589, 2641, 97, + 2882, 2584, 771, 2942, 3003, 3046, 2605, 1637, 1675, 2688, + 2695, 2537, 1235, 2639, 2556, 2555, 2710, 2662, 2543, 2538, + 2819, 1925, 2402, 2684, 1849, 2508, 1979, 2507, 2715, 2720, + + 2844, 2463, 1448, 2462, 1598, 2832, 2475, 2463, 2837, 2420, + 2412, 2894, 2582, 2374, 2365, 3042, 2023, 2628, 2816, 2853, + 2025, 2109, 2889, 2919, 2312, 1614, 2857, 2229, 2270, 2929, + 3047, 2262, 1615, 2931, 2423, 2439, 3052, 3083, 3071, 2289, + 2269, 3106, 2300, 2407, 3094, 2461, 2233, 2530, 2232, 3119, + 3124, 3129, 2191, 1714, 2183, 1734, 3117, 2186, 1033, 2175, + 1110, 3142, 3147, 3152, 2135, 1803, 2132, 2181, 2103, 2338, + 3076, 2090, 2077, 3160, 3148, 2035, 2003, 3172, 3132, 3134, + 0, 3213, 1864, 3230, 3173, 3254, 3181, 3312, 3378, 3437, + 3511, 3581, 3656, 3723, 3785, 3859, 3933, 3219, 3988, 4050, + + 3236, 2813, 3269, 2888, 2606, 2901, 3277, 3160, 2608, 2666, + 3251, 3162, 3338, 3190, 2881, 3264, 7110, 3191, 3285, 1994, + 1985, 2987, 3302, 3350, 3326, 3303, 3358, 3340, 1965, 1964, + 3341, 3369, 3367, 3038, 3373, 3009, 4107, 3394, 1039, 3416, + 4166, 696, 4225, 3442, 3463, 3481, 3497, 3517, 4285, 4346, + 4407, 3059, 3408, 3193, 1957, 1942, 3295, 3430, 3539, 3544, + 3283, 2258, 3485, 311, 4467, 4510, 4553, 4596, 590, 2669, + 3080, 3327, 3553, 3451, 1920, 1919, 3559, 1876, 2372, 805, + 1897, 1896, 3572, 3260, 3261, 1801, 3311, 1794, 3565, 3614, + 3619, 3505, 1764, 1751, 3626, 3572, 1712, 1704, 3635, 3537, + + 3597, 0, 842, 1683, 1668, 3640, 3543, 0, 962, 3354, + 3355, 3645, 3661, 1143, 3420, 3436, 3672, 3681, 3673, 3477, + 3547, 3701, 3710, 1613, 2478, 1302, 1608, 1607, 3716, 3707, + 3553, 1605, 3554, 1537, 3732, 3737, 3748, 3732, 1529, 1796, + 1502, 1830, 3762, 3770, 3777, 3774, 1498, 1459, 3798, 1394, + 3135, 1339, 1384, 1374, 3811, 0, 4639, 3784, 1740, 3822, + 2122, 3822, 3869, 3895, 3916, 3941, 3970, 3978, 3995, 4699, + 4002, 3880, 4083, 4105, 3722, 0, 3634, 0, 1410, 7110, + 3904, 3810, 1349, 1342, 3782, 3868, 4066, 4635, 3883, 3654, + 3856, 1427, 3908, 1333, 1308, 3944, 4176, 3996, 3768, 3982, + + 1575, 4001, 4071, 4011, 3853, 4024, 1763, 4756, 4088, 7110, + 1487, 3423, 4816, 896, 3208, 4876, 4262, 4444, 4919, 4504, + 4547, 4591, 4677, 4979, 5040, 5101, 3896, 4040, 4023, 1274, + 1266, 3798, 4080, 4509, 4041, 4065, 4639, 1821, 4709, 5144, + 5187, 5230, 3632, 3726, 4208, 4213, 2076, 1260, 1207, 4231, + 1176, 1123, 4793, 3760, 1108, 3762, 1099, 4236, 4322, 4327, + 4093, 1043, 1038, 4332, 994, 3434, 2212, 1028, 1002, 4913, + 992, 951, 4552, 3833, 0, 3946, 3953, 4474, 4479, 4041, + 4059, 4645, 4716, 2284, 4091, 4106, 4721, 4733, 929, 840, + 4919, 4115, 838, 4116, 837, 4738, 4743, 4756, 811, 2240, + + 777, 3157, 4763, 4798, 4803, 2371, 745, 718, 4823, 658, + 646, 5138, 0, 4956, 5225, 5181, 5269, 5279, 5291, 5296, + 5303, 5315, 5386, 5143, 5350, 5369, 5375, 5394, 5408, 5448, + 5413, 642, 4130, 618, 583, 7110, 4253, 5467, 4134, 4243, + 5276, 2587, 4250, 4854, 4277, 4128, 4675, 2903, 4432, 7110, + 526, 2948, 4859, 1544, 4963, 5522, 1357, 3705, 5565, 5608, + 5472, 5669, 5477, 5730, 4466, 5171, 4581, 508, 493, 4435, + 5496, 4865, 4634, 5275, 3053, 5506, 5511, 5565, 478, 449, + 4864, 5767, 5602, 5607, 5772, 3203, 451, 445, 4924, 443, + 442, 5777, 5790, 5795, 5805, 5812, 5835, 5853, 5859, 4140, + + 4164, 4984, 5017, 5866, 5871, 5876, 5881, 5889, 5894, 5899, + 411, 381, 5022, 5907, 5913, 7110, 4866, 5027, 5214, 4678, + 5521, 3400, 4944, 7110, 370, 3468, 3483, 5950, 5993, 6036, + 5987, 6030, 6096, 0, 6139, 7110, 5502, 5131, 4161, 4218, + 4832, 5304, 6035, 5313, 4441, 5307, 3527, 5992, 344, 285, + 5490, 6133, 6073, 6138, 6176, 5382, 7110, 296, 3629, 3675, + 6213, 6256, 6299, 6199, 6342, 6385, 5403, 237, 230, 7110, + 5415, 6212, 6255, 5439, 3976, 5380, 3852, 6293, 3928, 6428, + 6471, 6514, 6557, 6600, 5441, 5531, 5500, 5100, 5886, 4057, + 6643, 6686, 6729, 5612, 5628, 7110, 133, 4058, 6772, 4181, + + 6336, 7110, 6833, 6837, 6846, 6850, 6855, 6864, 6873, 6882, + 6891, 6900, 112, 6904, 6913, 6922, 6931, 6940, 6949, 6958, + 6967, 6976, 6984, 6993, 7002, 7011, 7020, 7029, 7038, 7047, + 7056, 7065, 7074, 7083, 7092, 7100 + } ; + +static const flex_int16_t yy_def[1137] = + { 0, + 1102, 1, 1102, 1102, 1102, 1102, 1102, 1103, 1104, 1105, + 1106, 1102, 1102, 1102, 1102, 1102, 1107, 1107, 1108, 1102, + 1102, 1102, 1102, 1102, 1102, 1102, 1103, 1102, 1109, 1104, + 1102, 1110, 1105, 1111, 1102, 1107, 1108, 14, 1112, 1102, + 1113, 1102, 14, 1114, 1114, 1114, 1114, 1114, 1114, 1114, + 1114, 1114, 1114, 1114, 1114, 1102, 1102, 1102, 1102, 1102, + 1102, 1102, 1102, 1107, 1115, 1107, 1107, 1107, 1102, 1102, + 1116, 1102, 1102, 1102, 1102, 1102, 1102, 1103, 1103, 1103, + 1117, 1104, 1104, 1105, 1105, 1105, 1102, 1112, 1118, 56, + 1114, 1119, 1114, 1119, 1114, 94, 1114, 1114, 94, 1114, + + 94, 1114, 94, 1114, 94, 1114, 94, 1114, 1114, 94, + 1114, 1114, 1114, 94, 1114, 94, 1114, 1114, 118, 118, + 118, 118, 118, 1114, 1114, 1114, 1114, 1114, 1114, 1114, + 1114, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, + 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1107, 68, 1107, + 1107, 68, 1116, 1120, 1102, 1102, 1102, 1102, 1102, 1102, + 1102, 1102, 1103, 1103, 80, 1117, 1121, 1104, 83, 1105, + 1105, 86, 1122, 1102, 1114, 118, 176, 176, 176, 1114, + 1114, 94, 176, 176, 176, 176, 176, 176, 176, 176, + 1114, 1114, 1114, 94, 176, 176, 176, 1114, 176, 176, + + 176, 1114, 176, 176, 176, 1114, 1114, 94, 176, 176, + 176, 1114, 176, 176, 176, 176, 176, 1114, 1114, 176, + 176, 176, 176, 176, 1114, 1114, 1114, 94, 176, 176, + 176, 1114, 118, 233, 233, 233, 233, 233, 233, 239, + 239, 239, 239, 239, 239, 239, 239, 233, 248, 248, + 239, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, + 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, + 1102, 1102, 1102, 1102, 1107, 68, 1123, 68, 1124, 1102, + 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, + 1102, 1102, 80, 1125, 1102, 83, 86, 1122, 1126, 1114, + + 176, 301, 301, 301, 301, 301, 176, 176, 176, 1114, + 301, 301, 301, 301, 301, 301, 301, 301, 301, 301, + 301, 301, 1114, 94, 176, 176, 176, 301, 301, 301, + 301, 301, 301, 301, 301, 301, 301, 301, 301, 301, + 301, 176, 176, 176, 1114, 301, 301, 301, 301, 301, + 301, 301, 301, 301, 301, 301, 301, 301, 301, 301, + 301, 301, 301, 301, 301, 176, 176, 176, 301, 301, + 301, 301, 233, 373, 373, 373, 373, 373, 373, 379, + 379, 379, 379, 379, 379, 379, 379, 373, 388, 388, + 379, 1114, 1114, 1114, 1114, 373, 1114, 1114, 1114, 1114, + + 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, + 373, 1114, 1114, 373, 1114, 1114, 1102, 1102, 1102, 1102, + 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, + 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, + 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 276, 1123, + 1123, 1127, 1128, 1102, 1102, 276, 1129, 1130, 1102, 1102, + 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, + 1131, 1132, 1133, 1102, 86, 301, 476, 476, 476, 476, + 476, 1114, 1114, 301, 301, 301, 301, 476, 476, 476, + 476, 1114, 1114, 476, 476, 476, 476, 476, 476, 476, + + 476, 1114, 1114, 1114, 1114, 176, 176, 176, 301, 301, + 301, 301, 476, 476, 476, 476, 1114, 1114, 476, 476, + 476, 476, 476, 476, 1114, 1114, 476, 476, 476, 476, + 476, 1114, 1114, 301, 301, 301, 301, 301, 476, 476, + 476, 476, 1114, 1114, 476, 476, 476, 476, 476, 476, + 476, 476, 1114, 1114, 1114, 1114, 476, 476, 476, 476, + 476, 476, 476, 476, 1114, 1114, 1114, 1114, 1114, 1114, + 301, 301, 301, 301, 476, 476, 476, 476, 1114, 1114, + 476, 373, 582, 582, 582, 582, 582, 582, 582, 582, + 582, 582, 582, 582, 590, 590, 582, 582, 582, 590, + + 582, 582, 582, 582, 1102, 1102, 1102, 1102, 1102, 1102, + 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, + 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, + 1102, 1102, 1102, 1102, 1102, 1102, 276, 1102, 1127, 1102, + 1134, 1128, 1135, 1123, 1123, 1102, 1123, 1123, 1123, 1102, + 456, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, + 1102, 1102, 1102, 1102, 1131, 474, 475, 476, 668, 668, + 668, 668, 668, 476, 476, 476, 476, 1114, 1114, 668, + 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, + 668, 301, 301, 301, 301, 476, 476, 476, 476, 1114, + + 1114, 476, 668, 668, 668, 668, 668, 668, 668, 668, + 668, 668, 668, 668, 668, 668, 668, 668, 476, 476, + 476, 476, 476, 1114, 1114, 668, 668, 668, 668, 668, + 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, + 668, 668, 668, 668, 668, 476, 476, 476, 476, 1114, + 1114, 668, 668, 668, 668, 668, 582, 757, 757, 757, + 757, 757, 757, 757, 757, 757, 757, 757, 757, 757, + 757, 757, 757, 757, 757, 757, 757, 757, 1102, 1102, + 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, + 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, + + 1102, 1102, 1102, 1102, 1102, 1102, 1102, 276, 1102, 1102, + 1127, 1127, 1127, 1128, 1128, 1128, 1123, 1123, 649, 1136, + 1136, 1123, 1136, 649, 1102, 651, 1102, 1102, 1102, 1102, + 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1131, 474, + 475, 668, 842, 842, 842, 842, 668, 668, 668, 668, + 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, + 476, 476, 476, 476, 1114, 1114, 668, 668, 668, 668, + 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, + 842, 842, 842, 668, 668, 668, 668, 668, 842, 842, + 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, + + 842, 842, 842, 842, 842, 668, 668, 668, 668, 842, + 842, 842, 842, 1114, 1114, 1114, 1114, 1114, 1114, 1114, + 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, + 1114, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, + 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, + 1102, 1102, 826, 1127, 1127, 813, 1128, 1128, 816, 649, + 1136, 1102, 1136, 824, 1102, 1102, 1102, 1102, 1102, 1102, + 1102, 1102, 1102, 1102, 1102, 1114, 1114, 1114, 842, 842, + 842, 1114, 1114, 1114, 1114, 668, 668, 668, 668, 842, + 842, 842, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 842, + + 842, 842, 842, 1114, 1114, 1114, 1114, 1114, 1114, 1114, + 842, 842, 842, 1114, 1114, 1102, 1102, 1102, 1102, 1102, + 1102, 1102, 1102, 1102, 1102, 1102, 1102, 813, 816, 649, + 1136, 1136, 1136, 962, 824, 1102, 1102, 1102, 1102, 1102, + 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1114, 842, 842, + 842, 1114, 1114, 1114, 1114, 1102, 1102, 1102, 1102, 1102, + 813, 816, 649, 1136, 1033, 824, 1102, 1102, 1102, 1102, + 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1114, 1102, 813, + 816, 649, 1033, 824, 1102, 1102, 1102, 1102, 1102, 1102, + 813, 816, 1033, 1082, 1102, 1102, 1102, 1102, 1033, 1102, + + 1136, 0, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, + 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, + 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, + 1102, 1102, 1102, 1102, 1102, 1102 + } ; + +static const flex_int16_t yy_nxt[7190] = + { 0, + 4, 5, 6, 5, 5, 5, 7, 8, 9, 4, + 4, 10, 4, 4, 4, 11, 12, 13, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 15, 4, + 4, 16, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 18, 17, 17, 19, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 18, 17, 17, 20, 21, 17, 22, + 22, 22, 22, 22, 22, 22, 22, 22, 22, 23, + 23, 23, 23, 23, 28, 31, 28, 35, 63, 22, + + 22, 22, 22, 22, 63, 24, 38, 38, 38, 38, + 38, 38, 38, 38, 38, 38, 72, 1102, 1102, 75, + 44, 76, 133, 28, 58, 95, 73, 74, 25, 63, + 59, 75, 32, 76, 60, 1096, 37, 61, 72, 34, + 65, 29, 26, 96, 62, 133, 65, 58, 95, 77, + 253, 25, 40, 59, 32, 32, 60, 41, 42, 61, + 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, + 29, 65, 77, 253, 44, 44, 45, 46, 47, 44, + 48, 49, 50, 44, 51, 44, 52, 44, 44, 53, + 54, 55, 44, 44, 44, 44, 56, 44, 44, 45, + + 46, 47, 44, 48, 49, 50, 51, 44, 52, 44, + 44, 53, 54, 55, 44, 44, 44, 44, 63, 28, + 44, 1102, 63, 38, 38, 38, 38, 38, 38, 38, + 38, 38, 38, 102, 103, 23, 23, 23, 23, 23, + 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, + 100, 24, 1086, 93, 66, 102, 101, 28, 28, 1086, + 65, 161, 34, 94, 65, 75, 89, 76, 154, 174, + 167, 280, 100, 295, 25, 93, 66, 68, 68, 68, + 68, 68, 68, 68, 68, 68, 68, 106, 26, 28, + 104, 68, 68, 68, 68, 68, 68, 25, 1057, 105, + + 34, 97, 107, 108, 115, 29, 138, 1078, 109, 98, + 106, 99, 104, 110, 68, 68, 68, 68, 68, 68, + 27, 27, 79, 97, 134, 108, 116, 115, 139, 138, + 109, 98, 34, 158, 135, 159, 80, 80, 80, 80, + 80, 80, 80, 80, 80, 80, 134, 136, 63, 155, + 80, 80, 80, 80, 80, 80, 156, 277, 27, 33, + 63, 299, 328, 28, 174, 137, 1078, 329, 28, 330, + 136, 155, 1024, 80, 80, 80, 80, 80, 80, 83, + 83, 83, 83, 83, 83, 83, 83, 83, 83, 111, + 65, 150, 104, 83, 83, 83, 83, 83, 83, 65, + + 157, 105, 65, 1055, 158, 112, 159, 113, 193, 114, + 29, 34, 111, 150, 104, 72, 83, 83, 83, 83, + 83, 83, 33, 33, 85, 73, 160, 112, 100, 113, + 194, 193, 364, 1055, 101, 181, 365, 72, 86, 86, + 86, 86, 86, 86, 86, 86, 86, 86, 160, 67, + 100, 182, 86, 86, 86, 86, 86, 86, 181, 63, + 364, 1052, 1052, 28, 365, 183, 203, 1051, 640, 184, + 204, 185, 205, 1051, 1048, 86, 86, 86, 86, 86, + 86, 68, 68, 68, 68, 68, 68, 68, 68, 68, + 68, 175, 175, 206, 115, 68, 68, 68, 68, 68, + + 68, 65, 234, 1048, 207, 208, 234, 234, 234, 234, + 29, 643, 1043, 175, 175, 206, 116, 115, 68, 68, + 68, 68, 68, 68, 117, 117, 207, 1043, 950, 117, + 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, + 117, 117, 118, 119, 119, 119, 120, 121, 122, 123, + 119, 119, 117, 117, 117, 117, 119, 119, 119, 119, + 119, 119, 124, 125, 126, 117, 127, 117, 128, 117, + 117, 129, 130, 131, 117, 117, 117, 117, 117, 119, + 119, 119, 119, 119, 119, 124, 125, 126, 127, 117, + 128, 117, 117, 129, 130, 131, 117, 117, 117, 117, + + 117, 117, 117, 140, 227, 1018, 254, 141, 142, 143, + 144, 262, 843, 255, 844, 263, 288, 264, 229, 102, + 103, 417, 230, 228, 231, 145, 265, 227, 254, 146, + 106, 247, 147, 248, 249, 234, 234, 234, 234, 288, + 1018, 102, 266, 417, 175, 107, 267, 1016, 145, 265, + 268, 146, 269, 106, 147, 149, 149, 149, 149, 149, + 149, 149, 149, 149, 149, 1014, 175, 289, 260, 149, + 149, 149, 149, 149, 149, 458, 287, 1014, 280, 186, + 158, 271, 159, 187, 188, 189, 190, 261, 111, 272, + 289, 260, 149, 149, 149, 149, 149, 149, 67, 67, + + 67, 151, 67, 155, 112, 191, 113, 640, 114, 63, + 156, 111, 272, 192, 138, 152, 152, 152, 152, 152, + 152, 152, 152, 152, 152, 155, 112, 191, 113, 152, + 152, 152, 152, 152, 152, 192, 139, 138, 563, 199, + 1013, 281, 564, 176, 200, 176, 201, 117, 640, 282, + 643, 65, 152, 152, 152, 152, 152, 152, 163, 78, + 78, 164, 163, 281, 28, 175, 247, 1013, 248, 249, + 234, 234, 234, 234, 202, 165, 165, 165, 165, 165, + 165, 165, 165, 165, 165, 473, 305, 175, 295, 165, + 165, 165, 165, 165, 165, 641, 202, 256, 1008, 92, + + 270, 257, 271, 258, 141, 142, 143, 144, 136, 305, + 274, 29, 165, 165, 165, 165, 165, 165, 82, 82, + 82, 168, 82, 259, 290, 306, 137, 851, 75, 852, + 76, 136, 1008, 274, 1102, 169, 169, 169, 169, 169, + 169, 169, 169, 169, 169, 259, 134, 320, 306, 169, + 169, 169, 169, 169, 169, 283, 135, 302, 1006, 1006, + 284, 303, 285, 304, 78, 871, 1004, 872, 134, 28, + 320, 32, 169, 169, 169, 169, 169, 169, 170, 84, + 84, 171, 170, 311, 286, 322, 315, 312, 28, 313, + 316, 317, 318, 319, 175, 172, 172, 172, 172, 172, + + 172, 172, 172, 172, 172, 82, 286, 640, 322, 172, + 172, 172, 172, 172, 172, 325, 29, 193, 332, 326, + 1102, 327, 195, 333, 335, 334, 176, 196, 176, 197, + 323, 34, 172, 172, 172, 172, 172, 172, 119, 194, + 193, 175, 119, 119, 119, 119, 92, 335, 175, 324, + 643, 108, 198, 323, 336, 1004, 109, 32, 117, 117, + 117, 110, 117, 175, 117, 340, 84, 117, 117, 117, + 175, 993, 563, 108, 198, 28, 564, 336, 109, 341, + 355, 117, 117, 117, 117, 876, 117, 877, 340, 117, + 117, 117, 176, 176, 176, 176, 176, 176, 176, 176, + + 176, 176, 341, 355, 357, 425, 176, 176, 176, 176, + 176, 176, 993, 291, 291, 291, 292, 291, 34, 337, + 346, 992, 426, 338, 347, 339, 348, 357, 425, 176, + 176, 176, 176, 176, 176, 177, 176, 176, 176, 178, + 176, 179, 176, 176, 176, 426, 640, 992, 92, 176, + 176, 176, 176, 176, 176, 744, 72, 427, 209, 745, + 989, 180, 210, 213, 211, 989, 73, 214, 215, 216, + 217, 428, 176, 176, 176, 176, 176, 176, 72, 212, + 427, 220, 434, 180, 175, 221, 222, 223, 224, 218, + 207, 208, 350, 641, 219, 418, 351, 352, 353, 354, + + 435, 281, 212, 419, 307, 434, 175, 175, 308, 282, + 309, 218, 207, 225, 358, 226, 219, 418, 359, 360, + 361, 362, 369, 281, 310, 984, 370, 366, 371, 175, + 175, 367, 744, 368, 984, 225, 745, 226, 117, 117, + 117, 232, 117, 480, 374, 481, 982, 310, 374, 374, + 374, 374, 175, 175, 499, 233, 234, 234, 234, 235, + 236, 237, 238, 234, 234, 880, 480, 881, 481, 234, + 234, 234, 234, 234, 234, 175, 424, 499, 254, 420, + 257, 415, 258, 342, 421, 255, 422, 176, 343, 176, + 344, 92, 234, 234, 234, 234, 234, 234, 234, 982, + + 254, 239, 240, 241, 234, 242, 243, 244, 423, 175, + 429, 501, 523, 245, 430, 246, 431, 387, 345, 388, + 389, 374, 374, 374, 374, 399, 399, 399, 400, 399, + 423, 175, 981, 92, 501, 523, 245, 482, 246, 234, + 345, 524, 239, 240, 241, 234, 242, 243, 244, 482, + 482, 482, 483, 482, 250, 387, 251, 388, 389, 374, + 374, 374, 374, 432, 524, 148, 465, 263, 91, 264, + 440, 284, 100, 285, 268, 63, 269, 250, 101, 251, + 148, 148, 148, 275, 148, 981, 459, 436, 971, 92, + 91, 437, 460, 438, 100, 530, 971, 276, 276, 276, + + 276, 276, 276, 276, 276, 276, 276, 439, 459, 531, + 537, 276, 276, 276, 276, 276, 276, 65, 530, 415, + 415, 415, 416, 415, 889, 461, 890, 944, 538, 462, + 439, 463, 531, 537, 276, 276, 276, 276, 276, 276, + 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, + 374, 538, 944, 464, 278, 278, 278, 278, 278, 278, + 442, 910, 938, 911, 141, 142, 143, 144, 640, 938, + 467, 550, 92, 374, 158, 464, 159, 278, 278, 278, + 278, 278, 278, 293, 293, 293, 293, 293, 293, 293, + 293, 293, 293, 912, 550, 291, 605, 293, 293, 293, + + 293, 293, 293, 912, 445, 445, 445, 446, 445, 470, + 477, 643, 513, 75, 478, 76, 479, 514, 605, 515, + 293, 293, 293, 293, 293, 293, 296, 296, 296, 296, + 296, 296, 296, 296, 296, 296, 72, 72, 552, 136, + 296, 296, 296, 296, 296, 296, 73, 73, 92, 257, + 502, 258, 397, 397, 397, 398, 397, 137, 72, 72, + 932, 552, 136, 296, 296, 296, 296, 296, 296, 297, + 297, 297, 297, 297, 297, 297, 297, 297, 297, 102, + 103, 909, 932, 297, 297, 297, 297, 297, 297, 482, + 482, 482, 483, 482, 640, 97, 403, 403, 403, 404, + + 403, 102, 92, 98, 106, 99, 297, 297, 297, 297, + 297, 297, 175, 175, 175, 300, 175, 97, 484, 107, + 909, 520, 485, 903, 486, 98, 521, 106, 522, 301, + 301, 301, 301, 301, 301, 301, 301, 301, 301, 91, + 104, 641, 93, 301, 301, 301, 301, 301, 301, 105, + 903, 640, 94, 447, 447, 447, 448, 447, 897, 488, + 115, 91, 104, 489, 93, 490, 301, 301, 301, 301, + 301, 301, 373, 374, 374, 374, 375, 376, 377, 378, + 374, 374, 116, 115, 138, 659, 374, 374, 374, 374, + 374, 374, 394, 394, 394, 395, 394, 263, 641, 264, + + 504, 443, 443, 443, 444, 443, 139, 138, 659, 374, + 374, 374, 374, 374, 374, 374, 525, 532, 379, 380, + 381, 374, 382, 383, 384, 509, 897, 396, 660, 510, + 385, 511, 386, 891, 891, 91, 155, 401, 401, 401, + 402, 401, 494, 156, 134, 96, 495, 496, 497, 498, + 396, 660, 92, 385, 135, 386, 374, 91, 155, 379, + 380, 381, 374, 382, 383, 384, 134, 92, 92, 92, + 104, 390, 672, 391, 405, 405, 405, 406, 405, 105, + 91, 407, 407, 407, 408, 407, 401, 527, 873, 102, + 103, 528, 104, 529, 390, 672, 391, 392, 392, 392, + + 393, 392, 91, 873, 407, 407, 407, 408, 407, 539, + 673, 102, 106, 540, 374, 541, 553, 91, 374, 374, + 374, 374, 506, 870, 108, 534, 507, 107, 508, 109, + 535, 870, 536, 673, 110, 106, 555, 102, 103, 91, + 93, 405, 405, 405, 406, 405, 108, 108, 175, 545, + 94, 109, 109, 546, 547, 548, 549, 110, 923, 102, + 924, 925, 93, 409, 409, 409, 410, 409, 92, 108, + 175, 557, 374, 864, 109, 558, 559, 560, 561, 106, + 468, 468, 468, 469, 468, 268, 864, 269, 92, 445, + 445, 445, 446, 445, 107, 374, 411, 450, 450, 450, + + 450, 450, 106, 452, 571, 565, 91, 453, 572, 454, + 573, 575, 112, 97, 113, 576, 114, 577, 904, 411, + 859, 98, 905, 99, 136, 583, 155, 859, 91, 583, + 583, 583, 583, 156, 112, 97, 113, 412, 412, 412, + 413, 412, 137, 98, 284, 100, 285, 136, 155, 614, + 455, 101, 904, 257, 374, 258, 905, 92, 374, 374, + 374, 374, 502, 502, 502, 503, 502, 100, 414, 23, + 23, 23, 23, 23, 504, 504, 504, 505, 504, 502, + 502, 502, 503, 502, 689, 24, 757, 757, 757, 757, + 116, 414, 148, 148, 148, 275, 148, 525, 525, 525, + + 526, 525, 525, 525, 525, 526, 525, 689, 25, 449, + 449, 449, 449, 449, 449, 449, 449, 449, 449, 853, + 853, 418, 26, 449, 449, 449, 449, 449, 449, 419, + 92, 25, 468, 468, 468, 469, 468, 532, 532, 532, + 533, 532, 617, 418, 850, 850, 449, 449, 449, 449, + 449, 449, 456, 456, 456, 456, 456, 456, 456, 456, + 456, 456, 834, 181, 618, 617, 456, 456, 456, 456, + 456, 456, 532, 532, 532, 533, 532, 834, 155, 182, + 517, 517, 517, 518, 517, 156, 181, 803, 803, 456, + 456, 456, 456, 456, 456, 553, 553, 553, 554, 553, + + 155, 471, 471, 471, 471, 471, 471, 471, 471, 471, + 471, 519, 797, 138, 691, 471, 471, 471, 471, 471, + 471, 797, 755, 543, 543, 543, 544, 543, 555, 555, + 555, 556, 555, 194, 519, 139, 138, 691, 471, 471, + 471, 471, 471, 471, 474, 474, 474, 474, 474, 474, + 474, 474, 474, 474, 755, 193, 95, 712, 474, 474, + 474, 474, 474, 474, 553, 553, 553, 554, 553, 565, + 565, 565, 566, 565, 96, 207, 208, 194, 193, 95, + 712, 474, 474, 474, 474, 474, 474, 475, 475, 475, + 475, 475, 475, 475, 475, 475, 475, 207, 979, 749, + + 980, 475, 475, 475, 475, 475, 475, 567, 567, 567, + 568, 567, 749, 492, 492, 492, 493, 492, 569, 569, + 569, 570, 569, 392, 475, 475, 475, 475, 475, 475, + 476, 476, 476, 476, 476, 476, 476, 476, 476, 476, + 923, 713, 924, 925, 476, 476, 476, 476, 476, 476, + 181, 579, 579, 579, 580, 579, 596, 92, 597, 598, + 583, 583, 583, 583, 713, 93, 182, 476, 476, 476, + 476, 476, 476, 181, 596, 94, 597, 598, 583, 583, + 583, 583, 111, 567, 652, 581, 92, 93, 653, 92, + 415, 415, 415, 416, 415, 623, 743, 606, 112, 430, + + 113, 431, 114, 607, 228, 111, 652, 743, 581, 582, + 583, 583, 583, 584, 585, 586, 587, 583, 583, 606, + 112, 583, 113, 583, 583, 583, 583, 583, 583, 394, + 394, 394, 395, 394, 990, 92, 991, 92, 397, 397, + 397, 398, 397, 92, 583, 92, 583, 583, 583, 583, + 583, 583, 583, 736, 736, 588, 589, 590, 583, 591, + 592, 593, 1009, 612, 601, 717, 1010, 594, 421, 595, + 422, 394, 91, 399, 399, 399, 399, 400, 399, 583, + 397, 97, 96, 583, 583, 583, 583, 601, 717, 98, + 594, 99, 595, 583, 91, 729, 588, 589, 590, 583, + + 591, 592, 593, 97, 281, 95, 718, 1000, 599, 1001, + 600, 98, 282, 405, 608, 729, 92, 91, 609, 100, + 610, 100, 97, 96, 403, 101, 281, 101, 95, 718, + 98, 599, 99, 600, 392, 392, 392, 393, 392, 91, + 569, 100, 611, 100, 97, 401, 401, 401, 402, 401, + 106, 583, 98, 207, 208, 583, 583, 583, 583, 403, + 403, 403, 404, 403, 611, 107, 92, 104, 405, 405, + 405, 406, 405, 106, 678, 207, 105, 93, 459, 407, + 407, 407, 408, 407, 460, 706, 108, 94, 91, 104, + 412, 109, 92, 1011, 706, 1012, 110, 102, 103, 93, + + 459, 625, 91, 104, 492, 263, 106, 264, 108, 543, + 91, 91, 105, 109, 407, 407, 407, 408, 407, 102, + 115, 107, 108, 661, 91, 104, 92, 109, 284, 106, + 285, 699, 110, 91, 405, 405, 405, 406, 405, 699, + 181, 583, 116, 115, 108, 583, 583, 583, 583, 109, + 409, 409, 409, 410, 409, 722, 182, 108, 604, 409, + 207, 208, 109, 181, 628, 583, 407, 110, 629, 583, + 630, 723, 106, 583, 583, 583, 583, 228, 722, 108, + 724, 604, 207, 602, 109, 695, 631, 107, 583, 181, + 437, 111, 438, 91, 723, 106, 735, 695, 619, 112, + + 134, 113, 620, 114, 621, 182, 602, 112, 108, 113, + 135, 114, 181, 109, 111, 91, 92, 92, 110, 735, + 622, 112, 134, 113, 412, 412, 412, 413, 412, 112, + 108, 113, 92, 690, 690, 109, 615, 615, 615, 616, + 615, 583, 445, 622, 434, 583, 583, 583, 583, 615, + 615, 615, 616, 615, 443, 603, 626, 626, 626, 627, + 626, 683, 435, 447, 633, 737, 683, 434, 268, 136, + 269, 634, 634, 634, 635, 634, 136, 116, 603, 636, + 677, 677, 254, 141, 142, 143, 144, 137, 737, 255, + 260, 92, 136, 138, 137, 254, 134, 658, 473, 136, + + 703, 462, 255, 463, 254, 704, 135, 705, 265, 261, + 421, 458, 422, 260, 654, 139, 138, 254, 134, 655, + 632, 656, 664, 669, 266, 632, 158, 670, 159, 671, + 517, 265, 637, 637, 637, 637, 637, 637, 637, 637, + 637, 637, 779, 468, 657, 787, 637, 637, 637, 637, + 637, 637, 450, 450, 450, 450, 450, 674, 452, 624, + 193, 675, 453, 676, 454, 779, 657, 624, 787, 637, + 637, 637, 637, 637, 637, 638, 638, 638, 638, 638, + 680, 1102, 194, 193, 681, 1102, 682, 454, 155, 482, + 482, 482, 483, 482, 613, 156, 482, 482, 482, 483, + + 482, 613, 684, 788, 845, 455, 685, 686, 687, 688, + 155, 678, 678, 678, 679, 678, 502, 502, 502, 503, + 502, 504, 504, 504, 505, 504, 788, 845, 455, 644, + 645, 646, 646, 646, 645, 647, 644, 647, 647, 647, + 644, 644, 648, 647, 647, 647, 647, 649, 649, 649, + 649, 649, 649, 649, 649, 649, 649, 647, 647, 647, + 647, 649, 649, 649, 649, 649, 649, 647, 647, 647, + 647, 647, 647, 647, 647, 647, 647, 647, 647, 647, + 647, 647, 647, 650, 649, 649, 649, 649, 649, 649, + 647, 647, 647, 647, 647, 647, 647, 647, 647, 647, + + 647, 647, 647, 647, 647, 647, 647, 647, 67, 67, + 67, 151, 67, 92, 578, 662, 662, 662, 663, 662, + 492, 492, 492, 493, 492, 651, 651, 651, 651, 651, + 651, 651, 651, 651, 651, 757, 757, 757, 757, 651, + 651, 651, 651, 651, 651, 502, 502, 502, 503, 502, + 692, 708, 578, 574, 693, 696, 694, 181, 574, 697, + 281, 698, 651, 651, 651, 651, 651, 651, 282, 562, + 324, 709, 562, 182, 708, 714, 710, 551, 711, 715, + 181, 716, 281, 163, 78, 78, 164, 163, 551, 28, + 525, 525, 525, 526, 525, 700, 700, 700, 701, 700, + + 665, 665, 665, 665, 665, 665, 665, 665, 665, 665, + 757, 757, 757, 757, 665, 665, 665, 665, 665, 665, + 525, 525, 525, 526, 525, 430, 542, 431, 254, 702, + 532, 532, 532, 533, 532, 255, 29, 665, 665, 665, + 665, 665, 665, 82, 82, 82, 168, 82, 324, 719, + 254, 780, 702, 542, 720, 781, 721, 30, 92, 516, + 666, 666, 666, 666, 666, 666, 666, 666, 666, 666, + 437, 516, 438, 780, 666, 666, 666, 666, 666, 666, + 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 32, 666, 666, 666, + + 666, 666, 666, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, 512, 617, + 30, 667, 667, 667, 667, 667, 667, 667, 667, 667, + 667, 141, 142, 143, 144, 667, 667, 667, 667, 667, + 667, 618, 617, 517, 517, 517, 518, 517, 532, 532, + 532, 533, 532, 724, 724, 724, 725, 724, 667, 667, + 667, 667, 667, 667, 668, 668, 668, 668, 668, 668, + 668, 668, 668, 668, 707, 462, 265, 463, 668, 668, + 668, 668, 668, 668, 724, 724, 724, 725, 724, 726, + 512, 827, 266, 727, 746, 728, 194, 707, 747, 265, + + 748, 668, 668, 668, 668, 668, 668, 543, 543, 543, + 544, 543, 730, 828, 827, 846, 731, 732, 733, 734, + 553, 553, 553, 554, 553, 555, 555, 555, 556, 555, + 553, 553, 553, 554, 553, 738, 579, 750, 846, 739, + 740, 741, 742, 565, 565, 565, 566, 565, 567, 567, + 567, 568, 567, 569, 569, 569, 570, 569, 92, 207, + 208, 750, 750, 750, 751, 750, 752, 227, 500, 227, + 753, 500, 754, 579, 579, 579, 580, 579, 786, 1009, + 789, 207, 609, 1010, 610, 421, 228, 422, 228, 92, + 227, 770, 227, 771, 772, 757, 757, 757, 757, 770, + + 491, 771, 772, 757, 757, 757, 757, 756, 792, 793, + 642, 833, 257, 794, 258, 795, 655, 491, 656, 640, + 415, 415, 415, 416, 415, 1049, 228, 1050, 92, 487, + 756, 757, 757, 757, 757, 758, 759, 760, 761, 757, + 757, 757, 757, 757, 757, 757, 757, 757, 757, 757, + 757, 762, 763, 764, 757, 765, 766, 767, 757, 757, + 757, 757, 643, 768, 487, 769, 615, 299, 757, 757, + 757, 757, 757, 757, 181, 762, 763, 764, 757, 765, + 766, 767, 854, 855, 856, 857, 768, 773, 769, 774, + 182, 757, 757, 757, 757, 782, 858, 181, 473, 606, + + 783, 838, 784, 796, 778, 607, 284, 620, 285, 621, + 773, 254, 774, 392, 392, 392, 393, 392, 255, 858, + 798, 606, 466, 228, 430, 785, 431, 778, 482, 482, + 482, 483, 482, 254, 757, 757, 757, 757, 260, 790, + 790, 790, 791, 790, 801, 652, 860, 785, 263, 653, + 264, 799, 799, 799, 800, 799, 93, 261, 802, 804, + 626, 260, 629, 437, 630, 438, 94, 652, 466, 860, + 805, 805, 805, 806, 805, 634, 458, 441, 93, 394, + 394, 394, 395, 394, 418, 807, 878, 879, 441, 268, + 427, 269, 419, 260, 433, 638, 638, 638, 638, 638, + + 757, 757, 757, 757, 428, 434, 418, 454, 433, 878, + 879, 265, 261, 427, 775, 372, 260, 809, 809, 809, + 809, 809, 609, 435, 610, 639, 829, 266, 434, 810, + 640, 830, 96, 831, 265, 372, 865, 775, 397, 397, + 397, 398, 397, 638, 638, 638, 638, 638, 835, 1102, + 92, 92, 462, 1102, 463, 454, 882, 92, 832, 757, + 757, 757, 757, 363, 638, 638, 638, 638, 638, 847, + 1102, 363, 883, 848, 1102, 849, 454, 641, 92, 882, + 832, 97, 646, 646, 646, 646, 646, 662, 92, 98, + 620, 99, 621, 92, 454, 883, 455, 356, 638, 638, + + 638, 638, 638, 97, 1102, 629, 356, 630, 1102, 887, + 454, 98, 399, 399, 399, 400, 399, 455, 638, 638, + 638, 638, 638, 861, 1102, 349, 349, 862, 1102, 863, + 454, 281, 887, 757, 757, 757, 757, 92, 92, 282, + 836, 836, 836, 837, 836, 836, 836, 836, 837, 836, + 655, 455, 656, 281, 482, 482, 482, 483, 482, 100, + 678, 678, 678, 679, 678, 101, 502, 502, 502, 503, + 502, 455, 323, 492, 492, 492, 493, 492, 875, 888, + 92, 100, 401, 401, 401, 402, 401, 459, 896, 898, + 867, 324, 459, 460, 868, 323, 869, 324, 460, 700, + + 331, 875, 888, 757, 757, 757, 757, 331, 92, 459, + 181, 896, 898, 92, 459, 504, 504, 504, 505, 504, + 502, 502, 502, 503, 502, 321, 182, 865, 865, 865, + 866, 865, 323, 181, 102, 103, 700, 700, 700, 701, + 700, 517, 517, 517, 518, 517, 525, 525, 525, 526, + 525, 324, 783, 321, 784, 323, 102, 403, 403, 403, + 404, 403, 525, 525, 525, 526, 525, 977, 314, 931, + 708, 314, 874, 532, 532, 532, 533, 532, 757, 757, + 757, 757, 532, 532, 532, 533, 532, 92, 228, 324, + 977, 884, 931, 708, 194, 874, 885, 794, 886, 795, + + 418, 104, 724, 724, 724, 725, 724, 814, 419, 92, + 105, 724, 724, 724, 725, 724, 640, 543, 543, 543, + 544, 543, 418, 104, 405, 405, 405, 406, 405, 892, + 893, 894, 895, 553, 553, 553, 554, 553, 555, 555, + 555, 556, 555, 92, 299, 757, 757, 757, 757, 553, + 553, 553, 554, 553, 899, 900, 901, 902, 167, 643, + 181, 978, 106, 565, 565, 565, 566, 565, 154, 207, + 208, 567, 567, 567, 568, 567, 182, 107, 569, 569, + 569, 570, 569, 181, 978, 106, 407, 407, 407, 408, + 407, 207, 906, 273, 273, 983, 907, 985, 908, 750, + + 750, 750, 751, 750, 252, 915, 916, 917, 427, 918, + 919, 920, 579, 579, 579, 580, 579, 921, 983, 922, + 985, 92, 428, 392, 392, 392, 393, 392, 937, 108, + 827, 427, 780, 783, 109, 784, 781, 91, 92, 110, + 921, 92, 922, 915, 916, 917, 913, 918, 919, 920, + 92, 108, 828, 827, 780, 926, 109, 927, 790, 91, + 409, 409, 409, 410, 409, 228, 93, 92, 995, 913, + 394, 394, 394, 395, 394, 830, 94, 831, 926, 92, + 927, 415, 415, 415, 416, 415, 939, 324, 93, 434, + 609, 995, 610, 776, 92, 92, 397, 397, 397, 398, + + 397, 942, 418, 91, 92, 928, 421, 435, 422, 112, + 419, 113, 434, 114, 92, 92, 776, 399, 399, 399, + 400, 399, 933, 96, 418, 91, 943, 934, 928, 935, + 794, 112, 795, 113, 412, 412, 412, 413, 412, 97, + 92, 965, 401, 401, 401, 402, 401, 98, 92, 99, + 966, 934, 89, 935, 936, 757, 757, 757, 757, 167, + 162, 97, 945, 965, 100, 777, 620, 162, 621, 98, + 101, 403, 403, 403, 404, 403, 936, 154, 996, 405, + 405, 405, 406, 405, 799, 997, 100, 116, 777, 405, + 405, 405, 406, 405, 102, 103, 407, 407, 407, 408, + + 407, 996, 132, 412, 412, 412, 413, 412, 997, 92, + 757, 757, 757, 757, 948, 104, 102, 106, 430, 949, + 431, 965, 427, 629, 105, 630, 805, 106, 92, 952, + 966, 90, 107, 437, 930, 438, 428, 104, 89, 108, + 106, 970, 107, 965, 109, 427, 830, 87, 831, 110, + 106, 407, 407, 407, 408, 407, 116, 930, 967, 975, + 434, 108, 968, 462, 969, 463, 109, 940, 940, 940, + 941, 940, 950, 950, 950, 951, 950, 998, 435, 968, + 1039, 969, 1040, 434, 405, 405, 405, 406, 405, 809, + 809, 809, 809, 809, 108, 999, 81, 71, 972, 109, + + 998, 810, 91, 655, 110, 656, 407, 407, 407, 408, + 407, 986, 70, 459, 606, 987, 108, 988, 999, 460, + 607, 109, 106, 1002, 91, 808, 808, 808, 808, 808, + 808, 808, 808, 808, 808, 459, 606, 107, 1003, 808, + 808, 808, 808, 808, 808, 106, 1002, 69, 1017, 108, + 1005, 1007, 1022, 934, 109, 935, 609, 57, 610, 110, + 617, 1003, 808, 808, 808, 808, 808, 808, 639, 639, + 812, 108, 1053, 1005, 1007, 39, 109, 946, 946, 946, + 947, 946, 618, 617, 813, 813, 813, 813, 813, 813, + 813, 813, 813, 813, 1102, 1053, 1054, 1072, 813, 813, + + 813, 813, 813, 813, 1068, 1102, 1069, 1102, 617, 482, + 482, 482, 483, 482, 482, 482, 482, 483, 482, 1054, + 1072, 813, 813, 813, 813, 813, 813, 642, 642, 815, + 618, 617, 678, 678, 678, 679, 678, 502, 502, 502, + 503, 502, 1102, 816, 816, 816, 816, 816, 816, 816, + 816, 816, 816, 1102, 1073, 1102, 1102, 816, 816, 816, + 816, 816, 816, 638, 638, 638, 638, 638, 1023, 1102, + 1102, 1019, 794, 1102, 795, 454, 783, 1073, 784, 1102, + 816, 816, 816, 816, 816, 816, 817, 817, 817, 818, + 817, 606, 1102, 1102, 1102, 1026, 1102, 607, 454, 620, + + 1102, 621, 1102, 819, 819, 819, 819, 819, 819, 819, + 819, 819, 819, 606, 1102, 1102, 455, 819, 819, 819, + 819, 819, 819, 504, 504, 504, 505, 504, 502, 502, + 502, 503, 502, 865, 865, 865, 866, 865, 1102, 455, + 819, 819, 819, 819, 819, 819, 820, 821, 638, 638, + 638, 821, 822, 820, 822, 822, 822, 820, 820, 823, + 822, 822, 822, 822, 824, 824, 824, 824, 824, 824, + 824, 824, 824, 824, 822, 822, 822, 822, 824, 824, + 824, 824, 824, 824, 822, 822, 822, 822, 822, 822, + 822, 822, 822, 822, 822, 822, 822, 822, 822, 822, + + 825, 824, 824, 824, 824, 824, 824, 822, 822, 822, + 822, 822, 822, 822, 822, 822, 822, 822, 822, 822, + 822, 822, 822, 822, 822, 826, 826, 826, 826, 826, + 826, 826, 826, 826, 826, 1102, 1102, 1102, 1102, 826, + 826, 826, 826, 826, 826, 638, 817, 638, 638, 638, + 1027, 1102, 1102, 1044, 629, 1102, 630, 454, 830, 1102, + 831, 1102, 826, 826, 826, 826, 826, 826, 163, 78, + 78, 164, 163, 827, 28, 525, 525, 525, 526, 525, + 525, 525, 525, 526, 525, 839, 839, 839, 839, 839, + 839, 839, 839, 839, 839, 828, 827, 1102, 455, 839, + + 839, 839, 839, 839, 839, 646, 646, 646, 646, 646, + 973, 973, 973, 974, 973, 1102, 1036, 454, 1102, 1102, + 1037, 29, 839, 839, 839, 839, 839, 839, 840, 840, + 840, 840, 840, 840, 840, 840, 840, 840, 1036, 1102, + 1102, 1102, 840, 840, 840, 840, 840, 840, 638, 638, + 638, 638, 638, 517, 517, 517, 518, 517, 962, 652, + 454, 1102, 1102, 653, 1102, 840, 840, 840, 840, 840, + 840, 841, 841, 841, 841, 841, 841, 841, 841, 841, + 841, 652, 1102, 1102, 994, 841, 841, 841, 841, 841, + 841, 1102, 638, 638, 638, 638, 638, 1102, 1102, 1042, + + 1102, 962, 1102, 968, 454, 969, 194, 994, 841, 841, + 841, 841, 841, 841, 842, 842, 842, 842, 842, 842, + 842, 842, 842, 842, 1102, 1102, 1102, 1102, 842, 842, + 842, 842, 842, 842, 1102, 1102, 940, 940, 940, 941, + 940, 836, 1102, 1102, 1102, 455, 532, 532, 532, 533, + 532, 842, 842, 842, 842, 842, 842, 914, 914, 914, + 914, 914, 914, 914, 914, 914, 914, 1102, 1102, 1102, + 1102, 914, 914, 914, 914, 914, 914, 946, 646, 646, + 646, 646, 646, 606, 652, 1102, 1102, 459, 653, 607, + 454, 1102, 1102, 460, 914, 914, 914, 914, 914, 914, + + 409, 409, 409, 410, 409, 606, 652, 617, 1102, 459, + 163, 78, 78, 164, 163, 1102, 28, 532, 532, 532, + 533, 532, 724, 724, 724, 725, 724, 1102, 780, 618, + 617, 962, 781, 929, 724, 724, 724, 725, 724, 553, + 553, 553, 554, 553, 555, 555, 555, 556, 555, 112, + 780, 113, 1102, 114, 1102, 1102, 929, 553, 553, 553, + 554, 553, 1102, 29, 565, 565, 565, 566, 565, 1102, + 1102, 112, 1102, 113, 953, 953, 953, 953, 953, 953, + 953, 953, 953, 953, 1102, 1102, 1102, 1102, 953, 953, + 953, 953, 953, 953, 492, 492, 492, 493, 492, 567, + + 567, 567, 568, 567, 569, 569, 569, 570, 569, 1102, + 1102, 953, 953, 953, 953, 953, 953, 954, 811, 811, + 955, 954, 1102, 640, 750, 750, 750, 751, 750, 1102, + 1102, 181, 1102, 1102, 956, 956, 956, 956, 956, 956, + 956, 956, 956, 956, 1102, 1102, 1102, 182, 956, 956, + 956, 956, 956, 956, 181, 1024, 1024, 1024, 1025, 1024, + 148, 148, 148, 275, 148, 678, 678, 678, 679, 678, + 641, 956, 956, 956, 956, 956, 956, 957, 814, 814, + 958, 957, 1036, 1047, 1056, 1102, 1037, 640, 655, 934, + 656, 935, 1102, 1102, 959, 959, 959, 959, 959, 959, + + 959, 959, 959, 959, 1036, 1102, 1102, 1102, 959, 959, + 959, 959, 959, 959, 700, 700, 700, 701, 700, 1102, + 543, 543, 543, 544, 543, 865, 865, 865, 866, 865, + 643, 959, 959, 959, 959, 959, 959, 960, 960, 960, + 960, 960, 960, 960, 960, 960, 960, 1102, 875, 1102, + 1102, 960, 960, 960, 960, 960, 960, 117, 117, 117, + 232, 117, 1060, 1102, 1102, 811, 794, 324, 795, 1102, + 640, 875, 207, 208, 960, 960, 960, 960, 960, 960, + 821, 821, 821, 963, 821, 724, 724, 724, 725, 724, + 1102, 1102, 1102, 1102, 207, 1102, 1102, 964, 964, 964, + + 964, 964, 964, 964, 964, 964, 964, 1102, 1102, 1102, + 92, 964, 964, 964, 964, 964, 964, 641, 724, 724, + 724, 725, 724, 750, 750, 750, 751, 750, 1057, 1057, + 1057, 1058, 1057, 1102, 964, 964, 964, 964, 964, 964, + 644, 645, 646, 646, 646, 645, 647, 644, 647, 647, + 647, 644, 644, 648, 647, 647, 647, 647, 649, 649, + 649, 649, 649, 649, 649, 649, 649, 649, 647, 647, + 647, 647, 649, 649, 649, 649, 649, 649, 647, 647, + 647, 647, 647, 647, 647, 647, 647, 647, 647, 647, + 647, 647, 647, 647, 650, 649, 649, 649, 649, 649, + + 649, 647, 647, 647, 647, 647, 647, 647, 647, 647, + 647, 647, 647, 647, 647, 647, 647, 647, 647, 64, + 64, 64, 64, 64, 64, 64, 64, 64, 64, 1102, + 1102, 1102, 1102, 64, 64, 64, 64, 64, 64, 579, + 579, 579, 580, 579, 412, 412, 412, 413, 412, 1071, + 1036, 1102, 1102, 1039, 1037, 1040, 64, 64, 64, 64, + 64, 64, 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 1036, 1015, 1102, 115, 30, 30, 30, 30, + 30, 30, 394, 394, 394, 395, 394, 1102, 1102, 1038, + 1102, 1102, 228, 1039, 1102, 1040, 1015, 116, 115, 30, + + 30, 30, 30, 30, 30, 33, 33, 33, 33, 33, + 33, 33, 33, 33, 33, 1102, 1041, 95, 1102, 33, + 33, 33, 33, 33, 33, 1102, 392, 392, 392, 393, + 392, 1102, 1059, 1102, 1102, 96, 1102, 783, 1041, 784, + 95, 1102, 33, 33, 33, 33, 33, 33, 976, 976, + 976, 976, 976, 976, 976, 976, 976, 976, 1102, 1102, + 1102, 1102, 976, 976, 976, 976, 976, 976, 1102, 93, + 397, 397, 397, 398, 397, 1102, 1102, 973, 940, 94, + 399, 399, 399, 400, 399, 976, 976, 976, 976, 976, + 976, 93, 401, 401, 401, 402, 401, 403, 403, 403, + + 404, 403, 1102, 1102, 405, 405, 405, 406, 405, 1045, + 1102, 1102, 1102, 97, 1102, 1102, 407, 407, 407, 408, + 407, 98, 1074, 99, 606, 652, 968, 100, 969, 653, + 607, 1077, 1102, 101, 1102, 97, 830, 1102, 831, 827, + 1102, 104, 106, 98, 102, 103, 606, 652, 1102, 100, + 105, 415, 415, 415, 416, 415, 1102, 107, 1102, 108, + 1102, 828, 827, 104, 109, 106, 102, 1102, 1102, 110, + 405, 405, 405, 406, 405, 1102, 407, 407, 407, 408, + 407, 108, 1075, 1102, 1102, 1102, 109, 409, 409, 409, + 410, 409, 1102, 1102, 1102, 117, 117, 117, 232, 117, + + 1079, 1102, 1102, 1102, 92, 934, 1102, 935, 106, 117, + 117, 117, 232, 117, 117, 117, 117, 232, 117, 108, + 111, 1085, 1102, 107, 109, 965, 1068, 1102, 1069, 110, + 1102, 106, 181, 1087, 966, 1102, 112, 1039, 113, 1040, + 114, 108, 1102, 111, 1102, 1102, 109, 965, 182, 117, + 117, 117, 232, 117, 1102, 181, 1102, 1090, 112, 1095, + 113, 968, 92, 969, 1068, 1102, 1069, 92, 1020, 1020, + 1020, 1021, 1020, 646, 646, 646, 646, 646, 638, 821, + 638, 638, 638, 227, 1102, 454, 1102, 1102, 1102, 1102, + 454, 865, 865, 865, 866, 865, 1102, 1045, 1045, 1045, + + 1046, 1045, 228, 1102, 1102, 1102, 227, 175, 175, 175, + 300, 175, 482, 482, 482, 483, 482, 780, 1098, 1102, + 1067, 781, 1039, 1020, 1040, 1068, 962, 1069, 827, 1102, + 1102, 962, 1096, 1096, 1096, 1097, 1096, 1102, 1102, 780, + 1028, 1028, 1028, 1028, 1028, 1028, 1028, 1028, 1028, 1028, + 828, 827, 1070, 1102, 1028, 1028, 1028, 1028, 1028, 1028, + 92, 1102, 1102, 1102, 1102, 92, 482, 482, 482, 483, + 482, 780, 1102, 1102, 1070, 781, 1102, 1028, 1028, 1028, + 1028, 1028, 1028, 1029, 1029, 1029, 1029, 1029, 1029, 1029, + 1029, 1029, 1029, 780, 1102, 1102, 1102, 1029, 1029, 1029, + + 1029, 1029, 1029, 502, 502, 502, 503, 502, 504, 504, + 504, 505, 504, 821, 821, 821, 963, 821, 1102, 92, + 1029, 1029, 1029, 1029, 1029, 1029, 1030, 1030, 1030, 1030, + 1030, 1030, 1030, 1030, 1030, 1030, 1102, 1102, 1102, 1102, + 1030, 1030, 1030, 1030, 1030, 1030, 1100, 1102, 1102, 1102, + 1102, 1068, 1102, 1069, 1102, 1102, 92, 1102, 1102, 1102, + 1102, 92, 1102, 1030, 1030, 1030, 1030, 1030, 1030, 820, + 1031, 646, 646, 646, 1031, 1032, 820, 1032, 1032, 1032, + 820, 820, 823, 1032, 1032, 1032, 1032, 1033, 1033, 1033, + 1033, 1033, 1033, 1033, 1033, 1033, 1033, 1032, 1032, 1032, + + 1032, 1033, 1033, 1033, 1033, 1033, 1033, 1032, 1032, 1032, + 1032, 1032, 1032, 1032, 1032, 1032, 1032, 1032, 1032, 1032, + 1032, 1032, 1032, 1034, 1033, 1033, 1033, 1033, 1033, 1033, + 1032, 1032, 1032, 1032, 1032, 1032, 1032, 1032, 1032, 1032, + 1032, 1032, 1032, 1032, 1032, 1032, 1032, 1032, 1035, 1035, + 1035, 1035, 1035, 1035, 1035, 1035, 1035, 1035, 1102, 1102, + 1102, 1102, 1035, 1035, 1035, 1035, 1035, 1035, 492, 492, + 492, 493, 492, 502, 502, 502, 503, 502, 700, 700, + 700, 701, 700, 1102, 1102, 1035, 1035, 1035, 1035, 1035, + 1035, 517, 517, 517, 518, 517, 175, 175, 175, 300, + + 175, 1102, 1102, 1102, 1102, 181, 175, 175, 175, 300, + 175, 1102, 995, 525, 525, 525, 526, 525, 1102, 1102, + 1102, 182, 193, 1102, 1102, 1102, 92, 1102, 181, 1102, + 323, 324, 1102, 1102, 1102, 995, 525, 525, 525, 526, + 525, 1102, 1102, 1102, 194, 193, 1102, 1102, 1102, 324, + 1102, 1102, 1102, 323, 532, 532, 532, 533, 532, 92, + 532, 532, 532, 533, 532, 1102, 92, 543, 543, 543, + 544, 543, 553, 553, 553, 554, 553, 555, 555, 555, + 556, 555, 553, 553, 553, 554, 553, 1102, 1088, 92, + 565, 565, 565, 566, 565, 567, 567, 567, 568, 567, + + 569, 569, 569, 570, 569, 1102, 1102, 92, 579, 579, + 579, 580, 579, 92, 175, 175, 175, 300, 175, 207, + 208, 1102, 1102, 1102, 1102, 92, 1102, 1102, 1102, 1102, + 92, 1102, 1102, 1102, 1102, 92, 1036, 1102, 1102, 1102, + 1037, 207, 227, 92, 1102, 1102, 1102, 1102, 92, 1102, + 1102, 1102, 1102, 92, 1102, 1102, 1102, 1102, 1036, 1102, + 1102, 228, 1102, 1102, 1102, 227, 1102, 92, 1061, 1061, + 1061, 1061, 1061, 1061, 1061, 1061, 1061, 1061, 1102, 1102, + 1102, 1102, 1061, 1061, 1061, 1061, 1061, 1061, 646, 646, + 646, 646, 646, 678, 678, 678, 679, 678, 1102, 1102, + + 454, 1102, 1102, 1102, 1102, 1061, 1061, 1061, 1061, 1061, + 1061, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, + 1062, 1102, 1102, 1102, 1102, 1062, 1062, 1062, 1062, 1062, + 1062, 646, 646, 646, 646, 646, 1075, 1075, 1075, 1076, + 1075, 962, 1102, 454, 1102, 1102, 92, 1102, 1062, 1062, + 1062, 1062, 1062, 1062, 1063, 1063, 1063, 1063, 1063, 1063, + 1063, 1063, 1063, 1063, 1102, 1102, 1102, 1102, 1063, 1063, + 1063, 1063, 1063, 1063, 724, 724, 724, 725, 724, 1102, + 965, 1102, 1102, 1102, 962, 1102, 1102, 1102, 1102, 966, + 1102, 1063, 1063, 1063, 1063, 1063, 1063, 1031, 1031, 1031, + + 1064, 1031, 965, 1102, 1102, 1102, 1102, 1102, 1102, 454, + 1102, 1102, 1102, 1102, 1065, 1065, 1065, 1065, 1065, 1065, + 1065, 1065, 1065, 1065, 1102, 1102, 1102, 92, 1065, 1065, + 1065, 1065, 1065, 1065, 700, 700, 700, 701, 700, 724, + 724, 724, 725, 724, 1102, 1102, 1102, 1102, 1102, 1102, + 962, 1065, 1065, 1065, 1065, 1065, 1065, 1066, 1066, 1066, + 1066, 1066, 1066, 1066, 1066, 1066, 1066, 1102, 323, 1102, + 1102, 1066, 1066, 1066, 1066, 1066, 1066, 750, 750, 750, + 751, 750, 1102, 1102, 1102, 1102, 1102, 324, 1102, 1102, + 1102, 323, 92, 1102, 1066, 1066, 1066, 1066, 1066, 1066, + + 646, 1031, 646, 646, 646, 1102, 1102, 1102, 1102, 1102, + 1102, 1102, 454, 1088, 1088, 1088, 1089, 1088, 1102, 1102, + 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, + 92, 1080, 1080, 1080, 1080, 1080, 1080, 1080, 1080, 1080, + 1080, 1102, 1102, 1102, 1102, 1080, 1080, 1080, 1080, 1080, + 1080, 1102, 1102, 962, 1102, 1102, 1088, 1088, 1088, 1089, + 1088, 1102, 1036, 1102, 1102, 1102, 1037, 1102, 1080, 1080, + 1080, 1080, 1080, 1080, 1081, 1081, 1081, 1081, 1081, 1081, + 1081, 1081, 1081, 1081, 1036, 1102, 1102, 1102, 1081, 1081, + 1081, 1081, 1081, 1081, 865, 865, 865, 866, 865, 1102, + + 1102, 1102, 1102, 1102, 1102, 1036, 1102, 1102, 1102, 1037, + 1102, 1081, 1081, 1081, 1081, 1081, 1081, 1082, 1082, 1082, + 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1036, 1102, 1102, + 1102, 1082, 1082, 1082, 1082, 1082, 1082, 1031, 1031, 1031, + 1064, 1031, 1102, 1102, 1102, 1102, 1102, 92, 1102, 454, + 1102, 1102, 1102, 1102, 1082, 1082, 1082, 1082, 1082, 1082, + 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, + 1102, 1102, 1102, 1102, 1083, 1083, 1083, 1083, 1083, 1083, + 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, + 962, 1102, 1102, 1102, 1102, 1102, 1102, 1083, 1083, 1083, + + 1083, 1083, 1083, 1084, 1084, 1084, 1084, 1084, 1084, 1084, + 1084, 1084, 1084, 1102, 1102, 1102, 1102, 1084, 1084, 1084, + 1084, 1084, 1084, 1102, 1102, 1102, 1102, 1102, 1102, 1102, + 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, + 1084, 1084, 1084, 1084, 1084, 1084, 1091, 1091, 1091, 1091, + 1091, 1091, 1091, 1091, 1091, 1091, 1102, 1102, 1102, 1102, + 1091, 1091, 1091, 1091, 1091, 1091, 1102, 1102, 1102, 1102, + 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, + 1102, 1102, 1102, 1091, 1091, 1091, 1091, 1091, 1091, 1092, + 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1102, + + 1102, 1102, 1102, 1092, 1092, 1092, 1092, 1092, 1092, 1102, + 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, + 1102, 1102, 1102, 1102, 1102, 1102, 1092, 1092, 1092, 1092, + 1092, 1092, 451, 451, 451, 451, 451, 451, 451, 451, + 451, 451, 1102, 1102, 1102, 1102, 451, 451, 451, 451, + 451, 451, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, + 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 451, + 451, 451, 451, 451, 451, 1093, 1093, 1093, 1093, 1093, + 1093, 1093, 1093, 1093, 1093, 1102, 1102, 1102, 1102, 1093, + 1093, 1093, 1093, 1093, 1093, 1102, 1102, 1102, 1102, 1102, + + 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, + 1102, 1102, 1093, 1093, 1093, 1093, 1093, 1093, 1094, 1094, + 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1102, 1102, + 1102, 1102, 1094, 1094, 1094, 1094, 1094, 1094, 1102, 1102, + 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, + 1102, 1102, 1102, 1102, 1102, 1094, 1094, 1094, 1094, 1094, + 1094, 639, 639, 639, 639, 639, 639, 639, 639, 639, + 639, 1102, 1102, 1102, 1102, 639, 639, 639, 639, 639, + 639, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, + 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 639, 639, + + 639, 639, 639, 639, 642, 642, 642, 642, 642, 642, + 642, 642, 642, 642, 1102, 1102, 1102, 1102, 642, 642, + 642, 642, 642, 642, 1102, 1102, 1102, 1102, 1102, 1102, + 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, + 1102, 642, 642, 642, 642, 642, 642, 1099, 1099, 1099, + 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1102, 1102, 1102, + 1102, 1099, 1099, 1099, 1099, 1099, 1099, 1102, 1102, 1102, + 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, + 1102, 1102, 1102, 1102, 1099, 1099, 1099, 1099, 1099, 1099, + 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, + + 1102, 1102, 1102, 1102, 1101, 1101, 1101, 1101, 1101, 1101, + 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, + 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1101, 1101, 1101, + 1101, 1101, 1101, 27, 27, 1102, 27, 27, 27, 27, + 27, 27, 30, 30, 30, 30, 33, 33, 1102, 33, + 33, 33, 33, 33, 33, 36, 1102, 1102, 36, 64, + 64, 1102, 64, 64, 67, 67, 1102, 67, 67, 67, + 67, 67, 67, 78, 78, 78, 78, 78, 78, 78, + 78, 78, 82, 82, 1102, 82, 82, 82, 82, 82, + 82, 84, 84, 84, 84, 84, 84, 84, 84, 84, + + 88, 88, 88, 88, 88, 88, 88, 88, 88, 91, + 1102, 91, 91, 148, 148, 1102, 148, 148, 148, 148, + 148, 148, 153, 153, 153, 153, 153, 153, 153, 153, + 153, 166, 166, 166, 166, 166, 166, 166, 166, 166, + 173, 173, 173, 173, 173, 173, 173, 173, 173, 175, + 175, 1102, 175, 175, 175, 175, 175, 175, 279, 279, + 279, 279, 279, 279, 279, 279, 279, 294, 294, 294, + 294, 294, 294, 294, 294, 294, 298, 298, 298, 298, + 298, 298, 298, 298, 298, 451, 451, 451, 1102, 451, + 451, 451, 451, 457, 457, 457, 457, 457, 457, 457, + + 457, 457, 472, 472, 472, 472, 472, 472, 472, 472, + 472, 173, 173, 173, 173, 173, 173, 173, 173, 173, + 639, 639, 1102, 639, 639, 639, 639, 639, 639, 642, + 642, 1102, 642, 642, 642, 642, 642, 642, 457, 457, + 457, 457, 457, 457, 457, 457, 457, 279, 279, 279, + 279, 279, 279, 279, 279, 279, 27, 27, 27, 27, + 27, 27, 27, 27, 27, 472, 472, 472, 472, 472, + 472, 472, 472, 472, 294, 294, 294, 294, 294, 294, + 294, 294, 294, 811, 811, 811, 811, 811, 811, 811, + 811, 811, 814, 814, 814, 814, 814, 814, 814, 814, + + 814, 961, 961, 1102, 1102, 961, 961, 961, 961, 3, + 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, + 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, + 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, + 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, + 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, + 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, + 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, + 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102 + } ; + +static const flex_int16_t yy_chk[7190] = + { 0, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 5, + 5, 5, 5, 5, 6, 6, 6, 6, 6, 7, + 7, 7, 7, 7, 8, 9, 10, 11, 17, 22, + + 22, 22, 22, 22, 36, 7, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 25, 30, 82, 470, + 1113, 470, 58, 27, 16, 46, 25, 26, 7, 64, + 16, 26, 9, 26, 16, 1097, 11, 16, 25, 10, + 17, 8, 7, 46, 16, 58, 36, 16, 46, 26, + 133, 7, 14, 16, 30, 82, 16, 14, 14, 16, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 27, 64, 26, 133, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 18, 33, + 14, 38, 67, 38, 38, 38, 38, 38, 38, 38, + 38, 38, 38, 49, 49, 23, 23, 23, 23, 23, + 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, + 48, 23, 1069, 45, 18, 49, 48, 84, 78, 1068, + 18, 74, 33, 45, 67, 74, 89, 74, 154, 89, + 167, 154, 48, 167, 23, 45, 18, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 51, 23, 170, + 50, 19, 19, 19, 19, 19, 19, 23, 1058, 50, + + 84, 47, 51, 52, 54, 78, 61, 1050, 52, 47, + 51, 47, 50, 52, 19, 19, 19, 19, 19, 19, + 29, 29, 29, 47, 59, 52, 54, 54, 61, 61, + 52, 47, 170, 664, 59, 664, 29, 29, 29, 29, + 29, 29, 29, 29, 29, 29, 59, 60, 148, 72, + 29, 29, 29, 29, 29, 29, 72, 150, 79, 85, + 66, 299, 195, 79, 299, 60, 1049, 195, 85, 195, + 60, 72, 1025, 29, 29, 29, 29, 29, 29, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 53, + 148, 66, 126, 32, 32, 32, 32, 32, 32, 150, + + 73, 126, 66, 1012, 73, 53, 73, 53, 100, 53, + 79, 85, 53, 66, 126, 77, 32, 32, 32, 32, + 32, 32, 34, 34, 34, 77, 73, 53, 124, 53, + 100, 100, 222, 1011, 124, 95, 222, 77, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 73, 151, + 124, 95, 34, 34, 34, 34, 34, 34, 95, 151, + 224, 991, 990, 163, 224, 96, 105, 988, 453, 96, + 105, 96, 105, 987, 980, 34, 34, 34, 34, 34, + 34, 37, 37, 37, 37, 37, 37, 37, 37, 37, + 37, 96, 105, 105, 130, 37, 37, 37, 37, 37, + + 37, 151, 119, 979, 106, 106, 119, 119, 119, 119, + 163, 453, 969, 96, 105, 105, 130, 130, 37, 37, + 37, 37, 37, 37, 56, 56, 106, 968, 951, 56, + 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, + + 56, 56, 56, 62, 115, 935, 134, 62, 62, 62, + 62, 137, 669, 134, 669, 137, 158, 137, 116, 125, + 125, 253, 116, 115, 116, 62, 138, 115, 134, 62, + 127, 121, 62, 121, 121, 121, 121, 121, 121, 158, + 934, 125, 138, 253, 116, 127, 139, 932, 62, 138, + 139, 62, 139, 127, 62, 65, 65, 65, 65, 65, + 65, 65, 65, 65, 65, 911, 116, 159, 136, 65, + 65, 65, 65, 65, 65, 458, 157, 910, 458, 99, + 157, 141, 157, 99, 99, 99, 99, 136, 129, 141, + 159, 136, 65, 65, 65, 65, 65, 65, 68, 68, + + 68, 68, 68, 160, 129, 99, 129, 642, 129, 68, + 160, 129, 141, 99, 147, 68, 68, 68, 68, 68, + 68, 68, 68, 68, 68, 160, 129, 99, 129, 68, + 68, 68, 68, 68, 68, 99, 147, 147, 360, 103, + 908, 155, 360, 103, 103, 103, 103, 232, 452, 155, + 642, 68, 68, 68, 68, 68, 68, 68, 80, 80, + 80, 80, 80, 155, 80, 103, 123, 907, 123, 123, + 123, 123, 123, 123, 103, 80, 80, 80, 80, 80, + 80, 80, 80, 80, 80, 473, 178, 103, 473, 80, + 80, 80, 80, 80, 80, 452, 103, 135, 901, 232, + + 140, 135, 143, 135, 140, 140, 140, 140, 146, 178, + 143, 80, 80, 80, 80, 80, 80, 80, 83, 83, + 83, 83, 83, 135, 161, 179, 146, 680, 161, 680, + 161, 146, 899, 143, 83, 83, 83, 83, 83, 83, + 83, 83, 83, 83, 83, 135, 145, 187, 179, 83, + 83, 83, 83, 83, 83, 156, 145, 177, 895, 893, + 156, 177, 156, 177, 164, 703, 890, 703, 145, 164, + 187, 83, 83, 83, 83, 83, 83, 83, 86, 86, + 86, 86, 86, 183, 156, 189, 186, 183, 86, 183, + 186, 186, 186, 186, 300, 86, 86, 86, 86, 86, + + 86, 86, 86, 86, 86, 168, 156, 814, 189, 86, + 86, 86, 86, 86, 86, 194, 164, 198, 199, 194, + 168, 194, 101, 199, 200, 199, 101, 101, 101, 101, + 193, 86, 86, 86, 86, 86, 86, 86, 90, 198, + 198, 194, 90, 90, 90, 90, 300, 200, 101, 193, + 814, 128, 101, 193, 201, 889, 128, 168, 90, 90, + 90, 128, 90, 194, 90, 204, 171, 90, 90, 90, + 101, 872, 362, 128, 101, 171, 362, 201, 128, 205, + 214, 90, 90, 90, 90, 709, 90, 709, 204, 90, + 90, 90, 92, 92, 92, 92, 92, 92, 92, 92, + + 92, 92, 205, 214, 216, 257, 92, 92, 92, 92, + 92, 92, 871, 162, 162, 162, 162, 162, 171, 203, + 209, 869, 258, 203, 209, 203, 209, 216, 257, 92, + 92, 92, 92, 92, 92, 94, 94, 94, 94, 94, + 94, 94, 94, 94, 94, 258, 639, 868, 865, 94, + 94, 94, 94, 94, 94, 559, 162, 260, 107, 559, + 863, 94, 107, 110, 107, 862, 162, 110, 110, 110, + 110, 260, 94, 94, 94, 94, 94, 94, 162, 107, + 260, 114, 265, 94, 107, 114, 114, 114, 114, 110, + 212, 212, 213, 639, 110, 254, 213, 213, 213, 213, + + 265, 286, 107, 254, 182, 265, 107, 114, 182, 286, + 182, 110, 212, 114, 220, 114, 110, 254, 220, 220, + 220, 220, 229, 286, 182, 857, 229, 228, 229, 114, + 182, 228, 561, 228, 855, 114, 561, 114, 118, 118, + 118, 118, 118, 303, 234, 304, 852, 182, 234, 234, + 234, 234, 182, 228, 316, 118, 118, 118, 118, 118, + 118, 118, 118, 118, 118, 714, 303, 714, 304, 118, + 118, 118, 118, 118, 118, 228, 256, 316, 259, 255, + 256, 416, 256, 208, 255, 259, 255, 208, 208, 208, + 208, 118, 118, 118, 118, 118, 118, 118, 120, 851, + + 259, 120, 120, 120, 120, 120, 120, 120, 255, 208, + 261, 318, 333, 120, 261, 120, 261, 236, 208, 236, + 236, 236, 236, 236, 236, 242, 242, 242, 242, 242, + 255, 208, 849, 416, 318, 333, 120, 483, 120, 122, + 208, 334, 122, 122, 122, 122, 122, 122, 122, 305, + 305, 305, 305, 305, 122, 238, 122, 238, 238, 238, + 238, 238, 238, 262, 334, 275, 283, 262, 242, 262, + 267, 283, 242, 283, 267, 275, 267, 122, 242, 122, + 149, 149, 149, 149, 149, 848, 281, 266, 831, 483, + 242, 266, 281, 266, 242, 338, 830, 149, 149, 149, + + 149, 149, 149, 149, 149, 149, 149, 266, 281, 339, + 343, 149, 149, 149, 149, 149, 149, 275, 338, 249, + 249, 249, 249, 249, 726, 282, 726, 795, 344, 282, + 266, 282, 339, 343, 149, 149, 149, 149, 149, 149, + 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, + 249, 344, 794, 282, 152, 152, 152, 152, 152, 152, + 270, 752, 784, 752, 270, 270, 270, 270, 957, 783, + 287, 351, 249, 249, 287, 282, 287, 152, 152, 152, + 152, 152, 152, 165, 165, 165, 165, 165, 165, 165, + 165, 165, 165, 754, 351, 292, 417, 165, 165, 165, + + 165, 165, 165, 753, 272, 272, 272, 272, 272, 290, + 302, 957, 328, 290, 302, 290, 302, 328, 417, 328, + 165, 165, 165, 165, 165, 165, 169, 169, 169, 169, + 169, 169, 169, 169, 169, 169, 291, 292, 353, 272, + 169, 169, 169, 169, 169, 169, 291, 292, 750, 792, + 503, 792, 241, 241, 241, 241, 241, 272, 291, 292, + 779, 353, 272, 169, 169, 169, 169, 169, 169, 172, + 172, 172, 172, 172, 172, 172, 172, 172, 172, 401, + 401, 748, 779, 172, 172, 172, 172, 172, 172, 306, + 306, 306, 306, 306, 811, 241, 244, 244, 244, 244, + + 244, 401, 503, 241, 405, 241, 172, 172, 172, 172, + 172, 172, 176, 176, 176, 176, 176, 241, 307, 405, + 747, 332, 307, 741, 307, 241, 332, 405, 332, 176, + 176, 176, 176, 176, 176, 176, 176, 176, 176, 244, + 244, 811, 392, 176, 176, 176, 176, 176, 176, 244, + 739, 954, 392, 273, 273, 273, 273, 273, 734, 311, + 412, 244, 244, 311, 392, 311, 176, 176, 176, 176, + 176, 176, 233, 233, 233, 233, 233, 233, 233, 233, + 233, 233, 412, 412, 273, 462, 233, 233, 233, 233, + 233, 233, 240, 240, 240, 240, 240, 801, 954, 801, + + 505, 271, 271, 271, 271, 271, 273, 273, 462, 233, + 233, 233, 233, 233, 233, 235, 526, 533, 235, 235, + 235, 235, 235, 235, 235, 325, 732, 240, 463, 325, + 235, 325, 235, 728, 727, 240, 468, 243, 243, 243, + 243, 243, 315, 468, 271, 240, 315, 315, 315, 315, + 240, 463, 505, 235, 271, 235, 237, 240, 468, 237, + 237, 237, 237, 237, 237, 237, 271, 724, 526, 533, + 403, 237, 478, 237, 245, 245, 245, 245, 245, 403, + 243, 246, 246, 246, 246, 246, 402, 337, 705, 243, + 243, 337, 403, 337, 237, 478, 237, 239, 239, 239, + + 239, 239, 243, 704, 251, 251, 251, 251, 251, 346, + 479, 243, 245, 346, 239, 346, 554, 245, 239, 239, + 239, 239, 324, 698, 246, 342, 324, 245, 324, 246, + 342, 697, 342, 479, 246, 245, 556, 402, 402, 245, + 239, 250, 250, 250, 250, 250, 246, 251, 324, 350, + 239, 246, 251, 350, 350, 350, 350, 251, 759, 402, + 759, 759, 239, 247, 247, 247, 247, 247, 554, 251, + 324, 358, 250, 694, 251, 358, 358, 358, 358, 250, + 288, 288, 288, 288, 288, 807, 693, 807, 556, 274, + 274, 274, 274, 274, 250, 250, 247, 277, 277, 277, + + 277, 277, 250, 277, 366, 566, 247, 277, 366, 277, + 366, 369, 247, 397, 247, 369, 247, 369, 740, 247, + 688, 397, 740, 397, 274, 374, 288, 686, 247, 374, + 374, 374, 374, 288, 247, 397, 247, 248, 248, 248, + 248, 248, 274, 397, 838, 399, 838, 274, 288, 424, + 277, 399, 742, 424, 248, 424, 742, 566, 248, 248, + 248, 248, 320, 320, 320, 320, 320, 399, 248, 280, + 280, 280, 280, 280, 321, 321, 321, 321, 321, 322, + 322, 322, 322, 322, 495, 280, 583, 583, 583, 583, + 248, 248, 276, 276, 276, 276, 276, 335, 335, 335, + + 335, 335, 336, 336, 336, 336, 336, 495, 280, 276, + 276, 276, 276, 276, 276, 276, 276, 276, 276, 682, + 681, 423, 280, 276, 276, 276, 276, 276, 276, 423, + 678, 280, 289, 289, 289, 289, 289, 340, 340, 340, + 340, 340, 427, 423, 676, 675, 276, 276, 276, 276, + 276, 276, 278, 278, 278, 278, 278, 278, 278, 278, + 278, 278, 656, 492, 427, 427, 278, 278, 278, 278, + 278, 278, 341, 341, 341, 341, 341, 655, 289, 492, + 331, 331, 331, 331, 331, 289, 492, 630, 629, 278, + 278, 278, 278, 278, 278, 355, 355, 355, 355, 355, + + 289, 293, 293, 293, 293, 293, 293, 293, 293, 293, + 293, 331, 621, 447, 497, 293, 293, 293, 293, 293, + 293, 620, 577, 349, 349, 349, 349, 349, 356, 356, + 356, 356, 356, 331, 331, 447, 447, 497, 293, 293, + 293, 293, 293, 293, 296, 296, 296, 296, 296, 296, + 296, 296, 296, 296, 576, 517, 394, 521, 296, 296, + 296, 296, 296, 296, 357, 357, 357, 357, 357, 363, + 363, 363, 363, 363, 394, 349, 349, 517, 517, 394, + 521, 296, 296, 296, 296, 296, 296, 297, 297, 297, + 297, 297, 297, 297, 297, 297, 297, 349, 847, 573, + + 847, 297, 297, 297, 297, 297, 297, 364, 364, 364, + 364, 364, 572, 314, 314, 314, 314, 314, 365, 365, + 365, 365, 365, 393, 297, 297, 297, 297, 297, 297, + 301, 301, 301, 301, 301, 301, 301, 301, 301, 301, + 761, 522, 761, 761, 301, 301, 301, 301, 301, 301, + 314, 372, 372, 372, 372, 372, 376, 569, 376, 376, + 376, 376, 376, 376, 522, 393, 314, 301, 301, 301, + 301, 301, 301, 314, 378, 393, 378, 378, 378, 378, + 378, 378, 409, 568, 459, 372, 567, 393, 459, 565, + 389, 389, 389, 389, 389, 429, 560, 418, 409, 429, + + 409, 429, 409, 418, 372, 409, 459, 558, 372, 373, + 373, 373, 373, 373, 373, 373, 373, 373, 373, 418, + 409, 389, 409, 373, 373, 373, 373, 373, 373, 380, + 380, 380, 380, 380, 867, 568, 867, 555, 381, 381, + 381, 381, 381, 389, 389, 553, 373, 373, 373, 373, + 373, 373, 375, 549, 547, 375, 375, 375, 375, 375, + 375, 375, 900, 420, 380, 528, 900, 375, 420, 375, + 420, 395, 380, 400, 382, 382, 382, 382, 382, 411, + 398, 381, 380, 411, 411, 411, 411, 380, 528, 381, + 375, 381, 375, 377, 380, 541, 377, 377, 377, 377, + + 377, 377, 377, 381, 662, 395, 529, 884, 377, 884, + 377, 381, 662, 406, 419, 540, 532, 382, 419, 400, + 419, 382, 398, 395, 404, 400, 662, 382, 395, 529, + 398, 377, 398, 377, 379, 379, 379, 379, 379, 382, + 570, 400, 419, 382, 398, 383, 383, 383, 383, 383, + 406, 379, 398, 543, 543, 379, 379, 379, 379, 384, + 384, 384, 384, 384, 419, 406, 525, 404, 385, 385, + 385, 385, 385, 406, 679, 543, 404, 379, 464, 386, + 386, 386, 386, 386, 464, 515, 407, 379, 383, 404, + 413, 407, 570, 906, 514, 906, 407, 383, 383, 379, + + 464, 432, 384, 384, 493, 432, 385, 432, 407, 544, + 383, 385, 384, 407, 391, 391, 391, 391, 391, 383, + 413, 385, 386, 465, 384, 384, 679, 386, 465, 385, + 465, 511, 386, 385, 390, 390, 390, 390, 390, 510, + 493, 414, 413, 413, 386, 414, 414, 414, 414, 386, + 387, 387, 387, 387, 387, 535, 493, 391, 414, 410, + 544, 544, 391, 493, 435, 390, 408, 391, 435, 396, + 435, 536, 390, 396, 396, 396, 396, 414, 535, 391, + 725, 414, 544, 387, 391, 508, 436, 390, 390, 396, + 436, 410, 436, 387, 536, 390, 546, 507, 428, 387, + + 443, 387, 428, 387, 428, 396, 387, 410, 408, 410, + 443, 410, 396, 408, 410, 387, 504, 502, 408, 546, + 428, 387, 443, 387, 388, 388, 388, 388, 388, 410, + 408, 410, 725, 498, 496, 408, 425, 425, 425, 425, + 425, 388, 446, 428, 439, 388, 388, 388, 388, 426, + 426, 426, 426, 426, 444, 388, 433, 433, 433, 433, + 433, 490, 439, 448, 440, 548, 489, 439, 440, 445, + 440, 441, 441, 441, 441, 441, 446, 388, 388, 442, + 486, 485, 425, 442, 442, 442, 442, 445, 548, 425, + 433, 482, 445, 448, 446, 426, 444, 461, 472, 446, + + 513, 461, 426, 461, 425, 513, 444, 513, 441, 433, + 942, 457, 942, 433, 460, 448, 448, 426, 444, 460, + 438, 460, 467, 477, 441, 437, 467, 477, 467, 477, + 518, 441, 449, 449, 449, 449, 449, 449, 449, 449, + 449, 449, 605, 469, 460, 609, 449, 449, 449, 449, + 449, 449, 450, 450, 450, 450, 450, 484, 450, 431, + 518, 484, 450, 484, 450, 605, 460, 430, 609, 449, + 449, 449, 449, 449, 449, 451, 451, 451, 451, 451, + 488, 451, 518, 518, 488, 451, 488, 451, 469, 480, + 480, 480, 480, 480, 422, 469, 481, 481, 481, 481, + + 481, 421, 494, 610, 670, 450, 494, 494, 494, 494, + 469, 487, 487, 487, 487, 487, 499, 499, 499, 499, + 499, 500, 500, 500, 500, 500, 610, 670, 451, 455, + 455, 455, 455, 455, 455, 455, 455, 455, 455, 455, + 455, 455, 455, 455, 455, 455, 455, 455, 455, 455, + 455, 455, 455, 455, 455, 455, 455, 455, 455, 455, + 455, 455, 455, 455, 455, 455, 455, 455, 455, 455, + 455, 455, 455, 455, 455, 455, 455, 455, 455, 455, + 455, 455, 455, 455, 455, 455, 455, 455, 455, 455, + 455, 455, 455, 455, 455, 455, 455, 455, 455, 455, + + 455, 455, 455, 455, 455, 455, 455, 455, 456, 456, + 456, 456, 456, 415, 371, 466, 466, 466, 466, 466, + 491, 491, 491, 491, 491, 456, 456, 456, 456, 456, + 456, 456, 456, 456, 456, 602, 602, 602, 602, 456, + 456, 456, 456, 456, 456, 501, 501, 501, 501, 501, + 506, 519, 370, 368, 506, 509, 506, 491, 367, 509, + 466, 509, 456, 456, 456, 456, 456, 456, 466, 361, + 519, 520, 359, 491, 519, 527, 520, 354, 520, 527, + 491, 527, 466, 471, 471, 471, 471, 471, 352, 471, + 523, 523, 523, 523, 523, 512, 512, 512, 512, 512, + + 471, 471, 471, 471, 471, 471, 471, 471, 471, 471, + 604, 604, 604, 604, 471, 471, 471, 471, 471, 471, + 524, 524, 524, 524, 524, 948, 348, 948, 615, 512, + 530, 530, 530, 530, 530, 615, 471, 471, 471, 471, + 471, 471, 471, 474, 474, 474, 474, 474, 512, 534, + 615, 606, 512, 347, 534, 606, 534, 474, 345, 330, + 474, 474, 474, 474, 474, 474, 474, 474, 474, 474, + 952, 329, 952, 606, 474, 474, 474, 474, 474, 474, + 474, 474, 474, 474, 474, 474, 474, 474, 474, 474, + 474, 474, 474, 474, 474, 474, 474, 474, 474, 474, + + 474, 474, 474, 474, 474, 474, 474, 474, 474, 474, + 474, 474, 474, 474, 474, 474, 474, 474, 327, 622, + 474, 475, 475, 475, 475, 475, 475, 475, 475, 475, + 475, 636, 636, 636, 636, 475, 475, 475, 475, 475, + 475, 622, 622, 516, 516, 516, 516, 516, 531, 531, + 531, 531, 531, 537, 537, 537, 537, 537, 475, 475, + 475, 475, 475, 475, 476, 476, 476, 476, 476, 476, + 476, 476, 476, 476, 516, 975, 634, 975, 476, 476, + 476, 476, 476, 476, 538, 538, 538, 538, 538, 539, + 326, 652, 634, 539, 571, 539, 516, 516, 571, 634, + + 571, 476, 476, 476, 476, 476, 476, 542, 542, 542, + 542, 542, 545, 652, 652, 671, 545, 545, 545, 545, + 550, 550, 550, 550, 550, 551, 551, 551, 551, 551, + 552, 552, 552, 552, 552, 557, 580, 751, 671, 557, + 557, 557, 557, 562, 562, 562, 562, 562, 563, 563, + 563, 563, 563, 564, 564, 564, 564, 564, 323, 542, + 542, 574, 574, 574, 574, 574, 575, 579, 319, 580, + 575, 317, 575, 578, 578, 578, 578, 578, 608, 902, + 612, 542, 608, 902, 608, 612, 579, 612, 580, 751, + 579, 585, 580, 585, 585, 585, 585, 585, 585, 587, + + 313, 587, 587, 587, 587, 587, 587, 578, 614, 618, + 815, 654, 614, 618, 614, 618, 654, 312, 654, 815, + 598, 598, 598, 598, 598, 986, 578, 986, 310, 309, + 578, 582, 582, 582, 582, 582, 582, 582, 582, 582, + 582, 598, 598, 598, 598, 582, 582, 582, 582, 582, + 582, 584, 584, 584, 584, 584, 584, 584, 601, 601, + 601, 601, 815, 584, 308, 584, 616, 298, 582, 582, + 582, 582, 582, 582, 601, 586, 586, 586, 586, 586, + 586, 586, 684, 684, 684, 684, 584, 586, 584, 586, + 601, 603, 603, 603, 603, 607, 685, 601, 294, 611, + + 607, 661, 607, 619, 603, 611, 661, 619, 661, 619, + 586, 616, 586, 588, 588, 588, 588, 588, 616, 685, + 623, 611, 285, 603, 623, 607, 623, 603, 672, 672, + 672, 672, 672, 616, 588, 588, 588, 588, 626, 613, + 613, 613, 613, 613, 625, 657, 687, 607, 625, 657, + 625, 624, 624, 624, 624, 624, 588, 626, 628, 631, + 627, 626, 628, 631, 628, 631, 588, 657, 284, 687, + 632, 632, 632, 632, 632, 635, 279, 269, 588, 589, + 589, 589, 589, 589, 613, 633, 710, 711, 268, 633, + 624, 633, 613, 627, 264, 638, 638, 638, 638, 638, + + 589, 589, 589, 589, 624, 632, 613, 638, 263, 710, + 711, 635, 627, 624, 589, 231, 627, 640, 640, 640, + 640, 640, 1022, 632, 1022, 812, 653, 635, 632, 640, + 812, 653, 589, 653, 635, 230, 866, 589, 590, 590, + 590, 590, 590, 644, 644, 644, 644, 644, 658, 644, + 227, 226, 658, 644, 658, 644, 715, 225, 653, 590, + 590, 590, 590, 223, 645, 645, 645, 645, 645, 674, + 645, 221, 716, 674, 645, 674, 645, 812, 219, 715, + 653, 590, 646, 646, 646, 646, 646, 663, 866, 590, + 1026, 590, 1026, 218, 646, 716, 644, 217, 647, 647, + + 647, 647, 647, 590, 647, 1027, 215, 1027, 647, 720, + 647, 590, 591, 591, 591, 591, 591, 645, 648, 648, + 648, 648, 648, 692, 648, 211, 210, 692, 648, 692, + 648, 663, 720, 591, 591, 591, 591, 207, 206, 663, + 659, 659, 659, 659, 659, 660, 660, 660, 660, 660, + 1047, 647, 1047, 663, 673, 673, 673, 673, 673, 591, + 677, 677, 677, 677, 677, 591, 689, 689, 689, 689, + 689, 648, 700, 683, 683, 683, 683, 683, 707, 721, + 202, 591, 592, 592, 592, 592, 592, 659, 731, 733, + 696, 700, 660, 659, 696, 700, 696, 707, 660, 701, + + 197, 707, 721, 592, 592, 592, 592, 196, 192, 659, + 683, 731, 733, 191, 660, 690, 690, 690, 690, 690, + 691, 691, 691, 691, 691, 190, 683, 695, 695, 695, + 695, 695, 701, 683, 592, 592, 699, 699, 699, 699, + 699, 706, 706, 706, 706, 706, 712, 712, 712, 712, + 712, 701, 1059, 188, 1059, 701, 592, 593, 593, 593, + 593, 593, 713, 713, 713, 713, 713, 843, 185, 777, + 699, 184, 706, 717, 717, 717, 717, 717, 593, 593, + 593, 593, 718, 718, 718, 718, 718, 181, 777, 699, + 843, 719, 777, 699, 706, 706, 719, 1060, 719, 1060, + + 790, 593, 722, 722, 722, 722, 722, 958, 790, 180, + 593, 723, 723, 723, 723, 723, 958, 729, 729, 729, + 729, 729, 790, 593, 594, 594, 594, 594, 594, 730, + 730, 730, 730, 735, 735, 735, 735, 735, 736, 736, + 736, 736, 736, 175, 173, 594, 594, 594, 594, 737, + 737, 737, 737, 737, 738, 738, 738, 738, 166, 958, + 775, 844, 594, 743, 743, 743, 743, 743, 153, 729, + 729, 744, 744, 744, 744, 744, 775, 594, 745, 745, + 745, 745, 745, 775, 844, 594, 595, 595, 595, 595, + 595, 729, 746, 144, 142, 854, 746, 856, 746, 749, + + 749, 749, 749, 749, 132, 758, 758, 758, 799, 758, + 758, 758, 755, 755, 755, 755, 755, 758, 854, 758, + 856, 131, 799, 762, 762, 762, 762, 762, 782, 595, + 832, 799, 785, 782, 595, 782, 785, 595, 117, 595, + 758, 113, 758, 760, 760, 760, 755, 760, 760, 760, + 112, 595, 832, 832, 785, 760, 595, 760, 791, 595, + 596, 596, 596, 596, 596, 755, 762, 111, 874, 755, + 763, 763, 763, 763, 763, 1077, 762, 1077, 760, 109, + 760, 772, 772, 772, 772, 772, 786, 874, 762, 805, + 786, 874, 786, 596, 108, 104, 764, 764, 764, 764, + + 764, 789, 791, 596, 102, 763, 789, 805, 789, 596, + 791, 596, 805, 596, 98, 97, 596, 765, 765, 765, + 765, 765, 781, 763, 791, 596, 793, 781, 763, 781, + 793, 596, 793, 596, 597, 597, 597, 597, 597, 764, + 93, 827, 766, 766, 766, 766, 766, 764, 91, 764, + 827, 1079, 88, 1079, 781, 597, 597, 597, 597, 81, + 76, 764, 796, 827, 765, 597, 796, 75, 796, 764, + 765, 767, 767, 767, 767, 767, 781, 71, 876, 768, + 768, 768, 768, 768, 800, 877, 765, 597, 597, 599, + 599, 599, 599, 599, 766, 766, 769, 769, 769, 769, + + 769, 876, 57, 771, 771, 771, 771, 771, 877, 55, + 599, 599, 599, 599, 798, 767, 766, 768, 798, 802, + 798, 1075, 800, 802, 767, 802, 806, 599, 44, 804, + 1075, 41, 768, 804, 771, 804, 800, 767, 39, 769, + 768, 829, 599, 1075, 769, 800, 829, 35, 829, 769, + 599, 600, 600, 600, 600, 600, 771, 771, 828, 835, + 806, 769, 828, 835, 828, 835, 769, 787, 787, 787, + 787, 787, 803, 803, 803, 803, 803, 880, 806, 1090, + 1098, 1090, 1098, 806, 773, 773, 773, 773, 773, 809, + 809, 809, 809, 809, 600, 881, 31, 24, 833, 600, + + 880, 809, 600, 833, 600, 833, 774, 774, 774, 774, + 774, 861, 21, 836, 787, 861, 600, 861, 881, 836, + 787, 600, 773, 885, 600, 637, 637, 637, 637, 637, + 637, 637, 637, 637, 637, 836, 787, 773, 886, 637, + 637, 637, 637, 637, 637, 773, 885, 20, 933, 774, + 892, 894, 939, 933, 774, 933, 939, 15, 939, 774, + 946, 886, 637, 637, 637, 637, 637, 637, 641, 641, + 641, 774, 1000, 892, 894, 13, 774, 797, 797, 797, + 797, 797, 946, 946, 641, 641, 641, 641, 641, 641, + 641, 641, 641, 641, 3, 1000, 1001, 1039, 641, 641, + + 641, 641, 641, 641, 1100, 0, 1100, 0, 797, 845, + 845, 845, 845, 845, 846, 846, 846, 846, 846, 1001, + 1039, 641, 641, 641, 641, 641, 641, 643, 643, 643, + 797, 797, 850, 850, 850, 850, 850, 858, 858, 858, + 858, 858, 0, 643, 643, 643, 643, 643, 643, 643, + 643, 643, 643, 0, 1040, 0, 0, 643, 643, 643, + 643, 643, 643, 817, 817, 817, 817, 817, 943, 817, + 0, 937, 943, 817, 943, 817, 937, 1040, 937, 0, + 643, 643, 643, 643, 643, 643, 649, 649, 649, 649, + 649, 940, 649, 0, 0, 945, 649, 940, 649, 945, + + 0, 945, 0, 649, 649, 649, 649, 649, 649, 649, + 649, 649, 649, 940, 0, 0, 817, 649, 649, 649, + 649, 649, 649, 859, 859, 859, 859, 859, 860, 860, + 860, 860, 860, 864, 864, 864, 864, 864, 0, 649, + 649, 649, 649, 649, 649, 649, 650, 650, 650, 650, + 650, 650, 650, 650, 650, 650, 650, 650, 650, 650, + 650, 650, 650, 650, 650, 650, 650, 650, 650, 650, + 650, 650, 650, 650, 650, 650, 650, 650, 650, 650, + 650, 650, 650, 650, 650, 650, 650, 650, 650, 650, + 650, 650, 650, 650, 650, 650, 650, 650, 650, 650, + + 650, 650, 650, 650, 650, 650, 650, 650, 650, 650, + 650, 650, 650, 650, 650, 650, 650, 650, 650, 650, + 650, 650, 650, 650, 650, 651, 651, 651, 651, 651, + 651, 651, 651, 651, 651, 0, 0, 0, 0, 651, + 651, 651, 651, 651, 651, 818, 818, 818, 818, 818, + 949, 818, 0, 970, 949, 818, 949, 818, 970, 0, + 970, 0, 651, 651, 651, 651, 651, 651, 665, 665, + 665, 665, 665, 1045, 665, 878, 878, 878, 878, 878, + 879, 879, 879, 879, 879, 665, 665, 665, 665, 665, + 665, 665, 665, 665, 665, 1045, 1045, 0, 818, 665, + + 665, 665, 665, 665, 665, 820, 820, 820, 820, 820, + 834, 834, 834, 834, 834, 0, 965, 820, 0, 0, + 965, 665, 665, 665, 665, 665, 665, 665, 666, 666, + 666, 666, 666, 666, 666, 666, 666, 666, 965, 0, + 0, 0, 666, 666, 666, 666, 666, 666, 821, 821, + 821, 821, 821, 873, 873, 873, 873, 873, 820, 834, + 821, 0, 0, 834, 0, 666, 666, 666, 666, 666, + 666, 667, 667, 667, 667, 667, 667, 667, 667, 667, + 667, 834, 0, 0, 873, 667, 667, 667, 667, 667, + 667, 0, 822, 822, 822, 822, 822, 0, 822, 967, + + 0, 821, 822, 967, 822, 967, 873, 873, 667, 667, + 667, 667, 667, 667, 668, 668, 668, 668, 668, 668, + 668, 668, 668, 668, 0, 0, 0, 0, 668, 668, + 668, 668, 668, 668, 0, 0, 788, 788, 788, 788, + 788, 837, 0, 0, 0, 822, 882, 882, 882, 882, + 882, 668, 668, 668, 668, 668, 668, 757, 757, 757, + 757, 757, 757, 757, 757, 757, 757, 0, 0, 0, + 0, 757, 757, 757, 757, 757, 757, 947, 823, 823, + 823, 823, 823, 788, 973, 0, 0, 837, 973, 788, + 823, 0, 0, 837, 757, 757, 757, 757, 757, 757, + + 770, 770, 770, 770, 770, 788, 973, 947, 0, 837, + 839, 839, 839, 839, 839, 0, 839, 883, 883, 883, + 883, 883, 887, 887, 887, 887, 887, 0, 1020, 947, + 947, 823, 1020, 770, 888, 888, 888, 888, 888, 896, + 896, 896, 896, 896, 897, 897, 897, 897, 897, 770, + 1020, 770, 0, 770, 0, 0, 770, 898, 898, 898, + 898, 898, 0, 839, 903, 903, 903, 903, 903, 0, + 0, 770, 0, 770, 808, 808, 808, 808, 808, 808, + 808, 808, 808, 808, 0, 0, 0, 0, 808, 808, + 808, 808, 808, 808, 853, 853, 853, 853, 853, 904, + + 904, 904, 904, 904, 905, 905, 905, 905, 905, 0, + 0, 808, 808, 808, 808, 808, 808, 813, 813, 813, + 813, 813, 0, 813, 909, 909, 909, 909, 909, 0, + 0, 853, 0, 0, 813, 813, 813, 813, 813, 813, + 813, 813, 813, 813, 0, 0, 0, 853, 813, 813, + 813, 813, 813, 813, 853, 944, 944, 944, 944, 944, + 953, 953, 953, 953, 953, 981, 981, 981, 981, 981, + 813, 813, 813, 813, 813, 813, 813, 816, 816, 816, + 816, 816, 1041, 972, 1017, 0, 1041, 816, 972, 1017, + 972, 1017, 0, 0, 816, 816, 816, 816, 816, 816, + + 816, 816, 816, 816, 1041, 0, 0, 0, 816, 816, + 816, 816, 816, 816, 870, 870, 870, 870, 870, 0, + 891, 891, 891, 891, 891, 989, 989, 989, 989, 989, + 816, 816, 816, 816, 816, 816, 816, 819, 819, 819, + 819, 819, 819, 819, 819, 819, 819, 0, 870, 0, + 0, 819, 819, 819, 819, 819, 819, 914, 914, 914, + 914, 914, 1023, 0, 0, 955, 1023, 870, 1023, 0, + 955, 870, 891, 891, 819, 819, 819, 819, 819, 819, + 824, 824, 824, 824, 824, 1002, 1002, 1002, 1002, 1002, + 0, 0, 0, 0, 891, 0, 0, 824, 824, 824, + + 824, 824, 824, 824, 824, 824, 824, 0, 0, 0, + 914, 824, 824, 824, 824, 824, 824, 955, 1003, 1003, + 1003, 1003, 1003, 1013, 1013, 1013, 1013, 1013, 1018, 1018, + 1018, 1018, 1018, 0, 824, 824, 824, 824, 824, 824, + 825, 825, 825, 825, 825, 825, 825, 825, 825, 825, + 825, 825, 825, 825, 825, 825, 825, 825, 825, 825, + 825, 825, 825, 825, 825, 825, 825, 825, 825, 825, + 825, 825, 825, 825, 825, 825, 825, 825, 825, 825, + 825, 825, 825, 825, 825, 825, 825, 825, 825, 825, + 825, 825, 825, 825, 825, 825, 825, 825, 825, 825, + + 825, 825, 825, 825, 825, 825, 825, 825, 825, 825, + 825, 825, 825, 825, 825, 825, 825, 825, 825, 826, + 826, 826, 826, 826, 826, 826, 826, 826, 826, 0, + 0, 0, 0, 826, 826, 826, 826, 826, 826, 912, + 912, 912, 912, 912, 924, 924, 924, 924, 924, 1038, + 1088, 0, 0, 1038, 1088, 1038, 826, 826, 826, 826, + 826, 826, 840, 840, 840, 840, 840, 840, 840, 840, + 840, 840, 1088, 912, 0, 924, 840, 840, 840, 840, + 840, 840, 916, 916, 916, 916, 916, 0, 0, 966, + 0, 0, 912, 966, 0, 966, 912, 924, 924, 840, + + 840, 840, 840, 840, 840, 841, 841, 841, 841, 841, + 841, 841, 841, 841, 841, 0, 966, 916, 0, 841, + 841, 841, 841, 841, 841, 0, 915, 915, 915, 915, + 915, 0, 1019, 0, 0, 916, 0, 1019, 966, 1019, + 916, 0, 841, 841, 841, 841, 841, 841, 842, 842, + 842, 842, 842, 842, 842, 842, 842, 842, 0, 0, + 0, 0, 842, 842, 842, 842, 842, 842, 0, 915, + 917, 917, 917, 917, 917, 0, 0, 974, 941, 915, + 918, 918, 918, 918, 918, 842, 842, 842, 842, 842, + 842, 915, 919, 919, 919, 919, 919, 920, 920, 920, + + 920, 920, 0, 0, 921, 921, 921, 921, 921, 1046, + 0, 0, 0, 917, 0, 0, 922, 922, 922, 922, + 922, 917, 1042, 917, 941, 974, 1042, 918, 1042, 974, + 941, 1044, 0, 918, 0, 917, 1044, 0, 1044, 1046, + 0, 920, 921, 917, 919, 919, 941, 974, 0, 918, + 920, 925, 925, 925, 925, 925, 0, 921, 0, 922, + 0, 1046, 1046, 920, 922, 921, 919, 0, 0, 922, + 926, 926, 926, 926, 926, 0, 927, 927, 927, 927, + 927, 922, 1076, 0, 0, 0, 922, 923, 923, 923, + 923, 923, 0, 0, 0, 928, 928, 928, 928, 928, + + 1056, 0, 0, 0, 925, 1056, 0, 1056, 926, 929, + 929, 929, 929, 929, 931, 931, 931, 931, 931, 927, + 923, 1067, 0, 926, 927, 1076, 1067, 0, 1067, 927, + 0, 926, 928, 1071, 1076, 0, 923, 1071, 923, 1071, + 923, 927, 0, 923, 0, 0, 927, 1076, 928, 930, + 930, 930, 930, 930, 0, 928, 0, 1074, 923, 1085, + 923, 1074, 929, 1074, 1085, 0, 1085, 931, 938, 938, + 938, 938, 938, 961, 961, 961, 961, 961, 963, 963, + 963, 963, 963, 930, 0, 961, 0, 0, 0, 0, + 963, 1051, 1051, 1051, 1051, 1051, 0, 971, 971, 971, + + 971, 971, 930, 0, 0, 0, 930, 976, 976, 976, + 976, 976, 977, 977, 977, 977, 977, 938, 1087, 0, + 1037, 938, 1087, 1021, 1087, 1037, 961, 1037, 971, 0, + 0, 963, 1086, 1086, 1086, 1086, 1086, 0, 0, 938, + 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, + 971, 971, 1037, 0, 956, 956, 956, 956, 956, 956, + 976, 0, 0, 0, 0, 977, 978, 978, 978, 978, + 978, 1021, 0, 0, 1037, 1021, 0, 956, 956, 956, + 956, 956, 956, 959, 959, 959, 959, 959, 959, 959, + 959, 959, 959, 1021, 0, 0, 0, 959, 959, 959, + + 959, 959, 959, 983, 983, 983, 983, 983, 984, 984, + 984, 984, 984, 1094, 1094, 1094, 1094, 1094, 0, 978, + 959, 959, 959, 959, 959, 959, 960, 960, 960, 960, + 960, 960, 960, 960, 960, 960, 0, 0, 0, 0, + 960, 960, 960, 960, 960, 960, 1095, 0, 0, 0, + 0, 1095, 0, 1095, 0, 0, 983, 0, 0, 0, + 0, 984, 0, 960, 960, 960, 960, 960, 960, 962, + 962, 962, 962, 962, 962, 962, 962, 962, 962, 962, + 962, 962, 962, 962, 962, 962, 962, 962, 962, 962, + 962, 962, 962, 962, 962, 962, 962, 962, 962, 962, + + 962, 962, 962, 962, 962, 962, 962, 962, 962, 962, + 962, 962, 962, 962, 962, 962, 962, 962, 962, 962, + 962, 962, 962, 962, 962, 962, 962, 962, 962, 962, + 962, 962, 962, 962, 962, 962, 962, 962, 962, 962, + 962, 962, 962, 962, 962, 962, 962, 962, 964, 964, + 964, 964, 964, 964, 964, 964, 964, 964, 0, 0, + 0, 0, 964, 964, 964, 964, 964, 964, 982, 982, + 982, 982, 982, 985, 985, 985, 985, 985, 992, 992, + 992, 992, 992, 0, 0, 964, 964, 964, 964, 964, + 964, 993, 993, 993, 993, 993, 994, 994, 994, 994, + + 994, 0, 0, 0, 0, 982, 995, 995, 995, 995, + 995, 0, 992, 996, 996, 996, 996, 996, 0, 0, + 0, 982, 993, 0, 0, 0, 985, 0, 982, 0, + 994, 992, 0, 0, 0, 992, 997, 997, 997, 997, + 997, 0, 0, 0, 993, 993, 0, 0, 0, 994, + 0, 0, 0, 994, 998, 998, 998, 998, 998, 995, + 999, 999, 999, 999, 999, 0, 996, 1004, 1004, 1004, + 1004, 1004, 1005, 1005, 1005, 1005, 1005, 1006, 1006, 1006, + 1006, 1006, 1007, 1007, 1007, 1007, 1007, 0, 1089, 997, + 1008, 1008, 1008, 1008, 1008, 1009, 1009, 1009, 1009, 1009, + + 1010, 1010, 1010, 1010, 1010, 0, 0, 998, 1014, 1014, + 1014, 1014, 1014, 999, 1015, 1015, 1015, 1015, 1015, 1004, + 1004, 0, 0, 0, 0, 1005, 0, 0, 0, 0, + 1006, 0, 0, 0, 0, 1007, 1089, 0, 0, 0, + 1089, 1004, 1014, 1008, 0, 0, 0, 0, 1009, 0, + 0, 0, 0, 1010, 0, 0, 0, 0, 1089, 0, + 0, 1014, 0, 0, 0, 1014, 0, 1015, 1028, 1028, + 1028, 1028, 1028, 1028, 1028, 1028, 1028, 1028, 0, 0, + 0, 0, 1028, 1028, 1028, 1028, 1028, 1028, 1031, 1031, + 1031, 1031, 1031, 1048, 1048, 1048, 1048, 1048, 0, 0, + + 1031, 0, 0, 0, 0, 1028, 1028, 1028, 1028, 1028, + 1028, 1029, 1029, 1029, 1029, 1029, 1029, 1029, 1029, 1029, + 1029, 0, 0, 0, 0, 1029, 1029, 1029, 1029, 1029, + 1029, 1032, 1032, 1032, 1032, 1032, 1043, 1043, 1043, 1043, + 1043, 1031, 0, 1032, 0, 0, 1048, 0, 1029, 1029, + 1029, 1029, 1029, 1029, 1030, 1030, 1030, 1030, 1030, 1030, + 1030, 1030, 1030, 1030, 0, 0, 0, 0, 1030, 1030, + 1030, 1030, 1030, 1030, 1053, 1053, 1053, 1053, 1053, 0, + 1043, 0, 0, 0, 1032, 0, 0, 0, 0, 1043, + 0, 1030, 1030, 1030, 1030, 1030, 1030, 1033, 1033, 1033, + + 1033, 1033, 1043, 0, 0, 0, 0, 0, 0, 1033, + 0, 0, 0, 0, 1033, 1033, 1033, 1033, 1033, 1033, + 1033, 1033, 1033, 1033, 0, 0, 0, 1053, 1033, 1033, + 1033, 1033, 1033, 1033, 1052, 1052, 1052, 1052, 1052, 1054, + 1054, 1054, 1054, 1054, 0, 0, 0, 0, 0, 0, + 1033, 1033, 1033, 1033, 1033, 1033, 1033, 1035, 1035, 1035, + 1035, 1035, 1035, 1035, 1035, 1035, 1035, 0, 1052, 0, + 0, 1035, 1035, 1035, 1035, 1035, 1035, 1055, 1055, 1055, + 1055, 1055, 0, 0, 0, 0, 0, 1052, 0, 0, + 0, 1052, 1054, 0, 1035, 1035, 1035, 1035, 1035, 1035, + + 1064, 1064, 1064, 1064, 1064, 0, 0, 0, 0, 0, + 0, 0, 1064, 1072, 1072, 1072, 1072, 1072, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1055, 1061, 1061, 1061, 1061, 1061, 1061, 1061, 1061, 1061, + 1061, 0, 0, 0, 0, 1061, 1061, 1061, 1061, 1061, + 1061, 0, 0, 1064, 0, 0, 1073, 1073, 1073, 1073, + 1073, 0, 1072, 0, 0, 0, 1072, 0, 1061, 1061, + 1061, 1061, 1061, 1061, 1062, 1062, 1062, 1062, 1062, 1062, + 1062, 1062, 1062, 1062, 1072, 0, 0, 0, 1062, 1062, + 1062, 1062, 1062, 1062, 1078, 1078, 1078, 1078, 1078, 0, + + 0, 0, 0, 0, 0, 1073, 0, 0, 0, 1073, + 0, 1062, 1062, 1062, 1062, 1062, 1062, 1063, 1063, 1063, + 1063, 1063, 1063, 1063, 1063, 1063, 1063, 1073, 0, 0, + 0, 1063, 1063, 1063, 1063, 1063, 1063, 1101, 1101, 1101, + 1101, 1101, 0, 0, 0, 0, 0, 1078, 0, 1101, + 0, 0, 0, 0, 1063, 1063, 1063, 1063, 1063, 1063, + 1065, 1065, 1065, 1065, 1065, 1065, 1065, 1065, 1065, 1065, + 0, 0, 0, 0, 1065, 1065, 1065, 1065, 1065, 1065, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1101, 0, 0, 0, 0, 0, 0, 1065, 1065, 1065, + + 1065, 1065, 1065, 1066, 1066, 1066, 1066, 1066, 1066, 1066, + 1066, 1066, 1066, 0, 0, 0, 0, 1066, 1066, 1066, + 1066, 1066, 1066, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1066, 1066, 1066, 1066, 1066, 1066, 1080, 1080, 1080, 1080, + 1080, 1080, 1080, 1080, 1080, 1080, 0, 0, 0, 0, + 1080, 1080, 1080, 1080, 1080, 1080, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1080, 1080, 1080, 1080, 1080, 1080, 1081, + 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 0, + + 0, 0, 0, 1081, 1081, 1081, 1081, 1081, 1081, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 1081, 1081, 1081, 1081, + 1081, 1081, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, + 1082, 1082, 0, 0, 0, 0, 1082, 1082, 1082, 1082, + 1082, 1082, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 1082, + 1082, 1082, 1082, 1082, 1082, 1083, 1083, 1083, 1083, 1083, + 1083, 1083, 1083, 1083, 1083, 0, 0, 0, 0, 1083, + 1083, 1083, 1083, 1083, 1083, 0, 0, 0, 0, 0, + + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1083, 1083, 1083, 1083, 1083, 1083, 1084, 1084, + 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 0, 0, + 0, 0, 1084, 1084, 1084, 1084, 1084, 1084, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 1084, 1084, 1084, 1084, 1084, + 1084, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, + 1091, 0, 0, 0, 0, 1091, 1091, 1091, 1091, 1091, + 1091, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 1091, 1091, + + 1091, 1091, 1091, 1091, 1092, 1092, 1092, 1092, 1092, 1092, + 1092, 1092, 1092, 1092, 0, 0, 0, 0, 1092, 1092, + 1092, 1092, 1092, 1092, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1092, 1092, 1092, 1092, 1092, 1092, 1093, 1093, 1093, + 1093, 1093, 1093, 1093, 1093, 1093, 1093, 0, 0, 0, + 0, 1093, 1093, 1093, 1093, 1093, 1093, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1093, 1093, 1093, 1093, 1093, 1093, + 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, + + 0, 0, 0, 0, 1099, 1099, 1099, 1099, 1099, 1099, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 1099, 1099, 1099, + 1099, 1099, 1099, 1103, 1103, 0, 1103, 1103, 1103, 1103, + 1103, 1103, 1104, 1104, 1104, 1104, 1105, 1105, 0, 1105, + 1105, 1105, 1105, 1105, 1105, 1106, 0, 0, 1106, 1107, + 1107, 0, 1107, 1107, 1108, 1108, 0, 1108, 1108, 1108, + 1108, 1108, 1108, 1109, 1109, 1109, 1109, 1109, 1109, 1109, + 1109, 1109, 1110, 1110, 0, 1110, 1110, 1110, 1110, 1110, + 1110, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, + + 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1114, + 0, 1114, 1114, 1115, 1115, 0, 1115, 1115, 1115, 1115, + 1115, 1115, 1116, 1116, 1116, 1116, 1116, 1116, 1116, 1116, + 1116, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, + 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1119, + 1119, 0, 1119, 1119, 1119, 1119, 1119, 1119, 1120, 1120, + 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1121, 1121, 1121, + 1121, 1121, 1121, 1121, 1121, 1121, 1122, 1122, 1122, 1122, + 1122, 1122, 1122, 1122, 1122, 1123, 1123, 1123, 0, 1123, + 1123, 1123, 1123, 1124, 1124, 1124, 1124, 1124, 1124, 1124, + + 1124, 1124, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, + 1125, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, + 1127, 1127, 0, 1127, 1127, 1127, 1127, 1127, 1127, 1128, + 1128, 0, 1128, 1128, 1128, 1128, 1128, 1128, 1129, 1129, + 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1130, 1130, 1130, + 1130, 1130, 1130, 1130, 1130, 1130, 1131, 1131, 1131, 1131, + 1131, 1131, 1131, 1131, 1131, 1132, 1132, 1132, 1132, 1132, + 1132, 1132, 1132, 1132, 1133, 1133, 1133, 1133, 1133, 1133, + 1133, 1133, 1133, 1134, 1134, 1134, 1134, 1134, 1134, 1134, + 1134, 1134, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, + + 1135, 1136, 1136, 0, 0, 1136, 1136, 1136, 1136, 1102, + 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, + 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, + 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, + 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, + 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, + 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, + 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, + 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102 + } ; + +static yy_state_type yy_last_accepting_state; +static char *yy_last_accepting_cpos; + +extern int yy_flex_debug; +int yy_flex_debug = 0; + +/* The intent behind this definition is that it'll catch + * any uses of REJECT which flex missed. + */ +#define REJECT reject_used_but_not_detected +#define yymore() yymore_used_but_not_detected +#define YY_MORE_ADJ 0 +#define YY_RESTORE_YY_MORE_OFFSET +char *yytext; +#line 1 "css.l" + +#line 13 "css.l" +/* Lex source for CSS tokenizing. + Taken from http://www.w3.org/TR/CSS21/grammar.html#q2 + Copyright (C) 2006, 2009-2011, 2015, 2018-2020 Free Software + Foundation, Inc. + +This file is part of GNU Wget. + +GNU Wget is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 3 of the License, or (at +your option) any later version. + +GNU Wget 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 Wget. If not, see . + +Additional permission under GNU GPL version 3 section 7 + +If you modify this program, or any covered work, by linking or +combining it with the OpenSSL project's OpenSSL library (or a +modified version of that library), containing parts covered by the +terms of the OpenSSL or SSLeay licenses, the Free Software Foundation +grants you additional permission to convey the resulting work. +Corresponding Source for a non-source form of such a combination +shall include the source code for the parts of OpenSSL used as well +as that of the covered work. */ + +#define YY_NO_INPUT + +#include "css-tokens.h" + +#if defined __clang__ || __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5) + #pragma GCC diagnostic ignored "-Wunknown-pragmas" // clang mourns about the next one + #pragma GCC diagnostic ignored "-Wunused-function" + #pragma GCC diagnostic ignored "-Wunused-macros" + #pragma GCC diagnostic ignored "-Wunused-parameter" + #pragma GCC diagnostic ignored "-Wsign-compare" + #pragma GCC diagnostic ignored "-Wswitch-default" + #pragma GCC diagnostic ignored "-Wunreachable-code" // clang + #pragma clang diagnostic ignored "-Wshorten-64-to-32" + #ifndef __clang__ + #pragma GCC diagnostic ignored "-Wsuggest-attribute=pure" + #endif +#endif + +#line 2452 "css.c" +#line 2453 "css.c" + +#define INITIAL 0 + +#ifndef YY_NO_UNISTD_H +/* Special case for "unistd.h", since it is non-ANSI. We include it way + * down here because we want the user's section 1 to have been scanned first. + * The user has a chance to override it with an option. + */ +#include +#endif + +#ifndef YY_EXTRA_TYPE +#define YY_EXTRA_TYPE void * +#endif + +static int yy_init_globals ( void ); + +/* Accessor methods to globals. + These are made visible to non-reentrant scanners for convenience. */ + +int yylex_destroy ( void ); + +int yyget_debug ( void ); + +void yyset_debug ( int debug_flag ); + +YY_EXTRA_TYPE yyget_extra ( void ); + +void yyset_extra ( YY_EXTRA_TYPE user_defined ); + +FILE *yyget_in ( void ); + +void yyset_in ( FILE * _in_str ); + +FILE *yyget_out ( void ); + +void yyset_out ( FILE * _out_str ); + + int yyget_leng ( void ); + +char *yyget_text ( void ); + +int yyget_lineno ( void ); + +void yyset_lineno ( int _line_number ); + +/* Macros after this point can all be overridden by user definitions in + * section 1. + */ + +#ifndef YY_SKIP_YYWRAP +#ifdef __cplusplus +extern "C" int yywrap ( void ); +#else +extern int yywrap ( void ); +#endif +#endif + +#ifndef YY_NO_UNPUT + +#endif + +#ifndef yytext_ptr +static void yy_flex_strncpy ( char *, const char *, int ); +#endif + +#ifdef YY_NEED_STRLEN +static int yy_flex_strlen ( const char * ); +#endif + +#ifndef YY_NO_INPUT +#ifdef __cplusplus +static int yyinput ( void ); +#else +static int input ( void ); +#endif + +#endif + +/* Amount of stuff to slurp up with each read. */ +#ifndef YY_READ_BUF_SIZE +#ifdef __ia64__ +/* On IA-64, the buffer size is 16k, not 8k */ +#define YY_READ_BUF_SIZE 16384 +#else +#define YY_READ_BUF_SIZE 8192 +#endif /* __ia64__ */ +#endif + +/* Copy whatever the last rule matched to the standard output. */ +#ifndef ECHO +/* This used to be an fputs(), but since the string might contain NUL's, + * we now use fwrite(). + */ +#define ECHO do { if (fwrite( yytext, (size_t) yyleng, 1, yyout )) {} } while (0) +#endif + +/* Gets input and stuffs it into "buf". number of characters read, or YY_NULL, + * is returned in "result". + */ +#ifndef YY_INPUT +#define YY_INPUT(buf,result,max_size) \ + if ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \ + { \ + int c = '*'; \ + int n; \ + for ( n = 0; n < max_size && \ + (c = getc( yyin )) != EOF && c != '\n'; ++n ) \ + buf[n] = (char) c; \ + if ( c == '\n' ) \ + buf[n++] = (char) c; \ + if ( c == EOF && ferror( yyin ) ) \ + YY_FATAL_ERROR( "input in flex scanner failed" ); \ + result = n; \ + } \ + else \ + { \ + errno=0; \ + while ( (result = (int) fread(buf, 1, (yy_size_t) max_size, yyin)) == 0 && ferror(yyin)) \ + { \ + if( errno != EINTR) \ + { \ + YY_FATAL_ERROR( "input in flex scanner failed" ); \ + break; \ + } \ + errno=0; \ + clearerr(yyin); \ + } \ + }\ +\ + +#endif + +/* No semi-colon after return; correct usage is to write "yyterminate();" - + * we don't want an extra ';' after the "return" because that will cause + * some compilers to complain about unreachable statements. + */ +#ifndef yyterminate +#define yyterminate() return YY_NULL +#endif + +/* Number of entries by which start-condition stack grows. */ +#ifndef YY_START_STACK_INCR +#define YY_START_STACK_INCR 25 +#endif + +/* Report a fatal error. */ +#ifndef YY_FATAL_ERROR +#define YY_FATAL_ERROR(msg) yy_fatal_error( msg ) +#endif + +/* end tables serialization structures and prototypes */ + +/* Default declaration of generated scanner - a define so the user can + * easily add parameters. + */ +#ifndef YY_DECL +#define YY_DECL_IS_OURS 1 + +extern int yylex (void); + +#define YY_DECL int yylex (void) +#endif /* !YY_DECL */ + +/* Code executed at the beginning of each rule, after yytext and yyleng + * have been set up. + */ +#ifndef YY_USER_ACTION +#define YY_USER_ACTION +#endif + +/* Code executed at the end of each rule. */ +#ifndef YY_BREAK +#define YY_BREAK /*LINTED*/break; +#endif + +#define YY_RULE_SETUP \ + YY_USER_ACTION + +/** The main scanner function which does all the work. + */ +YY_DECL +{ + yy_state_type yy_current_state; + char *yy_cp, *yy_bp; + int yy_act; + + if ( !(yy_init) ) + { + (yy_init) = 1; + +#ifdef YY_USER_INIT + YY_USER_INIT; +#endif + + if ( ! (yy_start) ) + (yy_start) = 1; /* first start state */ + + if ( ! yyin ) + yyin = stdin; + + if ( ! yyout ) + yyout = stdout; + + if ( ! YY_CURRENT_BUFFER ) { + yyensure_buffer_stack (); + YY_CURRENT_BUFFER_LVALUE = + yy_create_buffer( yyin, YY_BUF_SIZE ); + } + + yy_load_buffer_state( ); + } + + { +#line 112 "css.l" + + +#line 2671 "css.c" + + while ( /*CONSTCOND*/1 ) /* loops until end-of-file is reached */ + { + yy_cp = (yy_c_buf_p); + + /* Support of yytext. */ + *yy_cp = (yy_hold_char); + + /* yy_bp points to the position in yy_ch_buf of the start of + * the current run. + */ + yy_bp = yy_cp; + + yy_current_state = (yy_start); +yy_match: + do + { + YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)] ; + if ( yy_accept[yy_current_state] ) + { + (yy_last_accepting_state) = yy_current_state; + (yy_last_accepting_cpos) = yy_cp; + } + while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) + { + yy_current_state = (int) yy_def[yy_current_state]; + if ( yy_current_state >= 1103 ) + yy_c = yy_meta[yy_c]; + } + yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c]; + ++yy_cp; + } + while ( yy_current_state != 1102 ); + yy_cp = (yy_last_accepting_cpos); + yy_current_state = (yy_last_accepting_state); + +yy_find_action: + yy_act = yy_accept[yy_current_state]; + + YY_DO_BEFORE_ACTION; + +do_action: /* This label is used only to access EOF actions. */ + + switch ( yy_act ) + { /* beginning of action switch */ + case 0: /* must back up */ + /* undo the effects of YY_DO_BEFORE_ACTION */ + *yy_cp = (yy_hold_char); + yy_cp = (yy_last_accepting_cpos); + yy_current_state = (yy_last_accepting_state); + goto yy_find_action; + +case 1: +/* rule 1 can match eol */ +YY_RULE_SETUP +#line 114 "css.l" +{return S;} + YY_BREAK +case 2: +/* rule 2 can match eol */ +YY_RULE_SETUP +#line 116 "css.l" +{return COMMENT;} + YY_BREAK +case 3: +/* rule 3 can match eol */ +YY_RULE_SETUP +#line 117 "css.l" +/* ignore comments */ + YY_BREAK +case 4: +/* rule 4 can match eol */ +YY_RULE_SETUP +#line 118 "css.l" +/* unclosed comment at EOF */ + YY_BREAK +case 5: +YY_RULE_SETUP +#line 120 "css.l" +{return CDO;} + YY_BREAK +case 6: +YY_RULE_SETUP +#line 121 "css.l" +{return CDC;} + YY_BREAK +case 7: +YY_RULE_SETUP +#line 122 "css.l" +{return INCLUDES;} + YY_BREAK +case 8: +YY_RULE_SETUP +#line 123 "css.l" +{return DASHMATCH;} + YY_BREAK +case 9: +/* rule 9 can match eol */ +YY_RULE_SETUP +#line 125 "css.l" +{return STRING;} + YY_BREAK +case 10: +/* rule 10 can match eol */ +YY_RULE_SETUP +#line 126 "css.l" +{return BAD_STRING;} + YY_BREAK +case 11: +/* rule 11 can match eol */ +YY_RULE_SETUP +#line 128 "css.l" +{return IDENT;} + YY_BREAK +case 12: +/* rule 12 can match eol */ +YY_RULE_SETUP +#line 130 "css.l" +{return HASH;} + YY_BREAK +case 13: +/* rule 13 can match eol */ +YY_RULE_SETUP +#line 132 "css.l" +{return IMPORT_SYM;} + YY_BREAK +case 14: +/* rule 14 can match eol */ +YY_RULE_SETUP +#line 133 "css.l" +{return PAGE_SYM;} + YY_BREAK +case 15: +/* rule 15 can match eol */ +YY_RULE_SETUP +#line 134 "css.l" +{return MEDIA_SYM;} + YY_BREAK +case 16: +YY_RULE_SETUP +#line 135 "css.l" +{return CHARSET_SYM;} + YY_BREAK +case 17: +/* rule 17 can match eol */ +YY_RULE_SETUP +#line 137 "css.l" +{return IMPORTANT_SYM;} + YY_BREAK +case 18: +/* rule 18 can match eol */ +YY_RULE_SETUP +#line 139 "css.l" +{return EMS;} + YY_BREAK +case 19: +/* rule 19 can match eol */ +YY_RULE_SETUP +#line 140 "css.l" +{return EXS;} + YY_BREAK +case 20: +/* rule 20 can match eol */ +YY_RULE_SETUP +#line 141 "css.l" +{return LENGTH;} + YY_BREAK +case 21: +/* rule 21 can match eol */ +YY_RULE_SETUP +#line 142 "css.l" +{return LENGTH;} + YY_BREAK +case 22: +/* rule 22 can match eol */ +YY_RULE_SETUP +#line 143 "css.l" +{return LENGTH;} + YY_BREAK +case 23: +/* rule 23 can match eol */ +YY_RULE_SETUP +#line 144 "css.l" +{return LENGTH;} + YY_BREAK +case 24: +/* rule 24 can match eol */ +YY_RULE_SETUP +#line 145 "css.l" +{return LENGTH;} + YY_BREAK +case 25: +/* rule 25 can match eol */ +YY_RULE_SETUP +#line 146 "css.l" +{return LENGTH;} + YY_BREAK +case 26: +/* rule 26 can match eol */ +YY_RULE_SETUP +#line 147 "css.l" +{return ANGLE;} + YY_BREAK +case 27: +/* rule 27 can match eol */ +YY_RULE_SETUP +#line 148 "css.l" +{return ANGLE;} + YY_BREAK +case 28: +/* rule 28 can match eol */ +YY_RULE_SETUP +#line 149 "css.l" +{return ANGLE;} + YY_BREAK +case 29: +/* rule 29 can match eol */ +YY_RULE_SETUP +#line 150 "css.l" +{return TIME;} + YY_BREAK +case 30: +/* rule 30 can match eol */ +YY_RULE_SETUP +#line 151 "css.l" +{return TIME;} + YY_BREAK +case 31: +/* rule 31 can match eol */ +YY_RULE_SETUP +#line 152 "css.l" +{return FREQ;} + YY_BREAK +case 32: +/* rule 32 can match eol */ +YY_RULE_SETUP +#line 153 "css.l" +{return FREQ;} + YY_BREAK +case 33: +/* rule 33 can match eol */ +YY_RULE_SETUP +#line 154 "css.l" +{return DIMENSION;} + YY_BREAK +case 34: +YY_RULE_SETUP +#line 156 "css.l" +{return PERCENTAGE;} + YY_BREAK +case 35: +YY_RULE_SETUP +#line 157 "css.l" +{return NUMBER;} + YY_BREAK +case 36: +/* rule 36 can match eol */ +YY_RULE_SETUP +#line 159 "css.l" +{return URI;} + YY_BREAK +case 37: +/* rule 37 can match eol */ +YY_RULE_SETUP +#line 160 "css.l" +{return URI;} + YY_BREAK +case 38: +/* rule 38 can match eol */ +YY_RULE_SETUP +#line 161 "css.l" +{return BAD_URI;} + YY_BREAK +case 39: +/* rule 39 can match eol */ +YY_RULE_SETUP +#line 163 "css.l" +{return FUNCTION;} + YY_BREAK +case 40: +YY_RULE_SETUP +#line 165 "css.l" +{return *yytext;} + YY_BREAK +case 41: +YY_RULE_SETUP +#line 167 "css.l" +ECHO; + YY_BREAK +#line 2961 "css.c" +case YY_STATE_EOF(INITIAL): + yyterminate(); + + case YY_END_OF_BUFFER: + { + /* Amount of text matched not including the EOB char. */ + int yy_amount_of_matched_text = (int) (yy_cp - (yytext_ptr)) - 1; + + /* Undo the effects of YY_DO_BEFORE_ACTION. */ + *yy_cp = (yy_hold_char); + YY_RESTORE_YY_MORE_OFFSET + + if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_NEW ) + { + /* We're scanning a new file or input source. It's + * possible that this happened because the user + * just pointed yyin at a new source and called + * yylex(). If so, then we have to assure + * consistency between YY_CURRENT_BUFFER and our + * globals. Here is the right place to do so, because + * this is the first action (other than possibly a + * back-up) that will match for the new input source. + */ + (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; + YY_CURRENT_BUFFER_LVALUE->yy_input_file = yyin; + YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_NORMAL; + } + + /* Note that here we test for yy_c_buf_p "<=" to the position + * of the first EOB in the buffer, since yy_c_buf_p will + * already have been incremented past the NUL character + * (since all states make transitions on EOB to the + * end-of-buffer state). Contrast this with the test + * in input(). + */ + if ( (yy_c_buf_p) <= &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] ) + { /* This was really a NUL. */ + yy_state_type yy_next_state; + + (yy_c_buf_p) = (yytext_ptr) + yy_amount_of_matched_text; + + yy_current_state = yy_get_previous_state( ); + + /* Okay, we're now positioned to make the NUL + * transition. We couldn't have + * yy_get_previous_state() go ahead and do it + * for us because it doesn't know how to deal + * with the possibility of jamming (and we don't + * want to build jamming into it because then it + * will run more slowly). + */ + + yy_next_state = yy_try_NUL_trans( yy_current_state ); + + yy_bp = (yytext_ptr) + YY_MORE_ADJ; + + if ( yy_next_state ) + { + /* Consume the NUL. */ + yy_cp = ++(yy_c_buf_p); + yy_current_state = yy_next_state; + goto yy_match; + } + + else + { + yy_cp = (yy_last_accepting_cpos); + yy_current_state = (yy_last_accepting_state); + goto yy_find_action; + } + } + + else switch ( yy_get_next_buffer( ) ) + { + case EOB_ACT_END_OF_FILE: + { + (yy_did_buffer_switch_on_eof) = 0; + + if ( yywrap( ) ) + { + /* Note: because we've taken care in + * yy_get_next_buffer() to have set up + * yytext, we can now set up + * yy_c_buf_p so that if some total + * hoser (like flex itself) wants to + * call the scanner after we return the + * YY_NULL, it'll still work - another + * YY_NULL will get returned. + */ + (yy_c_buf_p) = (yytext_ptr) + YY_MORE_ADJ; + + yy_act = YY_STATE_EOF(YY_START); + goto do_action; + } + + else + { + if ( ! (yy_did_buffer_switch_on_eof) ) + YY_NEW_FILE; + } + break; + } + + case EOB_ACT_CONTINUE_SCAN: + (yy_c_buf_p) = + (yytext_ptr) + yy_amount_of_matched_text; + + yy_current_state = yy_get_previous_state( ); + + yy_cp = (yy_c_buf_p); + yy_bp = (yytext_ptr) + YY_MORE_ADJ; + goto yy_match; + + case EOB_ACT_LAST_MATCH: + (yy_c_buf_p) = + &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)]; + + yy_current_state = yy_get_previous_state( ); + + yy_cp = (yy_c_buf_p); + yy_bp = (yytext_ptr) + YY_MORE_ADJ; + goto yy_find_action; + } + break; + } + + default: + YY_FATAL_ERROR( + "fatal flex scanner internal error--no action found" ); + } /* end of action switch */ + } /* end of scanning one token */ + } /* end of user's declarations */ +} /* end of yylex */ + +/* yy_get_next_buffer - try to read in a new buffer + * + * Returns a code representing an action: + * EOB_ACT_LAST_MATCH - + * EOB_ACT_CONTINUE_SCAN - continue scanning from current position + * EOB_ACT_END_OF_FILE - end of file + */ +static int yy_get_next_buffer (void) +{ + char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf; + char *source = (yytext_ptr); + int number_to_move, i; + int ret_val; + + if ( (yy_c_buf_p) > &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] ) + YY_FATAL_ERROR( + "fatal flex scanner internal error--end of buffer missed" ); + + if ( YY_CURRENT_BUFFER_LVALUE->yy_fill_buffer == 0 ) + { /* Don't try to fill the buffer, so this is an EOF. */ + if ( (yy_c_buf_p) - (yytext_ptr) - YY_MORE_ADJ == 1 ) + { + /* We matched a single character, the EOB, so + * treat this as a final EOF. + */ + return EOB_ACT_END_OF_FILE; + } + + else + { + /* We matched some text prior to the EOB, first + * process it. + */ + return EOB_ACT_LAST_MATCH; + } + } + + /* Try to read more data. */ + + /* First move last chars to start of buffer. */ + number_to_move = (int) ((yy_c_buf_p) - (yytext_ptr) - 1); + + for ( i = 0; i < number_to_move; ++i ) + *(dest++) = *(source++); + + if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_EOF_PENDING ) + /* don't do the read, it's not guaranteed to return an EOF, + * just force an EOF + */ + YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars) = 0; + + else + { + int num_to_read = + YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1; + + while ( num_to_read <= 0 ) + { /* Not enough room in the buffer - grow it. */ + + /* just a shorter name for the current buffer */ + YY_BUFFER_STATE b = YY_CURRENT_BUFFER_LVALUE; + + int yy_c_buf_p_offset = + (int) ((yy_c_buf_p) - b->yy_ch_buf); + + if ( b->yy_is_our_buffer ) + { + int new_size = b->yy_buf_size * 2; + + if ( new_size <= 0 ) + b->yy_buf_size += b->yy_buf_size / 8; + else + b->yy_buf_size *= 2; + + b->yy_ch_buf = (char *) + /* Include room in for 2 EOB chars. */ + yyrealloc( (void *) b->yy_ch_buf, + (yy_size_t) (b->yy_buf_size + 2) ); + } + else + /* Can't grow it, we don't own it. */ + b->yy_ch_buf = NULL; + + if ( ! b->yy_ch_buf ) + YY_FATAL_ERROR( + "fatal error - scanner input buffer overflow" ); + + (yy_c_buf_p) = &b->yy_ch_buf[yy_c_buf_p_offset]; + + num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size - + number_to_move - 1; + + } + + if ( num_to_read > YY_READ_BUF_SIZE ) + num_to_read = YY_READ_BUF_SIZE; + + /* Read in more data. */ + YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]), + (yy_n_chars), num_to_read ); + + YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); + } + + if ( (yy_n_chars) == 0 ) + { + if ( number_to_move == YY_MORE_ADJ ) + { + ret_val = EOB_ACT_END_OF_FILE; + yyrestart( yyin ); + } + + else + { + ret_val = EOB_ACT_LAST_MATCH; + YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = + YY_BUFFER_EOF_PENDING; + } + } + + else + ret_val = EOB_ACT_CONTINUE_SCAN; + + if (((yy_n_chars) + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) { + /* Extend the array by 50%, plus the number we really need. */ + int new_size = (yy_n_chars) + number_to_move + ((yy_n_chars) >> 1); + YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) yyrealloc( + (void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf, (yy_size_t) new_size ); + if ( ! YY_CURRENT_BUFFER_LVALUE->yy_ch_buf ) + YY_FATAL_ERROR( "out of dynamic memory in yy_get_next_buffer()" ); + /* "- 2" to take care of EOB's */ + YY_CURRENT_BUFFER_LVALUE->yy_buf_size = (int) (new_size - 2); + } + + (yy_n_chars) += number_to_move; + YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] = YY_END_OF_BUFFER_CHAR; + YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] = YY_END_OF_BUFFER_CHAR; + + (yytext_ptr) = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[0]; + + return ret_val; +} + +/* yy_get_previous_state - get the state just before the EOB char was reached */ + + static yy_state_type yy_get_previous_state (void) +{ + yy_state_type yy_current_state; + char *yy_cp; + + yy_current_state = (yy_start); + + for ( yy_cp = (yytext_ptr) + YY_MORE_ADJ; yy_cp < (yy_c_buf_p); ++yy_cp ) + { + YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1); + if ( yy_accept[yy_current_state] ) + { + (yy_last_accepting_state) = yy_current_state; + (yy_last_accepting_cpos) = yy_cp; + } + while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) + { + yy_current_state = (int) yy_def[yy_current_state]; + if ( yy_current_state >= 1103 ) + yy_c = yy_meta[yy_c]; + } + yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c]; + } + + return yy_current_state; +} + +/* yy_try_NUL_trans - try to make a transition on the NUL character + * + * synopsis + * next_state = yy_try_NUL_trans( current_state ); + */ + static yy_state_type yy_try_NUL_trans (yy_state_type yy_current_state ) +{ + int yy_is_jam; + char *yy_cp = (yy_c_buf_p); + + YY_CHAR yy_c = 1; + if ( yy_accept[yy_current_state] ) + { + (yy_last_accepting_state) = yy_current_state; + (yy_last_accepting_cpos) = yy_cp; + } + while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) + { + yy_current_state = (int) yy_def[yy_current_state]; + if ( yy_current_state >= 1103 ) + yy_c = yy_meta[yy_c]; + } + yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c]; + yy_is_jam = (yy_current_state == 1102); + + return yy_is_jam ? 0 : yy_current_state; +} + +#ifndef YY_NO_UNPUT + +#endif + +#ifndef YY_NO_INPUT +#ifdef __cplusplus + static int yyinput (void) +#else + static int input (void) +#endif + +{ + int c; + + *(yy_c_buf_p) = (yy_hold_char); + + if ( *(yy_c_buf_p) == YY_END_OF_BUFFER_CHAR ) + { + /* yy_c_buf_p now points to the character we want to return. + * If this occurs *before* the EOB characters, then it's a + * valid NUL; if not, then we've hit the end of the buffer. + */ + if ( (yy_c_buf_p) < &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] ) + /* This was really a NUL. */ + *(yy_c_buf_p) = '\0'; + + else + { /* need more input */ + int offset = (int) ((yy_c_buf_p) - (yytext_ptr)); + ++(yy_c_buf_p); + + switch ( yy_get_next_buffer( ) ) + { + case EOB_ACT_LAST_MATCH: + /* This happens because yy_g_n_b() + * sees that we've accumulated a + * token and flags that we need to + * try matching the token before + * proceeding. But for input(), + * there's no matching to consider. + * So convert the EOB_ACT_LAST_MATCH + * to EOB_ACT_END_OF_FILE. + */ + + /* Reset buffer status. */ + yyrestart( yyin ); + + /*FALLTHROUGH*/ + + case EOB_ACT_END_OF_FILE: + { + if ( yywrap( ) ) + return 0; + + if ( ! (yy_did_buffer_switch_on_eof) ) + YY_NEW_FILE; +#ifdef __cplusplus + return yyinput(); +#else + return input(); +#endif + } + + case EOB_ACT_CONTINUE_SCAN: + (yy_c_buf_p) = (yytext_ptr) + offset; + break; + } + } + } + + c = *(unsigned char *) (yy_c_buf_p); /* cast for 8-bit char's */ + *(yy_c_buf_p) = '\0'; /* preserve yytext */ + (yy_hold_char) = *++(yy_c_buf_p); + + return c; +} +#endif /* ifndef YY_NO_INPUT */ + +/** Immediately switch to a different input stream. + * @param input_file A readable stream. + * + * @note This function does not reset the start condition to @c INITIAL . + */ + void yyrestart (FILE * input_file ) +{ + + if ( ! YY_CURRENT_BUFFER ){ + yyensure_buffer_stack (); + YY_CURRENT_BUFFER_LVALUE = + yy_create_buffer( yyin, YY_BUF_SIZE ); + } + + yy_init_buffer( YY_CURRENT_BUFFER, input_file ); + yy_load_buffer_state( ); +} + +/** Switch to a different input buffer. + * @param new_buffer The new input buffer. + * + */ + void yy_switch_to_buffer (YY_BUFFER_STATE new_buffer ) +{ + + /* TODO. We should be able to replace this entire function body + * with + * yypop_buffer_state(); + * yypush_buffer_state(new_buffer); + */ + yyensure_buffer_stack (); + if ( YY_CURRENT_BUFFER == new_buffer ) + return; + + if ( YY_CURRENT_BUFFER ) + { + /* Flush out information for old buffer. */ + *(yy_c_buf_p) = (yy_hold_char); + YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p); + YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); + } + + YY_CURRENT_BUFFER_LVALUE = new_buffer; + yy_load_buffer_state( ); + + /* We don't actually know whether we did this switch during + * EOF (yywrap()) processing, but the only time this flag + * is looked at is after yywrap() is called, so it's safe + * to go ahead and always set it. + */ + (yy_did_buffer_switch_on_eof) = 1; +} + +static void yy_load_buffer_state (void) +{ + (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; + (yytext_ptr) = (yy_c_buf_p) = YY_CURRENT_BUFFER_LVALUE->yy_buf_pos; + yyin = YY_CURRENT_BUFFER_LVALUE->yy_input_file; + (yy_hold_char) = *(yy_c_buf_p); +} + +/** Allocate and initialize an input buffer state. + * @param file A readable stream. + * @param size The character buffer size in bytes. When in doubt, use @c YY_BUF_SIZE. + * + * @return the allocated buffer state. + */ + YY_BUFFER_STATE yy_create_buffer (FILE * file, int size ) +{ + YY_BUFFER_STATE b; + + b = (YY_BUFFER_STATE) yyalloc( sizeof( struct yy_buffer_state ) ); + if ( ! b ) + YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); + + b->yy_buf_size = size; + + /* yy_ch_buf has to be 2 characters longer than the size given because + * we need to put in 2 end-of-buffer characters. + */ + b->yy_ch_buf = (char *) yyalloc( (yy_size_t) (b->yy_buf_size + 2) ); + if ( ! b->yy_ch_buf ) + YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); + + b->yy_is_our_buffer = 1; + + yy_init_buffer( b, file ); + + return b; +} + +/** Destroy the buffer. + * @param b a buffer created with yy_create_buffer() + * + */ + void yy_delete_buffer (YY_BUFFER_STATE b ) +{ + + if ( ! b ) + return; + + if ( b == YY_CURRENT_BUFFER ) /* Not sure if we should pop here. */ + YY_CURRENT_BUFFER_LVALUE = (YY_BUFFER_STATE) 0; + + if ( b->yy_is_our_buffer ) + yyfree( (void *) b->yy_ch_buf ); + + yyfree( (void *) b ); +} + +/* Initializes or reinitializes a buffer. + * This function is sometimes called more than once on the same buffer, + * such as during a yyrestart() or at EOF. + */ + static void yy_init_buffer (YY_BUFFER_STATE b, FILE * file ) + +{ + int oerrno = errno; + + yy_flush_buffer( b ); + + b->yy_input_file = file; + b->yy_fill_buffer = 1; + + /* If b is the current buffer, then yy_init_buffer was _probably_ + * called from yyrestart() or through yy_get_next_buffer. + * In that case, we don't want to reset the lineno or column. + */ + if (b != YY_CURRENT_BUFFER){ + b->yy_bs_lineno = 1; + b->yy_bs_column = 0; + } + + b->yy_is_interactive = 0; + + errno = oerrno; +} + +/** Discard all buffered characters. On the next scan, YY_INPUT will be called. + * @param b the buffer state to be flushed, usually @c YY_CURRENT_BUFFER. + * + */ + void yy_flush_buffer (YY_BUFFER_STATE b ) +{ + if ( ! b ) + return; + + b->yy_n_chars = 0; + + /* We always need two end-of-buffer characters. The first causes + * a transition to the end-of-buffer state. The second causes + * a jam in that state. + */ + b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR; + b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR; + + b->yy_buf_pos = &b->yy_ch_buf[0]; + + b->yy_at_bol = 1; + b->yy_buffer_status = YY_BUFFER_NEW; + + if ( b == YY_CURRENT_BUFFER ) + yy_load_buffer_state( ); +} + +/** Pushes the new state onto the stack. The new state becomes + * the current state. This function will allocate the stack + * if necessary. + * @param new_buffer The new state. + * + */ +void yypush_buffer_state (YY_BUFFER_STATE new_buffer ) +{ + if (new_buffer == NULL) + return; + + yyensure_buffer_stack(); + + /* This block is copied from yy_switch_to_buffer. */ + if ( YY_CURRENT_BUFFER ) + { + /* Flush out information for old buffer. */ + *(yy_c_buf_p) = (yy_hold_char); + YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p); + YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); + } + + /* Only push if top exists. Otherwise, replace top. */ + if (YY_CURRENT_BUFFER) + (yy_buffer_stack_top)++; + YY_CURRENT_BUFFER_LVALUE = new_buffer; + + /* copied from yy_switch_to_buffer. */ + yy_load_buffer_state( ); + (yy_did_buffer_switch_on_eof) = 1; +} + +/** Removes and deletes the top of the stack, if present. + * The next element becomes the new top. + * + */ +void yypop_buffer_state (void) +{ + if (!YY_CURRENT_BUFFER) + return; + + yy_delete_buffer(YY_CURRENT_BUFFER ); + YY_CURRENT_BUFFER_LVALUE = NULL; + if ((yy_buffer_stack_top) > 0) + --(yy_buffer_stack_top); + + if (YY_CURRENT_BUFFER) { + yy_load_buffer_state( ); + (yy_did_buffer_switch_on_eof) = 1; + } +} + +/* Allocates the stack if it does not exist. + * Guarantees space for at least one push. + */ +static void yyensure_buffer_stack (void) +{ + yy_size_t num_to_alloc; + + if (!(yy_buffer_stack)) { + + /* First allocation is just for 2 elements, since we don't know if this + * scanner will even need a stack. We use 2 instead of 1 to avoid an + * immediate realloc on the next call. + */ + num_to_alloc = 1; /* After all that talk, this was set to 1 anyways... */ + (yy_buffer_stack) = (struct yy_buffer_state**)yyalloc + (num_to_alloc * sizeof(struct yy_buffer_state*) + ); + if ( ! (yy_buffer_stack) ) + YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" ); + + memset((yy_buffer_stack), 0, num_to_alloc * sizeof(struct yy_buffer_state*)); + + (yy_buffer_stack_max) = num_to_alloc; + (yy_buffer_stack_top) = 0; + return; + } + + if ((yy_buffer_stack_top) >= ((yy_buffer_stack_max)) - 1){ + + /* Increase the buffer to prepare for a possible push. */ + yy_size_t grow_size = 8 /* arbitrary grow size */; + + num_to_alloc = (yy_buffer_stack_max) + grow_size; + (yy_buffer_stack) = (struct yy_buffer_state**)yyrealloc + ((yy_buffer_stack), + num_to_alloc * sizeof(struct yy_buffer_state*) + ); + if ( ! (yy_buffer_stack) ) + YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" ); + + /* zero only the new slots.*/ + memset((yy_buffer_stack) + (yy_buffer_stack_max), 0, grow_size * sizeof(struct yy_buffer_state*)); + (yy_buffer_stack_max) = num_to_alloc; + } +} + +/** Setup the input buffer state to scan directly from a user-specified character buffer. + * @param base the character buffer + * @param size the size in bytes of the character buffer + * + * @return the newly allocated buffer state object. + */ +YY_BUFFER_STATE yy_scan_buffer (char * base, yy_size_t size ) +{ + YY_BUFFER_STATE b; + + if ( size < 2 || + base[size-2] != YY_END_OF_BUFFER_CHAR || + base[size-1] != YY_END_OF_BUFFER_CHAR ) + /* They forgot to leave room for the EOB's. */ + return NULL; + + b = (YY_BUFFER_STATE) yyalloc( sizeof( struct yy_buffer_state ) ); + if ( ! b ) + YY_FATAL_ERROR( "out of dynamic memory in yy_scan_buffer()" ); + + b->yy_buf_size = (int) (size - 2); /* "- 2" to take care of EOB's */ + b->yy_buf_pos = b->yy_ch_buf = base; + b->yy_is_our_buffer = 0; + b->yy_input_file = NULL; + b->yy_n_chars = b->yy_buf_size; + b->yy_is_interactive = 0; + b->yy_at_bol = 1; + b->yy_fill_buffer = 0; + b->yy_buffer_status = YY_BUFFER_NEW; + + yy_switch_to_buffer( b ); + + return b; +} + +/** Setup the input buffer state to scan a string. The next call to yylex() will + * scan from a @e copy of @a str. + * @param yystr a NUL-terminated string to scan + * + * @return the newly allocated buffer state object. + * @note If you want to scan bytes that may contain NUL values, then use + * yy_scan_bytes() instead. + */ +YY_BUFFER_STATE yy_scan_string (const char * yystr ) +{ + + return yy_scan_bytes( yystr, (int) strlen(yystr) ); +} + +/** Setup the input buffer state to scan the given bytes. The next call to yylex() will + * scan from a @e copy of @a bytes. + * @param yybytes the byte buffer to scan + * @param _yybytes_len the number of bytes in the buffer pointed to by @a bytes. + * + * @return the newly allocated buffer state object. + */ +YY_BUFFER_STATE yy_scan_bytes (const char * yybytes, int _yybytes_len ) +{ + YY_BUFFER_STATE b; + char *buf; + yy_size_t n; + int i; + + /* Get memory for full buffer, including space for trailing EOB's. */ + n = (yy_size_t) (_yybytes_len + 2); + buf = (char *) yyalloc( n ); + if ( ! buf ) + YY_FATAL_ERROR( "out of dynamic memory in yy_scan_bytes()" ); + + for ( i = 0; i < _yybytes_len; ++i ) + buf[i] = yybytes[i]; + + buf[_yybytes_len] = buf[_yybytes_len+1] = YY_END_OF_BUFFER_CHAR; + + b = yy_scan_buffer( buf, n ); + if ( ! b ) + YY_FATAL_ERROR( "bad buffer in yy_scan_bytes()" ); + + /* It's okay to grow etc. this buffer, and we should throw it + * away when we're done. + */ + b->yy_is_our_buffer = 1; + + return b; +} + +#ifndef YY_EXIT_FAILURE +#define YY_EXIT_FAILURE 2 +#endif + +static void yynoreturn yy_fatal_error (const char* msg ) +{ + fprintf( stderr, "%s\n", msg ); + exit( YY_EXIT_FAILURE ); +} + +/* Redefine yyless() so it works in section 3 code. */ + +#undef yyless +#define yyless(n) \ + do \ + { \ + /* Undo effects of setting up yytext. */ \ + int yyless_macro_arg = (n); \ + YY_LESS_LINENO(yyless_macro_arg);\ + yytext[yyleng] = (yy_hold_char); \ + (yy_c_buf_p) = yytext + yyless_macro_arg; \ + (yy_hold_char) = *(yy_c_buf_p); \ + *(yy_c_buf_p) = '\0'; \ + yyleng = yyless_macro_arg; \ + } \ + while ( 0 ) + +/* Accessor methods (get/set functions) to struct members. */ + +/** Get the current line number. + * + */ +int yyget_lineno (void) +{ + + return yylineno; +} + +/** Get the input stream. + * + */ +FILE *yyget_in (void) +{ + return yyin; +} + +/** Get the output stream. + * + */ +FILE *yyget_out (void) +{ + return yyout; +} + +/** Get the length of the current token. + * + */ +int yyget_leng (void) +{ + return yyleng; +} + +/** Get the current token. + * + */ + +char *yyget_text (void) +{ + return yytext; +} + +/** Set the current line number. + * @param _line_number line number + * + */ +void yyset_lineno (int _line_number ) +{ + + yylineno = _line_number; +} + +/** Set the input stream. This does not discard the current + * input buffer. + * @param _in_str A readable stream. + * + * @see yy_switch_to_buffer + */ +void yyset_in (FILE * _in_str ) +{ + yyin = _in_str ; +} + +void yyset_out (FILE * _out_str ) +{ + yyout = _out_str ; +} + +int yyget_debug (void) +{ + return yy_flex_debug; +} + +void yyset_debug (int _bdebug ) +{ + yy_flex_debug = _bdebug ; +} + +static int yy_init_globals (void) +{ + /* Initialization is the same as for the non-reentrant scanner. + * This function is called from yylex_destroy(), so don't allocate here. + */ + + (yy_buffer_stack) = NULL; + (yy_buffer_stack_top) = 0; + (yy_buffer_stack_max) = 0; + (yy_c_buf_p) = NULL; + (yy_init) = 0; + (yy_start) = 0; + +/* Defined in main.c */ +#ifdef YY_STDINIT + yyin = stdin; + yyout = stdout; +#else + yyin = NULL; + yyout = NULL; +#endif + + /* For future reference: Set errno on error, since we are called by + * yylex_init() + */ + return 0; +} + +/* yylex_destroy is for both reentrant and non-reentrant scanners. */ +int yylex_destroy (void) +{ + + /* Pop the buffer stack, destroying each element. */ + while(YY_CURRENT_BUFFER){ + yy_delete_buffer( YY_CURRENT_BUFFER ); + YY_CURRENT_BUFFER_LVALUE = NULL; + yypop_buffer_state(); + } + + /* Destroy the stack itself. */ + yyfree((yy_buffer_stack) ); + (yy_buffer_stack) = NULL; + + /* Reset the globals. This is important in a non-reentrant scanner so the next time + * yylex() is called, initialization will occur. */ + yy_init_globals( ); + + return 0; +} + +/* + * Internal utility routines. + */ + +#ifndef yytext_ptr +static void yy_flex_strncpy (char* s1, const char * s2, int n ) +{ + + int i; + for ( i = 0; i < n; ++i ) + s1[i] = s2[i]; +} +#endif + +#ifdef YY_NEED_STRLEN +static int yy_flex_strlen (const char * s ) +{ + int n; + for ( n = 0; s[n]; ++n ) + ; + + return n; +} +#endif + +void *yyalloc (yy_size_t size ) +{ + return malloc(size); +} + +void *yyrealloc (void * ptr, yy_size_t size ) +{ + + /* The cast to (char *) in the following accommodates both + * implementations that use char* generic pointers, and those + * that use void* generic pointers. It works with the latter + * because both ANSI C and C++ allow castless assignment from + * any pointer type to void*, and deal with argument conversions + * as though doing an assignment. + */ + return realloc(ptr, size); +} + +void yyfree (void * ptr ) +{ + free( (char *) ptr ); /* see yyrealloc() for (char *) cast */ +} + +#define YYTABLES_NAME "yytables" + +#line 167 "css.l" + + diff --git a/src/css.l b/src/css.l new file mode 100644 index 0000000..bae065d --- /dev/null +++ b/src/css.l @@ -0,0 +1,167 @@ +%option case-insensitive +%option noyywrap +%option never-interactive +%option nounput + +%top{ +/* config.h must precede flex's inclusion of + in order for its _GNU_SOURCE definition to take effect. */ +#include +} + +%{ +/* Lex source for CSS tokenizing. + Taken from http://www.w3.org/TR/CSS21/grammar.html#q2 + Copyright (C) 2006, 2009-2011, 2015, 2018-2020 Free Software + Foundation, Inc. + +This file is part of GNU Wget. + +GNU Wget is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 3 of the License, or (at +your option) any later version. + +GNU Wget 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 Wget. If not, see . + +Additional permission under GNU GPL version 3 section 7 + +If you modify this program, or any covered work, by linking or +combining it with the OpenSSL project's OpenSSL library (or a +modified version of that library), containing parts covered by the +terms of the OpenSSL or SSLeay licenses, the Free Software Foundation +grants you additional permission to convey the resulting work. +Corresponding Source for a non-source form of such a combination +shall include the source code for the parts of OpenSSL used as well +as that of the covered work. */ + +#define YY_NO_INPUT + +#include "css-tokens.h" + +#if defined __clang__ || __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5) + #pragma GCC diagnostic ignored "-Wunknown-pragmas" // clang mourns about the next one + #pragma GCC diagnostic ignored "-Wunused-function" + #pragma GCC diagnostic ignored "-Wunused-macros" + #pragma GCC diagnostic ignored "-Wunused-parameter" + #pragma GCC diagnostic ignored "-Wsign-compare" + #pragma GCC diagnostic ignored "-Wswitch-default" + #pragma GCC diagnostic ignored "-Wunreachable-code" // clang + #pragma clang diagnostic ignored "-Wshorten-64-to-32" + #ifndef __clang__ + #pragma GCC diagnostic ignored "-Wsuggest-attribute=pure" + #endif +#endif + +%} + +h [0-9a-f] +nonascii [\240-\377] +unicode \\{h}{1,6}(\r\n|[ \t\r\n\f])? +escape {unicode}|\\[^\r\n\f0-9a-f] +nmstart [_a-z]|{nonascii}|{escape} +nmchar [_a-z0-9-]|{nonascii}|{escape} +string1 \"([^\n\r\f\\"]|\\{nl}|{escape})*\" +string2 \'([^\n\r\f\\']|\\{nl}|{escape})*\' +badstring1 \"([^\n\r\f\\"]|\\{nl}|{escape})*\\? +badstring2 \'([^\n\r\f\\']|\\{nl}|{escape})*\\? +badcomment1 \/\*[^*]*\*+([^/*][^*]*\*+)* +badcomment2 \/\*[^*]*(\*+[^/*][^*]*)* +baduri1 url\({w}([!#$%&*-\[\]-~]|{nonascii}|{escape})*{w} +baduri2 url\({w}{string}{w} +baduri3 url\({w}{badstring} +comment \/\*[^*]*\*+([^/*][^*]*\*+)*\/ +ident -?{nmstart}{nmchar}* +name {nmchar}+ +num [0-9]+|[0-9]*"."[0-9]+ +string {string1}|{string2} +badstring {badstring1}|{badstring2} +badcomment {badcomment1}|{badcomment2} +baduri {baduri1}|{baduri2}|{baduri3} +url ([!#$%&*-~]|{nonascii}|{escape})* +s [ \t\r\n\f]+ +w {s}? +nl \n|\r\n|\r|\f + +A a|\\0{0,4}(41|61)(\r\n|[ \t\r\n\f])? +C c|\\0{0,4}(43|63)(\r\n|[ \t\r\n\f])? +D d|\\0{0,4}(44|64)(\r\n|[ \t\r\n\f])? +E e|\\0{0,4}(45|65)(\r\n|[ \t\r\n\f])? +G g|\\0{0,4}(47|67)(\r\n|[ \t\r\n\f])?|\\g +H h|\\0{0,4}(48|68)(\r\n|[ \t\r\n\f])?|\\h +I i|\\0{0,4}(49|69)(\r\n|[ \t\r\n\f])?|\\i +K k|\\0{0,4}(4b|6b)(\r\n|[ \t\r\n\f])?|\\k +L l|\\0{0,4}(4c|6c)(\r\n|[ \t\r\n\f])?|\\l +M m|\\0{0,4}(4d|6d)(\r\n|[ \t\r\n\f])?|\\m +N n|\\0{0,4}(4e|6e)(\r\n|[ \t\r\n\f])?|\\n +O o|\\0{0,4}(4f|6f)(\r\n|[ \t\r\n\f])?|\\o +P p|\\0{0,4}(50|70)(\r\n|[ \t\r\n\f])?|\\p +R r|\\0{0,4}(52|72)(\r\n|[ \t\r\n\f])?|\\r +S s|\\0{0,4}(53|73)(\r\n|[ \t\r\n\f])?|\\s +T t|\\0{0,4}(54|74)(\r\n|[ \t\r\n\f])?|\\t +U u|\\0{0,4}(55|75)(\r\n|[ \t\r\n\f])?|\\u +X x|\\0{0,4}(58|78)(\r\n|[ \t\r\n\f])?|\\x +Z z|\\0{0,4}(5a|7a)(\r\n|[ \t\r\n\f])?|\\z + +%% + +{s} {return S;} + +{comment} {return COMMENT;} +#\/\*[^*]*\*+([^/*][^*]*\*+)*\/ /* ignore comments */ +{badcomment} /* unclosed comment at EOF */ + +"" {return CDC;} +"~=" {return INCLUDES;} +"|=" {return DASHMATCH;} + +{string} {return STRING;} +{badstring} {return BAD_STRING;} + +{ident} {return IDENT;} + +"#"{name} {return HASH;} + +@{I}{M}{P}{O}{R}{T} {return IMPORT_SYM;} +@{P}{A}{G}{E} {return PAGE_SYM;} +@{M}{E}{D}{I}{A} {return MEDIA_SYM;} +"@charset " {return CHARSET_SYM;} + +"!"({w}|{comment})*{I}{M}{P}{O}{R}{T}{A}{N}{T} {return IMPORTANT_SYM;} + +{num}{E}{M} {return EMS;} +{num}{E}{X} {return EXS;} +{num}{P}{X} {return LENGTH;} +{num}{C}{M} {return LENGTH;} +{num}{M}{M} {return LENGTH;} +{num}{I}{N} {return LENGTH;} +{num}{P}{T} {return LENGTH;} +{num}{P}{C} {return LENGTH;} +{num}{D}{E}{G} {return ANGLE;} +{num}{R}{A}{D} {return ANGLE;} +{num}{G}{R}{A}{D} {return ANGLE;} +{num}{M}{S} {return TIME;} +{num}{S} {return TIME;} +{num}{H}{Z} {return FREQ;} +{num}{K}{H}{Z} {return FREQ;} +{num}{ident} {return DIMENSION;} + +{num}% {return PERCENTAGE;} +{num} {return NUMBER;} + +"url("{w}{string}{w}")" {return URI;} +"url("{w}{url}{w}")" {return URI;} +{baduri} {return BAD_URI;} + +{ident}"(" {return FUNCTION;} + +. {return *yytext;} + +%% diff --git a/src/css_.c b/src/css_.c new file mode 100644 index 0000000..76e4bb9 --- /dev/null +++ b/src/css_.c @@ -0,0 +1,3933 @@ +#include "wget.h" +#line 1 "css.c" +/* config.h must precede flex's inclusion of + in order for its _GNU_SOURCE definition to take effect. */ +#include + +#line 6 "css.c" + +#define YY_INT_ALIGNED short int + +/* A lexical scanner generated by flex */ + +#define FLEX_SCANNER +#define YY_FLEX_MAJOR_VERSION 2 +#define YY_FLEX_MINOR_VERSION 6 +#define YY_FLEX_SUBMINOR_VERSION 4 +#if YY_FLEX_SUBMINOR_VERSION > 0 +#define FLEX_BETA +#endif + +/* First, we deal with platform-specific or compiler-specific issues. */ + +/* begin standard C headers. */ +#include +#include +#include +#include + +/* end standard C headers. */ + +/* flex integer type definitions */ + +#ifndef FLEXINT_H +#define FLEXINT_H + +/* C99 systems have . Non-C99 systems may or may not. */ + +#if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L + +/* C99 says to define __STDC_LIMIT_MACROS before including stdint.h, + * if you want the limit (max/min) macros for int types. + */ +#ifndef __STDC_LIMIT_MACROS +#define __STDC_LIMIT_MACROS 1 +#endif + +#include +typedef int8_t flex_int8_t; +typedef uint8_t flex_uint8_t; +typedef int16_t flex_int16_t; +typedef uint16_t flex_uint16_t; +typedef int32_t flex_int32_t; +typedef uint32_t flex_uint32_t; +#else +typedef signed char flex_int8_t; +typedef short int flex_int16_t; +typedef int flex_int32_t; +typedef unsigned char flex_uint8_t; +typedef unsigned short int flex_uint16_t; +typedef unsigned int flex_uint32_t; + +/* Limits of integral types. */ +#ifndef INT8_MIN +#define INT8_MIN (-128) +#endif +#ifndef INT16_MIN +#define INT16_MIN (-32767-1) +#endif +#ifndef INT32_MIN +#define INT32_MIN (-2147483647-1) +#endif +#ifndef INT8_MAX +#define INT8_MAX (127) +#endif +#ifndef INT16_MAX +#define INT16_MAX (32767) +#endif +#ifndef INT32_MAX +#define INT32_MAX (2147483647) +#endif +#ifndef UINT8_MAX +#define UINT8_MAX (255U) +#endif +#ifndef UINT16_MAX +#define UINT16_MAX (65535U) +#endif +#ifndef UINT32_MAX +#define UINT32_MAX (4294967295U) +#endif + +#ifndef SIZE_MAX +#define SIZE_MAX (~(size_t)0) +#endif + +#endif /* ! C99 */ + +#endif /* ! FLEXINT_H */ + +/* begin standard C++ headers. */ + +/* TODO: this is always defined, so inline it */ +#define yyconst const + +#if defined(__GNUC__) && __GNUC__ >= 3 +#define yynoreturn __attribute__((__noreturn__)) +#else +#define yynoreturn +#endif + +/* Returned upon end-of-file. */ +#define YY_NULL 0 + +/* Promotes a possibly negative, possibly signed char to an + * integer in range [0..255] for use as an array index. + */ +#define YY_SC_TO_UI(c) ((YY_CHAR) (c)) + +/* Enter a start condition. This macro really ought to take a parameter, + * but we do it the disgusting crufty way forced on us by the ()-less + * definition of BEGIN. + */ +#define BEGIN (yy_start) = 1 + 2 * +/* Translate the current start state into a value that can be later handed + * to BEGIN to return to the state. The YYSTATE alias is for lex + * compatibility. + */ +#define YY_START (((yy_start) - 1) / 2) +#define YYSTATE YY_START +/* Action number for EOF rule of a given start state. */ +#define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1) +/* Special action meaning "start processing a new file". */ +#define YY_NEW_FILE yyrestart( yyin ) +#define YY_END_OF_BUFFER_CHAR 0 + +/* Size of default input buffer. */ +#ifndef YY_BUF_SIZE +#ifdef __ia64__ +/* On IA-64, the buffer size is 16k, not 8k. + * Moreover, YY_BUF_SIZE is 2*YY_READ_BUF_SIZE in the general case. + * Ditto for the __ia64__ case accordingly. + */ +#define YY_BUF_SIZE 32768 +#else +#define YY_BUF_SIZE 16384 +#endif /* __ia64__ */ +#endif + +/* The state buf must be large enough to hold one state per character in the main buffer. + */ +#define YY_STATE_BUF_SIZE ((YY_BUF_SIZE + 2) * sizeof(yy_state_type)) + +#ifndef YY_TYPEDEF_YY_BUFFER_STATE +#define YY_TYPEDEF_YY_BUFFER_STATE +typedef struct yy_buffer_state *YY_BUFFER_STATE; +#endif + +#ifndef YY_TYPEDEF_YY_SIZE_T +#define YY_TYPEDEF_YY_SIZE_T +typedef size_t yy_size_t; +#endif + +extern int yyleng; + +extern FILE *yyin, *yyout; + +#define EOB_ACT_CONTINUE_SCAN 0 +#define EOB_ACT_END_OF_FILE 1 +#define EOB_ACT_LAST_MATCH 2 + + #define YY_LESS_LINENO(n) + #define YY_LINENO_REWIND_TO(ptr) + +/* Return all but the first "n" matched characters back to the input stream. */ +#define yyless(n) \ + do \ + { \ + /* Undo effects of setting up yytext. */ \ + int yyless_macro_arg = (n); \ + YY_LESS_LINENO(yyless_macro_arg);\ + *yy_cp = (yy_hold_char); \ + YY_RESTORE_YY_MORE_OFFSET \ + (yy_c_buf_p) = yy_cp = yy_bp + yyless_macro_arg - YY_MORE_ADJ; \ + YY_DO_BEFORE_ACTION; /* set up yytext again */ \ + } \ + while ( 0 ) +#define unput(c) yyunput( c, (yytext_ptr) ) + +#ifndef YY_STRUCT_YY_BUFFER_STATE +#define YY_STRUCT_YY_BUFFER_STATE +struct yy_buffer_state + { + FILE *yy_input_file; + + char *yy_ch_buf; /* input buffer */ + char *yy_buf_pos; /* current position in input buffer */ + + /* Size of input buffer in bytes, not including room for EOB + * characters. + */ + int yy_buf_size; + + /* Number of characters read into yy_ch_buf, not including EOB + * characters. + */ + int yy_n_chars; + + /* Whether we "own" the buffer - i.e., we know we created it, + * and can realloc() it to grow it, and should free() it to + * delete it. + */ + int yy_is_our_buffer; + + /* Whether this is an "interactive" input source; if so, and + * if we're using stdio for input, then we want to use getc() + * instead of fread(), to make sure we stop fetching input after + * each newline. + */ + int yy_is_interactive; + + /* Whether we're considered to be at the beginning of a line. + * If so, '^' rules will be active on the next match, otherwise + * not. + */ + int yy_at_bol; + + int yy_bs_lineno; /**< The line count. */ + int yy_bs_column; /**< The column count. */ + + /* Whether to try to fill the input buffer when we reach the + * end of it. + */ + int yy_fill_buffer; + + int yy_buffer_status; + +#define YY_BUFFER_NEW 0 +#define YY_BUFFER_NORMAL 1 + /* When an EOF's been seen but there's still some text to process + * then we mark the buffer as YY_EOF_PENDING, to indicate that we + * shouldn't try reading from the input source any more. We might + * still have a bunch of tokens to match, though, because of + * possible backing-up. + * + * When we actually see the EOF, we change the status to "new" + * (via yyrestart()), so that the user can continue scanning by + * just pointing yyin at a new input file. + */ +#define YY_BUFFER_EOF_PENDING 2 + + }; +#endif /* !YY_STRUCT_YY_BUFFER_STATE */ + +/* Stack of input buffers. */ +static size_t yy_buffer_stack_top = 0; /**< index of top of stack. */ +static size_t yy_buffer_stack_max = 0; /**< capacity of stack. */ +static YY_BUFFER_STATE * yy_buffer_stack = NULL; /**< Stack as an array. */ + +/* We provide macros for accessing buffer states in case in the + * future we want to put the buffer states in a more general + * "scanner state". + * + * Returns the top of the stack, or NULL. + */ +#define YY_CURRENT_BUFFER ( (yy_buffer_stack) \ + ? (yy_buffer_stack)[(yy_buffer_stack_top)] \ + : NULL) +/* Same as previous macro, but useful when we know that the buffer stack is not + * NULL or when we need an lvalue. For internal use only. + */ +#define YY_CURRENT_BUFFER_LVALUE (yy_buffer_stack)[(yy_buffer_stack_top)] + +/* yy_hold_char holds the character lost when yytext is formed. */ +static char yy_hold_char; +static int yy_n_chars; /* number of characters read into yy_ch_buf */ +int yyleng; + +/* Points to current character in buffer. */ +static char *yy_c_buf_p = NULL; +static int yy_init = 0; /* whether we need to initialize */ +static int yy_start = 0; /* start state number */ + +/* Flag which is used to allow yywrap()'s to do buffer switches + * instead of setting up a fresh yyin. A bit of a hack ... + */ +static int yy_did_buffer_switch_on_eof; + +void yyrestart ( FILE *input_file ); +void yy_switch_to_buffer ( YY_BUFFER_STATE new_buffer ); +YY_BUFFER_STATE yy_create_buffer ( FILE *file, int size ); +void yy_delete_buffer ( YY_BUFFER_STATE b ); +void yy_flush_buffer ( YY_BUFFER_STATE b ); +void yypush_buffer_state ( YY_BUFFER_STATE new_buffer ); +void yypop_buffer_state ( void ); + +static void yyensure_buffer_stack ( void ); +static void yy_load_buffer_state ( void ); +static void yy_init_buffer ( YY_BUFFER_STATE b, FILE *file ); +#define YY_FLUSH_BUFFER yy_flush_buffer( YY_CURRENT_BUFFER ) + +YY_BUFFER_STATE yy_scan_buffer ( char *base, yy_size_t size ); +YY_BUFFER_STATE yy_scan_string ( const char *yy_str ); +YY_BUFFER_STATE yy_scan_bytes ( const char *bytes, int len ); + +void *yyalloc ( yy_size_t ); +void *yyrealloc ( void *, yy_size_t ); +void yyfree ( void * ); + +#define yy_new_buffer yy_create_buffer +#define yy_set_interactive(is_interactive) \ + { \ + if ( ! YY_CURRENT_BUFFER ){ \ + yyensure_buffer_stack (); \ + YY_CURRENT_BUFFER_LVALUE = \ + yy_create_buffer( yyin, YY_BUF_SIZE ); \ + } \ + YY_CURRENT_BUFFER_LVALUE->yy_is_interactive = is_interactive; \ + } +#define yy_set_bol(at_bol) \ + { \ + if ( ! YY_CURRENT_BUFFER ){\ + yyensure_buffer_stack (); \ + YY_CURRENT_BUFFER_LVALUE = \ + yy_create_buffer( yyin, YY_BUF_SIZE ); \ + } \ + YY_CURRENT_BUFFER_LVALUE->yy_at_bol = at_bol; \ + } +#define YY_AT_BOL() (YY_CURRENT_BUFFER_LVALUE->yy_at_bol) + +/* Begin user sect3 */ + +#define yywrap() (/*CONSTCOND*/1) +#define YY_SKIP_YYWRAP +typedef flex_uint8_t YY_CHAR; + +FILE *yyin = NULL, *yyout = NULL; + +typedef int yy_state_type; + +extern int yylineno; +int yylineno = 1; + +extern char *yytext; +#ifdef yytext_ptr +#undef yytext_ptr +#endif +#define yytext_ptr yytext + +static yy_state_type yy_get_previous_state ( void ); +static yy_state_type yy_try_NUL_trans ( yy_state_type current_state ); +static int yy_get_next_buffer ( void ); +static void yynoreturn yy_fatal_error ( const char* msg ); + +/* Done after the current pattern has been matched and before the + * corresponding action - sets up yytext. + */ +#define YY_DO_BEFORE_ACTION \ + (yytext_ptr) = yy_bp; \ + yyleng = (int) (yy_cp - yy_bp); \ + (yy_hold_char) = *yy_cp; \ + *yy_cp = '\0'; \ + (yy_c_buf_p) = yy_cp; +#define YY_NUM_RULES 41 +#define YY_END_OF_BUFFER 42 +/* This struct is not used in this scanner, + but its presence is necessary. */ +struct yy_trans_info + { + flex_int32_t yy_verify; + flex_int32_t yy_nxt; + }; +static const flex_int16_t yy_accept[1103] = + { 0, + 0, 0, 42, 40, 1, 1, 40, 10, 40, 10, + 40, 40, 40, 35, 40, 40, 11, 11, 40, 40, + 40, 1, 0, 0, 0, 0, 10, 9, 10, 12, + 0, 0, 10, 10, 0, 11, 0, 35, 4, 34, + 0, 0, 35, 33, 33, 33, 33, 33, 33, 33, + 33, 33, 33, 33, 30, 0, 0, 0, 0, 0, + 0, 0, 39, 11, 0, 11, 11, 11, 8, 7, + 0, 0, 0, 0, 0, 0, 0, 10, 10, 10, + 0, 12, 12, 10, 10, 10, 6, 4, 4, 0, + 33, 0, 21, 0, 33, 0, 18, 19, 0, 33, + + 0, 31, 0, 23, 0, 33, 0, 22, 29, 0, + 25, 24, 20, 0, 33, 0, 33, 33, 33, 33, + 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, + 30, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 11, 11, 11, + 11, 11, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 10, 10, 10, 0, 0, 12, 12, 10, + 10, 10, 4, 2, 33, 33, 33, 33, 33, 21, + 26, 0, 33, 33, 33, 33, 33, 33, 33, 33, + 18, 19, 33, 0, 33, 33, 33, 33, 33, 33, + + 33, 31, 33, 33, 33, 23, 32, 0, 33, 33, + 33, 33, 33, 33, 33, 33, 33, 22, 29, 33, + 33, 33, 33, 33, 24, 20, 27, 0, 33, 33, + 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, + 33, 33, 33, 33, 33, 33, 33, 33, 30, 33, + 33, 5, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 11, 11, 38, 11, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 10, 0, 3, 12, 10, 4, 4, 33, + + 33, 33, 33, 33, 21, 21, 33, 33, 33, 26, + 33, 33, 33, 33, 33, 33, 33, 33, 33, 18, + 19, 18, 28, 0, 33, 33, 33, 33, 33, 33, + 33, 33, 33, 33, 31, 31, 33, 33, 33, 23, + 23, 33, 33, 33, 32, 33, 33, 33, 33, 33, + 33, 33, 33, 33, 22, 29, 22, 33, 33, 33, + 33, 33, 25, 24, 20, 33, 33, 33, 33, 33, + 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, + 33, 33, 33, 33, 33, 33, 33, 33, 30, 33, + 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, + + 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, + 25, 33, 33, 33, 30, 30, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 14, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 11, 38, + 38, 38, 38, 37, 0, 11, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 10, 0, 0, 12, 10, 33, 33, 33, 33, 21, + 21, 21, 21, 33, 33, 33, 26, 33, 33, 33, + 33, 33, 33, 33, 33, 33, 33, 33, 18, 19, + + 18, 18, 18, 19, 19, 33, 33, 33, 33, 33, + 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, + 33, 33, 31, 31, 31, 31, 33, 33, 33, 23, + 23, 23, 23, 33, 33, 33, 32, 32, 33, 33, + 33, 33, 33, 33, 33, 33, 33, 33, 33, 22, + 29, 22, 22, 22, 29, 29, 33, 33, 33, 33, + 33, 25, 24, 20, 25, 25, 24, 24, 20, 20, + 33, 33, 33, 27, 33, 33, 33, 33, 33, 33, + 27, 33, 33, 33, 33, 33, 33, 33, 33, 33, + 33, 33, 33, 33, 33, 33, 33, 30, 33, 33, + + 33, 25, 33, 27, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 11, 38, 38, 38, + 38, 38, 38, 38, 38, 0, 38, 37, 38, 38, + 11, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 10, 12, 10, 33, 33, 33, + 33, 21, 21, 33, 33, 33, 26, 26, 26, 33, + 33, 33, 33, 33, 33, 33, 33, 33, 18, 19, + 18, 33, 33, 33, 28, 33, 33, 33, 33, 33, + + 33, 28, 33, 33, 33, 33, 33, 28, 33, 33, + 33, 31, 31, 33, 33, 33, 23, 23, 33, 33, + 33, 32, 32, 32, 32, 33, 33, 33, 33, 33, + 33, 33, 33, 33, 22, 29, 22, 33, 33, 33, + 33, 33, 25, 24, 20, 33, 33, 33, 27, 27, + 27, 33, 33, 33, 33, 27, 33, 33, 33, 33, + 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, + 33, 30, 33, 33, 33, 25, 33, 27, 0, 13, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + + 0, 0, 14, 0, 0, 0, 0, 11, 38, 36, + 38, 38, 38, 38, 38, 38, 38, 38, 38, 0, + 38, 38, 37, 38, 0, 11, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 10, 12, + 10, 33, 33, 33, 21, 21, 33, 33, 33, 26, + 33, 33, 33, 33, 33, 33, 33, 18, 19, 18, + 33, 33, 33, 28, 28, 28, 33, 33, 33, 33, + 33, 33, 33, 33, 28, 33, 33, 31, 31, 33, + 33, 23, 23, 33, 33, 33, 32, 32, 33, 33, + 33, 33, 33, 33, 33, 22, 29, 22, 33, 33, + + 33, 33, 25, 24, 20, 33, 33, 33, 27, 33, + 33, 33, 27, 33, 33, 33, 33, 33, 33, 33, + 33, 33, 33, 33, 30, 33, 33, 33, 25, 33, + 27, 0, 0, 0, 0, 13, 0, 0, 0, 0, + 0, 0, 0, 15, 0, 0, 0, 0, 0, 14, + 14, 0, 11, 38, 38, 38, 38, 38, 38, 38, + 0, 0, 38, 38, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 33, 21, 21, 33, 33, + 26, 33, 18, 19, 18, 33, 33, 33, 28, 33, + 33, 33, 33, 33, 28, 31, 31, 23, 23, 33, + + 33, 32, 32, 33, 22, 29, 22, 25, 24, 20, + 33, 33, 27, 33, 27, 16, 0, 13, 0, 0, + 0, 0, 0, 15, 15, 0, 0, 38, 38, 38, + 0, 0, 0, 0, 38, 17, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 26, 33, 33, + 28, 33, 32, 32, 27, 0, 13, 13, 0, 0, + 38, 38, 38, 0, 0, 38, 0, 0, 0, 17, + 0, 0, 0, 0, 0, 0, 0, 28, 0, 38, + 38, 38, 0, 38, 0, 17, 0, 0, 0, 0, + 38, 38, 0, 38, 0, 17, 17, 0, 0, 0, + + 0, 0 + } ; + +static const YY_CHAR yy_ec[256] = + { 0, + 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, + 1, 4, 5, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 6, 7, 8, 9, 10, 11, 10, 12, 13, + 14, 15, 10, 10, 16, 17, 18, 19, 20, 21, + 22, 23, 24, 25, 26, 27, 28, 10, 10, 29, + 30, 31, 10, 32, 33, 34, 35, 36, 37, 38, + 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, + 42, 49, 50, 51, 52, 42, 42, 53, 42, 54, + 10, 55, 10, 10, 42, 10, 56, 57, 58, 59, + + 60, 61, 62, 63, 64, 42, 65, 66, 67, 68, + 69, 70, 42, 71, 72, 73, 74, 42, 42, 75, + 42, 76, 10, 77, 10, 78, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 79, + 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, + 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, + 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, + 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, + + 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, + 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, + 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, + 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, + 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, + 79, 79, 79, 79, 79 + } ; + +static const YY_CHAR yy_meta[80] = + { 0, + 1, 2, 3, 3, 3, 2, 2, 4, 2, 2, + 2, 4, 5, 2, 2, 6, 2, 7, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 2, 2, + 2, 2, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 2, 2, 9 + } ; + +static const flex_int16_t yy_base[1137] = + { 0, + 0, 0, 4195, 7110, 78, 83, 88, 87, 78, 85, + 82, 88, 4161, 142, 4151, 90, 86, 206, 259, 4118, + 4083, 98, 234, 4083, 72, 109, 116, 7110, 318, 100, + 4082, 361, 208, 420, 4017, 92, 463, 205, 4024, 7110, + 3977, 222, 0, 3974, 209, 89, 257, 202, 180, 245, + 248, 259, 355, 272, 3955, 524, 3987, 83, 280, 311, + 274, 585, 7110, 117, 637, 348, 210, 697, 7110, 7110, + 3963, 302, 382, 243, 3940, 3933, 371, 251, 356, 757, + 3945, 101, 817, 246, 357, 877, 7110, 3938, 252, 920, + 3894, 974, 3886, 1017, 397, 447, 3861, 3860, 661, 376, + + 904, 3850, 721, 3841, 448, 451, 1040, 3840, 3825, 1045, + 3813, 3796, 3787, 1063, 569, 600, 3784, 1137, 484, 1180, + 613, 1221, 748, 380, 566, 347, 591, 907, 654, 462, + 3767, 3789, 118, 559, 779, 633, 593, 588, 628, 782, + 654, 3776, 775, 3775, 802, 772, 682, 336, 1279, 345, + 447, 1322, 3754, 254, 695, 837, 658, 581, 632, 656, + 806, 1012, 456, 862, 1365, 3744, 256, 903, 1408, 278, + 964, 1451, 3730, 7110, 3689, 1511, 839, 751, 790, 3655, + 3633, 1086, 865, 3648, 3645, 868, 812, 3627, 850, 3599, + 3559, 3554, 895, 897, 344, 3587, 3580, 885, 900, 892, + + 922, 3526, 1001, 929, 943, 3484, 3483, 1165, 1002, 3500, + 3499, 1037, 1074, 945, 3485, 969, 3476, 3439, 3424, 1096, + 3450, 410, 3442, 438, 3403, 3397, 3396, 1109, 1104, 3416, + 3396, 745, 1554, 1126, 1597, 1199, 1638, 1237, 1696, 1591, + 1451, 1224, 1636, 1495, 1673, 1680, 1762, 1836, 1318, 1740, + 1703, 7110, 573, 1049, 1161, 1158, 970, 987, 1131, 1017, + 1192, 1245, 3385, 3371, 1046, 1269, 1252, 3369, 3358, 1342, + 1600, 1403, 1552, 1788, 1263, 1891, 1796, 1934, 3362, 1868, + 1238, 1307, 1248, 3350, 3304, 1055, 1352, 1779, 1931, 1391, + 1392, 1393, 1983, 3284, 7110, 2026, 2069, 3253, 347, 892, + + 2112, 1392, 1108, 1110, 1248, 1488, 1500, 3239, 3204, 3174, + 1541, 3194, 3177, 2112, 1624, 1119, 3145, 1176, 3142, 1861, + 1873, 1878, 3104, 1704, 1607, 3071, 2999, 1394, 2951, 2939, + 1979, 1503, 1180, 1209, 1896, 1901, 1669, 1259, 1273, 1936, + 1971, 1707, 1278, 1296, 2904, 1691, 2927, 2900, 2022, 1731, + 1336, 2867, 1403, 2856, 1994, 2027, 2063, 1753, 2851, 716, + 2848, 950, 2068, 2106, 2117, 1786, 2836, 2831, 1793, 2833, + 2795, 2150, 2191, 1807, 2234, 2138, 2275, 2156, 2333, 2228, + 2237, 2273, 2344, 2358, 2367, 2378, 2449, 2523, 2189, 2433, + 2413, 1498, 2121, 2020, 2269, 2451, 1769, 2278, 1797, 2271, + + 1426, 1684, 1625, 2322, 1465, 2311, 2342, 2464, 2148, 2457, + 2261, 1528, 2388, 2423, 2759, 1179, 1347, 2149, 2296, 2245, + 2683, 2676, 1875, 1831, 2535, 2548, 1910, 2480, 2177, 2645, + 2637, 2383, 2555, 7110, 2446, 2468, 2600, 2595, 2508, 2546, + 2570, 2561, 2456, 2552, 2533, 2540, 1981, 2561, 2614, 2651, + 2674, 741, 457, 7110, 2729, 2807, 2597, 661, 2134, 2596, + 2579, 1548, 1591, 2330, 2405, 2814, 2604, 1589, 2641, 97, + 2882, 2584, 771, 2942, 3003, 3046, 2605, 1637, 1675, 2688, + 2695, 2537, 1235, 2639, 2556, 2555, 2710, 2662, 2543, 2538, + 2819, 1925, 2402, 2684, 1849, 2508, 1979, 2507, 2715, 2720, + + 2844, 2463, 1448, 2462, 1598, 2832, 2475, 2463, 2837, 2420, + 2412, 2894, 2582, 2374, 2365, 3042, 2023, 2628, 2816, 2853, + 2025, 2109, 2889, 2919, 2312, 1614, 2857, 2229, 2270, 2929, + 3047, 2262, 1615, 2931, 2423, 2439, 3052, 3083, 3071, 2289, + 2269, 3106, 2300, 2407, 3094, 2461, 2233, 2530, 2232, 3119, + 3124, 3129, 2191, 1714, 2183, 1734, 3117, 2186, 1033, 2175, + 1110, 3142, 3147, 3152, 2135, 1803, 2132, 2181, 2103, 2338, + 3076, 2090, 2077, 3160, 3148, 2035, 2003, 3172, 3132, 3134, + 0, 3213, 1864, 3230, 3173, 3254, 3181, 3312, 3378, 3437, + 3511, 3581, 3656, 3723, 3785, 3859, 3933, 3219, 3988, 4050, + + 3236, 2813, 3269, 2888, 2606, 2901, 3277, 3160, 2608, 2666, + 3251, 3162, 3338, 3190, 2881, 3264, 7110, 3191, 3285, 1994, + 1985, 2987, 3302, 3350, 3326, 3303, 3358, 3340, 1965, 1964, + 3341, 3369, 3367, 3038, 3373, 3009, 4107, 3394, 1039, 3416, + 4166, 696, 4225, 3442, 3463, 3481, 3497, 3517, 4285, 4346, + 4407, 3059, 3408, 3193, 1957, 1942, 3295, 3430, 3539, 3544, + 3283, 2258, 3485, 311, 4467, 4510, 4553, 4596, 590, 2669, + 3080, 3327, 3553, 3451, 1920, 1919, 3559, 1876, 2372, 805, + 1897, 1896, 3572, 3260, 3261, 1801, 3311, 1794, 3565, 3614, + 3619, 3505, 1764, 1751, 3626, 3572, 1712, 1704, 3635, 3537, + + 3597, 0, 842, 1683, 1668, 3640, 3543, 0, 962, 3354, + 3355, 3645, 3661, 1143, 3420, 3436, 3672, 3681, 3673, 3477, + 3547, 3701, 3710, 1613, 2478, 1302, 1608, 1607, 3716, 3707, + 3553, 1605, 3554, 1537, 3732, 3737, 3748, 3732, 1529, 1796, + 1502, 1830, 3762, 3770, 3777, 3774, 1498, 1459, 3798, 1394, + 3135, 1339, 1384, 1374, 3811, 0, 4639, 3784, 1740, 3822, + 2122, 3822, 3869, 3895, 3916, 3941, 3970, 3978, 3995, 4699, + 4002, 3880, 4083, 4105, 3722, 0, 3634, 0, 1410, 7110, + 3904, 3810, 1349, 1342, 3782, 3868, 4066, 4635, 3883, 3654, + 3856, 1427, 3908, 1333, 1308, 3944, 4176, 3996, 3768, 3982, + + 1575, 4001, 4071, 4011, 3853, 4024, 1763, 4756, 4088, 7110, + 1487, 3423, 4816, 896, 3208, 4876, 4262, 4444, 4919, 4504, + 4547, 4591, 4677, 4979, 5040, 5101, 3896, 4040, 4023, 1274, + 1266, 3798, 4080, 4509, 4041, 4065, 4639, 1821, 4709, 5144, + 5187, 5230, 3632, 3726, 4208, 4213, 2076, 1260, 1207, 4231, + 1176, 1123, 4793, 3760, 1108, 3762, 1099, 4236, 4322, 4327, + 4093, 1043, 1038, 4332, 994, 3434, 2212, 1028, 1002, 4913, + 992, 951, 4552, 3833, 0, 3946, 3953, 4474, 4479, 4041, + 4059, 4645, 4716, 2284, 4091, 4106, 4721, 4733, 929, 840, + 4919, 4115, 838, 4116, 837, 4738, 4743, 4756, 811, 2240, + + 777, 3157, 4763, 4798, 4803, 2371, 745, 718, 4823, 658, + 646, 5138, 0, 4956, 5225, 5181, 5269, 5279, 5291, 5296, + 5303, 5315, 5386, 5143, 5350, 5369, 5375, 5394, 5408, 5448, + 5413, 642, 4130, 618, 583, 7110, 4253, 5467, 4134, 4243, + 5276, 2587, 4250, 4854, 4277, 4128, 4675, 2903, 4432, 7110, + 526, 2948, 4859, 1544, 4963, 5522, 1357, 3705, 5565, 5608, + 5472, 5669, 5477, 5730, 4466, 5171, 4581, 508, 493, 4435, + 5496, 4865, 4634, 5275, 3053, 5506, 5511, 5565, 478, 449, + 4864, 5767, 5602, 5607, 5772, 3203, 451, 445, 4924, 443, + 442, 5777, 5790, 5795, 5805, 5812, 5835, 5853, 5859, 4140, + + 4164, 4984, 5017, 5866, 5871, 5876, 5881, 5889, 5894, 5899, + 411, 381, 5022, 5907, 5913, 7110, 4866, 5027, 5214, 4678, + 5521, 3400, 4944, 7110, 370, 3468, 3483, 5950, 5993, 6036, + 5987, 6030, 6096, 0, 6139, 7110, 5502, 5131, 4161, 4218, + 4832, 5304, 6035, 5313, 4441, 5307, 3527, 5992, 344, 285, + 5490, 6133, 6073, 6138, 6176, 5382, 7110, 296, 3629, 3675, + 6213, 6256, 6299, 6199, 6342, 6385, 5403, 237, 230, 7110, + 5415, 6212, 6255, 5439, 3976, 5380, 3852, 6293, 3928, 6428, + 6471, 6514, 6557, 6600, 5441, 5531, 5500, 5100, 5886, 4057, + 6643, 6686, 6729, 5612, 5628, 7110, 133, 4058, 6772, 4181, + + 6336, 7110, 6833, 6837, 6846, 6850, 6855, 6864, 6873, 6882, + 6891, 6900, 112, 6904, 6913, 6922, 6931, 6940, 6949, 6958, + 6967, 6976, 6984, 6993, 7002, 7011, 7020, 7029, 7038, 7047, + 7056, 7065, 7074, 7083, 7092, 7100 + } ; + +static const flex_int16_t yy_def[1137] = + { 0, + 1102, 1, 1102, 1102, 1102, 1102, 1102, 1103, 1104, 1105, + 1106, 1102, 1102, 1102, 1102, 1102, 1107, 1107, 1108, 1102, + 1102, 1102, 1102, 1102, 1102, 1102, 1103, 1102, 1109, 1104, + 1102, 1110, 1105, 1111, 1102, 1107, 1108, 14, 1112, 1102, + 1113, 1102, 14, 1114, 1114, 1114, 1114, 1114, 1114, 1114, + 1114, 1114, 1114, 1114, 1114, 1102, 1102, 1102, 1102, 1102, + 1102, 1102, 1102, 1107, 1115, 1107, 1107, 1107, 1102, 1102, + 1116, 1102, 1102, 1102, 1102, 1102, 1102, 1103, 1103, 1103, + 1117, 1104, 1104, 1105, 1105, 1105, 1102, 1112, 1118, 56, + 1114, 1119, 1114, 1119, 1114, 94, 1114, 1114, 94, 1114, + + 94, 1114, 94, 1114, 94, 1114, 94, 1114, 1114, 94, + 1114, 1114, 1114, 94, 1114, 94, 1114, 1114, 118, 118, + 118, 118, 118, 1114, 1114, 1114, 1114, 1114, 1114, 1114, + 1114, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, + 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1107, 68, 1107, + 1107, 68, 1116, 1120, 1102, 1102, 1102, 1102, 1102, 1102, + 1102, 1102, 1103, 1103, 80, 1117, 1121, 1104, 83, 1105, + 1105, 86, 1122, 1102, 1114, 118, 176, 176, 176, 1114, + 1114, 94, 176, 176, 176, 176, 176, 176, 176, 176, + 1114, 1114, 1114, 94, 176, 176, 176, 1114, 176, 176, + + 176, 1114, 176, 176, 176, 1114, 1114, 94, 176, 176, + 176, 1114, 176, 176, 176, 176, 176, 1114, 1114, 176, + 176, 176, 176, 176, 1114, 1114, 1114, 94, 176, 176, + 176, 1114, 118, 233, 233, 233, 233, 233, 233, 239, + 239, 239, 239, 239, 239, 239, 239, 233, 248, 248, + 239, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, + 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, + 1102, 1102, 1102, 1102, 1107, 68, 1123, 68, 1124, 1102, + 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, + 1102, 1102, 80, 1125, 1102, 83, 86, 1122, 1126, 1114, + + 176, 301, 301, 301, 301, 301, 176, 176, 176, 1114, + 301, 301, 301, 301, 301, 301, 301, 301, 301, 301, + 301, 301, 1114, 94, 176, 176, 176, 301, 301, 301, + 301, 301, 301, 301, 301, 301, 301, 301, 301, 301, + 301, 176, 176, 176, 1114, 301, 301, 301, 301, 301, + 301, 301, 301, 301, 301, 301, 301, 301, 301, 301, + 301, 301, 301, 301, 301, 176, 176, 176, 301, 301, + 301, 301, 233, 373, 373, 373, 373, 373, 373, 379, + 379, 379, 379, 379, 379, 379, 379, 373, 388, 388, + 379, 1114, 1114, 1114, 1114, 373, 1114, 1114, 1114, 1114, + + 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, + 373, 1114, 1114, 373, 1114, 1114, 1102, 1102, 1102, 1102, + 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, + 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, + 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 276, 1123, + 1123, 1127, 1128, 1102, 1102, 276, 1129, 1130, 1102, 1102, + 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, + 1131, 1132, 1133, 1102, 86, 301, 476, 476, 476, 476, + 476, 1114, 1114, 301, 301, 301, 301, 476, 476, 476, + 476, 1114, 1114, 476, 476, 476, 476, 476, 476, 476, + + 476, 1114, 1114, 1114, 1114, 176, 176, 176, 301, 301, + 301, 301, 476, 476, 476, 476, 1114, 1114, 476, 476, + 476, 476, 476, 476, 1114, 1114, 476, 476, 476, 476, + 476, 1114, 1114, 301, 301, 301, 301, 301, 476, 476, + 476, 476, 1114, 1114, 476, 476, 476, 476, 476, 476, + 476, 476, 1114, 1114, 1114, 1114, 476, 476, 476, 476, + 476, 476, 476, 476, 1114, 1114, 1114, 1114, 1114, 1114, + 301, 301, 301, 301, 476, 476, 476, 476, 1114, 1114, + 476, 373, 582, 582, 582, 582, 582, 582, 582, 582, + 582, 582, 582, 582, 590, 590, 582, 582, 582, 590, + + 582, 582, 582, 582, 1102, 1102, 1102, 1102, 1102, 1102, + 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, + 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, + 1102, 1102, 1102, 1102, 1102, 1102, 276, 1102, 1127, 1102, + 1134, 1128, 1135, 1123, 1123, 1102, 1123, 1123, 1123, 1102, + 456, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, + 1102, 1102, 1102, 1102, 1131, 474, 475, 476, 668, 668, + 668, 668, 668, 476, 476, 476, 476, 1114, 1114, 668, + 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, + 668, 301, 301, 301, 301, 476, 476, 476, 476, 1114, + + 1114, 476, 668, 668, 668, 668, 668, 668, 668, 668, + 668, 668, 668, 668, 668, 668, 668, 668, 476, 476, + 476, 476, 476, 1114, 1114, 668, 668, 668, 668, 668, + 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, + 668, 668, 668, 668, 668, 476, 476, 476, 476, 1114, + 1114, 668, 668, 668, 668, 668, 582, 757, 757, 757, + 757, 757, 757, 757, 757, 757, 757, 757, 757, 757, + 757, 757, 757, 757, 757, 757, 757, 757, 1102, 1102, + 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, + 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, + + 1102, 1102, 1102, 1102, 1102, 1102, 1102, 276, 1102, 1102, + 1127, 1127, 1127, 1128, 1128, 1128, 1123, 1123, 649, 1136, + 1136, 1123, 1136, 649, 1102, 651, 1102, 1102, 1102, 1102, + 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1131, 474, + 475, 668, 842, 842, 842, 842, 668, 668, 668, 668, + 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, + 476, 476, 476, 476, 1114, 1114, 668, 668, 668, 668, + 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, + 842, 842, 842, 668, 668, 668, 668, 668, 842, 842, + 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, + + 842, 842, 842, 842, 842, 668, 668, 668, 668, 842, + 842, 842, 842, 1114, 1114, 1114, 1114, 1114, 1114, 1114, + 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, + 1114, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, + 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, + 1102, 1102, 826, 1127, 1127, 813, 1128, 1128, 816, 649, + 1136, 1102, 1136, 824, 1102, 1102, 1102, 1102, 1102, 1102, + 1102, 1102, 1102, 1102, 1102, 1114, 1114, 1114, 842, 842, + 842, 1114, 1114, 1114, 1114, 668, 668, 668, 668, 842, + 842, 842, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 842, + + 842, 842, 842, 1114, 1114, 1114, 1114, 1114, 1114, 1114, + 842, 842, 842, 1114, 1114, 1102, 1102, 1102, 1102, 1102, + 1102, 1102, 1102, 1102, 1102, 1102, 1102, 813, 816, 649, + 1136, 1136, 1136, 962, 824, 1102, 1102, 1102, 1102, 1102, + 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1114, 842, 842, + 842, 1114, 1114, 1114, 1114, 1102, 1102, 1102, 1102, 1102, + 813, 816, 649, 1136, 1033, 824, 1102, 1102, 1102, 1102, + 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1114, 1102, 813, + 816, 649, 1033, 824, 1102, 1102, 1102, 1102, 1102, 1102, + 813, 816, 1033, 1082, 1102, 1102, 1102, 1102, 1033, 1102, + + 1136, 0, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, + 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, + 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, + 1102, 1102, 1102, 1102, 1102, 1102 + } ; + +static const flex_int16_t yy_nxt[7190] = + { 0, + 4, 5, 6, 5, 5, 5, 7, 8, 9, 4, + 4, 10, 4, 4, 4, 11, 12, 13, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 15, 4, + 4, 16, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 18, 17, 17, 19, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 18, 17, 17, 20, 21, 17, 22, + 22, 22, 22, 22, 22, 22, 22, 22, 22, 23, + 23, 23, 23, 23, 28, 31, 28, 35, 63, 22, + + 22, 22, 22, 22, 63, 24, 38, 38, 38, 38, + 38, 38, 38, 38, 38, 38, 72, 1102, 1102, 75, + 44, 76, 133, 28, 58, 95, 73, 74, 25, 63, + 59, 75, 32, 76, 60, 1096, 37, 61, 72, 34, + 65, 29, 26, 96, 62, 133, 65, 58, 95, 77, + 253, 25, 40, 59, 32, 32, 60, 41, 42, 61, + 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, + 29, 65, 77, 253, 44, 44, 45, 46, 47, 44, + 48, 49, 50, 44, 51, 44, 52, 44, 44, 53, + 54, 55, 44, 44, 44, 44, 56, 44, 44, 45, + + 46, 47, 44, 48, 49, 50, 51, 44, 52, 44, + 44, 53, 54, 55, 44, 44, 44, 44, 63, 28, + 44, 1102, 63, 38, 38, 38, 38, 38, 38, 38, + 38, 38, 38, 102, 103, 23, 23, 23, 23, 23, + 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, + 100, 24, 1086, 93, 66, 102, 101, 28, 28, 1086, + 65, 161, 34, 94, 65, 75, 89, 76, 154, 174, + 167, 280, 100, 295, 25, 93, 66, 68, 68, 68, + 68, 68, 68, 68, 68, 68, 68, 106, 26, 28, + 104, 68, 68, 68, 68, 68, 68, 25, 1057, 105, + + 34, 97, 107, 108, 115, 29, 138, 1078, 109, 98, + 106, 99, 104, 110, 68, 68, 68, 68, 68, 68, + 27, 27, 79, 97, 134, 108, 116, 115, 139, 138, + 109, 98, 34, 158, 135, 159, 80, 80, 80, 80, + 80, 80, 80, 80, 80, 80, 134, 136, 63, 155, + 80, 80, 80, 80, 80, 80, 156, 277, 27, 33, + 63, 299, 328, 28, 174, 137, 1078, 329, 28, 330, + 136, 155, 1024, 80, 80, 80, 80, 80, 80, 83, + 83, 83, 83, 83, 83, 83, 83, 83, 83, 111, + 65, 150, 104, 83, 83, 83, 83, 83, 83, 65, + + 157, 105, 65, 1055, 158, 112, 159, 113, 193, 114, + 29, 34, 111, 150, 104, 72, 83, 83, 83, 83, + 83, 83, 33, 33, 85, 73, 160, 112, 100, 113, + 194, 193, 364, 1055, 101, 181, 365, 72, 86, 86, + 86, 86, 86, 86, 86, 86, 86, 86, 160, 67, + 100, 182, 86, 86, 86, 86, 86, 86, 181, 63, + 364, 1052, 1052, 28, 365, 183, 203, 1051, 640, 184, + 204, 185, 205, 1051, 1048, 86, 86, 86, 86, 86, + 86, 68, 68, 68, 68, 68, 68, 68, 68, 68, + 68, 175, 175, 206, 115, 68, 68, 68, 68, 68, + + 68, 65, 234, 1048, 207, 208, 234, 234, 234, 234, + 29, 643, 1043, 175, 175, 206, 116, 115, 68, 68, + 68, 68, 68, 68, 117, 117, 207, 1043, 950, 117, + 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, + 117, 117, 118, 119, 119, 119, 120, 121, 122, 123, + 119, 119, 117, 117, 117, 117, 119, 119, 119, 119, + 119, 119, 124, 125, 126, 117, 127, 117, 128, 117, + 117, 129, 130, 131, 117, 117, 117, 117, 117, 119, + 119, 119, 119, 119, 119, 124, 125, 126, 127, 117, + 128, 117, 117, 129, 130, 131, 117, 117, 117, 117, + + 117, 117, 117, 140, 227, 1018, 254, 141, 142, 143, + 144, 262, 843, 255, 844, 263, 288, 264, 229, 102, + 103, 417, 230, 228, 231, 145, 265, 227, 254, 146, + 106, 247, 147, 248, 249, 234, 234, 234, 234, 288, + 1018, 102, 266, 417, 175, 107, 267, 1016, 145, 265, + 268, 146, 269, 106, 147, 149, 149, 149, 149, 149, + 149, 149, 149, 149, 149, 1014, 175, 289, 260, 149, + 149, 149, 149, 149, 149, 458, 287, 1014, 280, 186, + 158, 271, 159, 187, 188, 189, 190, 261, 111, 272, + 289, 260, 149, 149, 149, 149, 149, 149, 67, 67, + + 67, 151, 67, 155, 112, 191, 113, 640, 114, 63, + 156, 111, 272, 192, 138, 152, 152, 152, 152, 152, + 152, 152, 152, 152, 152, 155, 112, 191, 113, 152, + 152, 152, 152, 152, 152, 192, 139, 138, 563, 199, + 1013, 281, 564, 176, 200, 176, 201, 117, 640, 282, + 643, 65, 152, 152, 152, 152, 152, 152, 163, 78, + 78, 164, 163, 281, 28, 175, 247, 1013, 248, 249, + 234, 234, 234, 234, 202, 165, 165, 165, 165, 165, + 165, 165, 165, 165, 165, 473, 305, 175, 295, 165, + 165, 165, 165, 165, 165, 641, 202, 256, 1008, 92, + + 270, 257, 271, 258, 141, 142, 143, 144, 136, 305, + 274, 29, 165, 165, 165, 165, 165, 165, 82, 82, + 82, 168, 82, 259, 290, 306, 137, 851, 75, 852, + 76, 136, 1008, 274, 1102, 169, 169, 169, 169, 169, + 169, 169, 169, 169, 169, 259, 134, 320, 306, 169, + 169, 169, 169, 169, 169, 283, 135, 302, 1006, 1006, + 284, 303, 285, 304, 78, 871, 1004, 872, 134, 28, + 320, 32, 169, 169, 169, 169, 169, 169, 170, 84, + 84, 171, 170, 311, 286, 322, 315, 312, 28, 313, + 316, 317, 318, 319, 175, 172, 172, 172, 172, 172, + + 172, 172, 172, 172, 172, 82, 286, 640, 322, 172, + 172, 172, 172, 172, 172, 325, 29, 193, 332, 326, + 1102, 327, 195, 333, 335, 334, 176, 196, 176, 197, + 323, 34, 172, 172, 172, 172, 172, 172, 119, 194, + 193, 175, 119, 119, 119, 119, 92, 335, 175, 324, + 643, 108, 198, 323, 336, 1004, 109, 32, 117, 117, + 117, 110, 117, 175, 117, 340, 84, 117, 117, 117, + 175, 993, 563, 108, 198, 28, 564, 336, 109, 341, + 355, 117, 117, 117, 117, 876, 117, 877, 340, 117, + 117, 117, 176, 176, 176, 176, 176, 176, 176, 176, + + 176, 176, 341, 355, 357, 425, 176, 176, 176, 176, + 176, 176, 993, 291, 291, 291, 292, 291, 34, 337, + 346, 992, 426, 338, 347, 339, 348, 357, 425, 176, + 176, 176, 176, 176, 176, 177, 176, 176, 176, 178, + 176, 179, 176, 176, 176, 426, 640, 992, 92, 176, + 176, 176, 176, 176, 176, 744, 72, 427, 209, 745, + 989, 180, 210, 213, 211, 989, 73, 214, 215, 216, + 217, 428, 176, 176, 176, 176, 176, 176, 72, 212, + 427, 220, 434, 180, 175, 221, 222, 223, 224, 218, + 207, 208, 350, 641, 219, 418, 351, 352, 353, 354, + + 435, 281, 212, 419, 307, 434, 175, 175, 308, 282, + 309, 218, 207, 225, 358, 226, 219, 418, 359, 360, + 361, 362, 369, 281, 310, 984, 370, 366, 371, 175, + 175, 367, 744, 368, 984, 225, 745, 226, 117, 117, + 117, 232, 117, 480, 374, 481, 982, 310, 374, 374, + 374, 374, 175, 175, 499, 233, 234, 234, 234, 235, + 236, 237, 238, 234, 234, 880, 480, 881, 481, 234, + 234, 234, 234, 234, 234, 175, 424, 499, 254, 420, + 257, 415, 258, 342, 421, 255, 422, 176, 343, 176, + 344, 92, 234, 234, 234, 234, 234, 234, 234, 982, + + 254, 239, 240, 241, 234, 242, 243, 244, 423, 175, + 429, 501, 523, 245, 430, 246, 431, 387, 345, 388, + 389, 374, 374, 374, 374, 399, 399, 399, 400, 399, + 423, 175, 981, 92, 501, 523, 245, 482, 246, 234, + 345, 524, 239, 240, 241, 234, 242, 243, 244, 482, + 482, 482, 483, 482, 250, 387, 251, 388, 389, 374, + 374, 374, 374, 432, 524, 148, 465, 263, 91, 264, + 440, 284, 100, 285, 268, 63, 269, 250, 101, 251, + 148, 148, 148, 275, 148, 981, 459, 436, 971, 92, + 91, 437, 460, 438, 100, 530, 971, 276, 276, 276, + + 276, 276, 276, 276, 276, 276, 276, 439, 459, 531, + 537, 276, 276, 276, 276, 276, 276, 65, 530, 415, + 415, 415, 416, 415, 889, 461, 890, 944, 538, 462, + 439, 463, 531, 537, 276, 276, 276, 276, 276, 276, + 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, + 374, 538, 944, 464, 278, 278, 278, 278, 278, 278, + 442, 910, 938, 911, 141, 142, 143, 144, 640, 938, + 467, 550, 92, 374, 158, 464, 159, 278, 278, 278, + 278, 278, 278, 293, 293, 293, 293, 293, 293, 293, + 293, 293, 293, 912, 550, 291, 605, 293, 293, 293, + + 293, 293, 293, 912, 445, 445, 445, 446, 445, 470, + 477, 643, 513, 75, 478, 76, 479, 514, 605, 515, + 293, 293, 293, 293, 293, 293, 296, 296, 296, 296, + 296, 296, 296, 296, 296, 296, 72, 72, 552, 136, + 296, 296, 296, 296, 296, 296, 73, 73, 92, 257, + 502, 258, 397, 397, 397, 398, 397, 137, 72, 72, + 932, 552, 136, 296, 296, 296, 296, 296, 296, 297, + 297, 297, 297, 297, 297, 297, 297, 297, 297, 102, + 103, 909, 932, 297, 297, 297, 297, 297, 297, 482, + 482, 482, 483, 482, 640, 97, 403, 403, 403, 404, + + 403, 102, 92, 98, 106, 99, 297, 297, 297, 297, + 297, 297, 175, 175, 175, 300, 175, 97, 484, 107, + 909, 520, 485, 903, 486, 98, 521, 106, 522, 301, + 301, 301, 301, 301, 301, 301, 301, 301, 301, 91, + 104, 641, 93, 301, 301, 301, 301, 301, 301, 105, + 903, 640, 94, 447, 447, 447, 448, 447, 897, 488, + 115, 91, 104, 489, 93, 490, 301, 301, 301, 301, + 301, 301, 373, 374, 374, 374, 375, 376, 377, 378, + 374, 374, 116, 115, 138, 659, 374, 374, 374, 374, + 374, 374, 394, 394, 394, 395, 394, 263, 641, 264, + + 504, 443, 443, 443, 444, 443, 139, 138, 659, 374, + 374, 374, 374, 374, 374, 374, 525, 532, 379, 380, + 381, 374, 382, 383, 384, 509, 897, 396, 660, 510, + 385, 511, 386, 891, 891, 91, 155, 401, 401, 401, + 402, 401, 494, 156, 134, 96, 495, 496, 497, 498, + 396, 660, 92, 385, 135, 386, 374, 91, 155, 379, + 380, 381, 374, 382, 383, 384, 134, 92, 92, 92, + 104, 390, 672, 391, 405, 405, 405, 406, 405, 105, + 91, 407, 407, 407, 408, 407, 401, 527, 873, 102, + 103, 528, 104, 529, 390, 672, 391, 392, 392, 392, + + 393, 392, 91, 873, 407, 407, 407, 408, 407, 539, + 673, 102, 106, 540, 374, 541, 553, 91, 374, 374, + 374, 374, 506, 870, 108, 534, 507, 107, 508, 109, + 535, 870, 536, 673, 110, 106, 555, 102, 103, 91, + 93, 405, 405, 405, 406, 405, 108, 108, 175, 545, + 94, 109, 109, 546, 547, 548, 549, 110, 923, 102, + 924, 925, 93, 409, 409, 409, 410, 409, 92, 108, + 175, 557, 374, 864, 109, 558, 559, 560, 561, 106, + 468, 468, 468, 469, 468, 268, 864, 269, 92, 445, + 445, 445, 446, 445, 107, 374, 411, 450, 450, 450, + + 450, 450, 106, 452, 571, 565, 91, 453, 572, 454, + 573, 575, 112, 97, 113, 576, 114, 577, 904, 411, + 859, 98, 905, 99, 136, 583, 155, 859, 91, 583, + 583, 583, 583, 156, 112, 97, 113, 412, 412, 412, + 413, 412, 137, 98, 284, 100, 285, 136, 155, 614, + 455, 101, 904, 257, 374, 258, 905, 92, 374, 374, + 374, 374, 502, 502, 502, 503, 502, 100, 414, 23, + 23, 23, 23, 23, 504, 504, 504, 505, 504, 502, + 502, 502, 503, 502, 689, 24, 757, 757, 757, 757, + 116, 414, 148, 148, 148, 275, 148, 525, 525, 525, + + 526, 525, 525, 525, 525, 526, 525, 689, 25, 449, + 449, 449, 449, 449, 449, 449, 449, 449, 449, 853, + 853, 418, 26, 449, 449, 449, 449, 449, 449, 419, + 92, 25, 468, 468, 468, 469, 468, 532, 532, 532, + 533, 532, 617, 418, 850, 850, 449, 449, 449, 449, + 449, 449, 456, 456, 456, 456, 456, 456, 456, 456, + 456, 456, 834, 181, 618, 617, 456, 456, 456, 456, + 456, 456, 532, 532, 532, 533, 532, 834, 155, 182, + 517, 517, 517, 518, 517, 156, 181, 803, 803, 456, + 456, 456, 456, 456, 456, 553, 553, 553, 554, 553, + + 155, 471, 471, 471, 471, 471, 471, 471, 471, 471, + 471, 519, 797, 138, 691, 471, 471, 471, 471, 471, + 471, 797, 755, 543, 543, 543, 544, 543, 555, 555, + 555, 556, 555, 194, 519, 139, 138, 691, 471, 471, + 471, 471, 471, 471, 474, 474, 474, 474, 474, 474, + 474, 474, 474, 474, 755, 193, 95, 712, 474, 474, + 474, 474, 474, 474, 553, 553, 553, 554, 553, 565, + 565, 565, 566, 565, 96, 207, 208, 194, 193, 95, + 712, 474, 474, 474, 474, 474, 474, 475, 475, 475, + 475, 475, 475, 475, 475, 475, 475, 207, 979, 749, + + 980, 475, 475, 475, 475, 475, 475, 567, 567, 567, + 568, 567, 749, 492, 492, 492, 493, 492, 569, 569, + 569, 570, 569, 392, 475, 475, 475, 475, 475, 475, + 476, 476, 476, 476, 476, 476, 476, 476, 476, 476, + 923, 713, 924, 925, 476, 476, 476, 476, 476, 476, + 181, 579, 579, 579, 580, 579, 596, 92, 597, 598, + 583, 583, 583, 583, 713, 93, 182, 476, 476, 476, + 476, 476, 476, 181, 596, 94, 597, 598, 583, 583, + 583, 583, 111, 567, 652, 581, 92, 93, 653, 92, + 415, 415, 415, 416, 415, 623, 743, 606, 112, 430, + + 113, 431, 114, 607, 228, 111, 652, 743, 581, 582, + 583, 583, 583, 584, 585, 586, 587, 583, 583, 606, + 112, 583, 113, 583, 583, 583, 583, 583, 583, 394, + 394, 394, 395, 394, 990, 92, 991, 92, 397, 397, + 397, 398, 397, 92, 583, 92, 583, 583, 583, 583, + 583, 583, 583, 736, 736, 588, 589, 590, 583, 591, + 592, 593, 1009, 612, 601, 717, 1010, 594, 421, 595, + 422, 394, 91, 399, 399, 399, 399, 400, 399, 583, + 397, 97, 96, 583, 583, 583, 583, 601, 717, 98, + 594, 99, 595, 583, 91, 729, 588, 589, 590, 583, + + 591, 592, 593, 97, 281, 95, 718, 1000, 599, 1001, + 600, 98, 282, 405, 608, 729, 92, 91, 609, 100, + 610, 100, 97, 96, 403, 101, 281, 101, 95, 718, + 98, 599, 99, 600, 392, 392, 392, 393, 392, 91, + 569, 100, 611, 100, 97, 401, 401, 401, 402, 401, + 106, 583, 98, 207, 208, 583, 583, 583, 583, 403, + 403, 403, 404, 403, 611, 107, 92, 104, 405, 405, + 405, 406, 405, 106, 678, 207, 105, 93, 459, 407, + 407, 407, 408, 407, 460, 706, 108, 94, 91, 104, + 412, 109, 92, 1011, 706, 1012, 110, 102, 103, 93, + + 459, 625, 91, 104, 492, 263, 106, 264, 108, 543, + 91, 91, 105, 109, 407, 407, 407, 408, 407, 102, + 115, 107, 108, 661, 91, 104, 92, 109, 284, 106, + 285, 699, 110, 91, 405, 405, 405, 406, 405, 699, + 181, 583, 116, 115, 108, 583, 583, 583, 583, 109, + 409, 409, 409, 410, 409, 722, 182, 108, 604, 409, + 207, 208, 109, 181, 628, 583, 407, 110, 629, 583, + 630, 723, 106, 583, 583, 583, 583, 228, 722, 108, + 724, 604, 207, 602, 109, 695, 631, 107, 583, 181, + 437, 111, 438, 91, 723, 106, 735, 695, 619, 112, + + 134, 113, 620, 114, 621, 182, 602, 112, 108, 113, + 135, 114, 181, 109, 111, 91, 92, 92, 110, 735, + 622, 112, 134, 113, 412, 412, 412, 413, 412, 112, + 108, 113, 92, 690, 690, 109, 615, 615, 615, 616, + 615, 583, 445, 622, 434, 583, 583, 583, 583, 615, + 615, 615, 616, 615, 443, 603, 626, 626, 626, 627, + 626, 683, 435, 447, 633, 737, 683, 434, 268, 136, + 269, 634, 634, 634, 635, 634, 136, 116, 603, 636, + 677, 677, 254, 141, 142, 143, 144, 137, 737, 255, + 260, 92, 136, 138, 137, 254, 134, 658, 473, 136, + + 703, 462, 255, 463, 254, 704, 135, 705, 265, 261, + 421, 458, 422, 260, 654, 139, 138, 254, 134, 655, + 632, 656, 664, 669, 266, 632, 158, 670, 159, 671, + 517, 265, 637, 637, 637, 637, 637, 637, 637, 637, + 637, 637, 779, 468, 657, 787, 637, 637, 637, 637, + 637, 637, 450, 450, 450, 450, 450, 674, 452, 624, + 193, 675, 453, 676, 454, 779, 657, 624, 787, 637, + 637, 637, 637, 637, 637, 638, 638, 638, 638, 638, + 680, 1102, 194, 193, 681, 1102, 682, 454, 155, 482, + 482, 482, 483, 482, 613, 156, 482, 482, 482, 483, + + 482, 613, 684, 788, 845, 455, 685, 686, 687, 688, + 155, 678, 678, 678, 679, 678, 502, 502, 502, 503, + 502, 504, 504, 504, 505, 504, 788, 845, 455, 644, + 645, 646, 646, 646, 645, 647, 644, 647, 647, 647, + 644, 644, 648, 647, 647, 647, 647, 649, 649, 649, + 649, 649, 649, 649, 649, 649, 649, 647, 647, 647, + 647, 649, 649, 649, 649, 649, 649, 647, 647, 647, + 647, 647, 647, 647, 647, 647, 647, 647, 647, 647, + 647, 647, 647, 650, 649, 649, 649, 649, 649, 649, + 647, 647, 647, 647, 647, 647, 647, 647, 647, 647, + + 647, 647, 647, 647, 647, 647, 647, 647, 67, 67, + 67, 151, 67, 92, 578, 662, 662, 662, 663, 662, + 492, 492, 492, 493, 492, 651, 651, 651, 651, 651, + 651, 651, 651, 651, 651, 757, 757, 757, 757, 651, + 651, 651, 651, 651, 651, 502, 502, 502, 503, 502, + 692, 708, 578, 574, 693, 696, 694, 181, 574, 697, + 281, 698, 651, 651, 651, 651, 651, 651, 282, 562, + 324, 709, 562, 182, 708, 714, 710, 551, 711, 715, + 181, 716, 281, 163, 78, 78, 164, 163, 551, 28, + 525, 525, 525, 526, 525, 700, 700, 700, 701, 700, + + 665, 665, 665, 665, 665, 665, 665, 665, 665, 665, + 757, 757, 757, 757, 665, 665, 665, 665, 665, 665, + 525, 525, 525, 526, 525, 430, 542, 431, 254, 702, + 532, 532, 532, 533, 532, 255, 29, 665, 665, 665, + 665, 665, 665, 82, 82, 82, 168, 82, 324, 719, + 254, 780, 702, 542, 720, 781, 721, 30, 92, 516, + 666, 666, 666, 666, 666, 666, 666, 666, 666, 666, + 437, 516, 438, 780, 666, 666, 666, 666, 666, 666, + 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 32, 666, 666, 666, + + 666, 666, 666, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, 512, 617, + 30, 667, 667, 667, 667, 667, 667, 667, 667, 667, + 667, 141, 142, 143, 144, 667, 667, 667, 667, 667, + 667, 618, 617, 517, 517, 517, 518, 517, 532, 532, + 532, 533, 532, 724, 724, 724, 725, 724, 667, 667, + 667, 667, 667, 667, 668, 668, 668, 668, 668, 668, + 668, 668, 668, 668, 707, 462, 265, 463, 668, 668, + 668, 668, 668, 668, 724, 724, 724, 725, 724, 726, + 512, 827, 266, 727, 746, 728, 194, 707, 747, 265, + + 748, 668, 668, 668, 668, 668, 668, 543, 543, 543, + 544, 543, 730, 828, 827, 846, 731, 732, 733, 734, + 553, 553, 553, 554, 553, 555, 555, 555, 556, 555, + 553, 553, 553, 554, 553, 738, 579, 750, 846, 739, + 740, 741, 742, 565, 565, 565, 566, 565, 567, 567, + 567, 568, 567, 569, 569, 569, 570, 569, 92, 207, + 208, 750, 750, 750, 751, 750, 752, 227, 500, 227, + 753, 500, 754, 579, 579, 579, 580, 579, 786, 1009, + 789, 207, 609, 1010, 610, 421, 228, 422, 228, 92, + 227, 770, 227, 771, 772, 757, 757, 757, 757, 770, + + 491, 771, 772, 757, 757, 757, 757, 756, 792, 793, + 642, 833, 257, 794, 258, 795, 655, 491, 656, 640, + 415, 415, 415, 416, 415, 1049, 228, 1050, 92, 487, + 756, 757, 757, 757, 757, 758, 759, 760, 761, 757, + 757, 757, 757, 757, 757, 757, 757, 757, 757, 757, + 757, 762, 763, 764, 757, 765, 766, 767, 757, 757, + 757, 757, 643, 768, 487, 769, 615, 299, 757, 757, + 757, 757, 757, 757, 181, 762, 763, 764, 757, 765, + 766, 767, 854, 855, 856, 857, 768, 773, 769, 774, + 182, 757, 757, 757, 757, 782, 858, 181, 473, 606, + + 783, 838, 784, 796, 778, 607, 284, 620, 285, 621, + 773, 254, 774, 392, 392, 392, 393, 392, 255, 858, + 798, 606, 466, 228, 430, 785, 431, 778, 482, 482, + 482, 483, 482, 254, 757, 757, 757, 757, 260, 790, + 790, 790, 791, 790, 801, 652, 860, 785, 263, 653, + 264, 799, 799, 799, 800, 799, 93, 261, 802, 804, + 626, 260, 629, 437, 630, 438, 94, 652, 466, 860, + 805, 805, 805, 806, 805, 634, 458, 441, 93, 394, + 394, 394, 395, 394, 418, 807, 878, 879, 441, 268, + 427, 269, 419, 260, 433, 638, 638, 638, 638, 638, + + 757, 757, 757, 757, 428, 434, 418, 454, 433, 878, + 879, 265, 261, 427, 775, 372, 260, 809, 809, 809, + 809, 809, 609, 435, 610, 639, 829, 266, 434, 810, + 640, 830, 96, 831, 265, 372, 865, 775, 397, 397, + 397, 398, 397, 638, 638, 638, 638, 638, 835, 1102, + 92, 92, 462, 1102, 463, 454, 882, 92, 832, 757, + 757, 757, 757, 363, 638, 638, 638, 638, 638, 847, + 1102, 363, 883, 848, 1102, 849, 454, 641, 92, 882, + 832, 97, 646, 646, 646, 646, 646, 662, 92, 98, + 620, 99, 621, 92, 454, 883, 455, 356, 638, 638, + + 638, 638, 638, 97, 1102, 629, 356, 630, 1102, 887, + 454, 98, 399, 399, 399, 400, 399, 455, 638, 638, + 638, 638, 638, 861, 1102, 349, 349, 862, 1102, 863, + 454, 281, 887, 757, 757, 757, 757, 92, 92, 282, + 836, 836, 836, 837, 836, 836, 836, 836, 837, 836, + 655, 455, 656, 281, 482, 482, 482, 483, 482, 100, + 678, 678, 678, 679, 678, 101, 502, 502, 502, 503, + 502, 455, 323, 492, 492, 492, 493, 492, 875, 888, + 92, 100, 401, 401, 401, 402, 401, 459, 896, 898, + 867, 324, 459, 460, 868, 323, 869, 324, 460, 700, + + 331, 875, 888, 757, 757, 757, 757, 331, 92, 459, + 181, 896, 898, 92, 459, 504, 504, 504, 505, 504, + 502, 502, 502, 503, 502, 321, 182, 865, 865, 865, + 866, 865, 323, 181, 102, 103, 700, 700, 700, 701, + 700, 517, 517, 517, 518, 517, 525, 525, 525, 526, + 525, 324, 783, 321, 784, 323, 102, 403, 403, 403, + 404, 403, 525, 525, 525, 526, 525, 977, 314, 931, + 708, 314, 874, 532, 532, 532, 533, 532, 757, 757, + 757, 757, 532, 532, 532, 533, 532, 92, 228, 324, + 977, 884, 931, 708, 194, 874, 885, 794, 886, 795, + + 418, 104, 724, 724, 724, 725, 724, 814, 419, 92, + 105, 724, 724, 724, 725, 724, 640, 543, 543, 543, + 544, 543, 418, 104, 405, 405, 405, 406, 405, 892, + 893, 894, 895, 553, 553, 553, 554, 553, 555, 555, + 555, 556, 555, 92, 299, 757, 757, 757, 757, 553, + 553, 553, 554, 553, 899, 900, 901, 902, 167, 643, + 181, 978, 106, 565, 565, 565, 566, 565, 154, 207, + 208, 567, 567, 567, 568, 567, 182, 107, 569, 569, + 569, 570, 569, 181, 978, 106, 407, 407, 407, 408, + 407, 207, 906, 273, 273, 983, 907, 985, 908, 750, + + 750, 750, 751, 750, 252, 915, 916, 917, 427, 918, + 919, 920, 579, 579, 579, 580, 579, 921, 983, 922, + 985, 92, 428, 392, 392, 392, 393, 392, 937, 108, + 827, 427, 780, 783, 109, 784, 781, 91, 92, 110, + 921, 92, 922, 915, 916, 917, 913, 918, 919, 920, + 92, 108, 828, 827, 780, 926, 109, 927, 790, 91, + 409, 409, 409, 410, 409, 228, 93, 92, 995, 913, + 394, 394, 394, 395, 394, 830, 94, 831, 926, 92, + 927, 415, 415, 415, 416, 415, 939, 324, 93, 434, + 609, 995, 610, 776, 92, 92, 397, 397, 397, 398, + + 397, 942, 418, 91, 92, 928, 421, 435, 422, 112, + 419, 113, 434, 114, 92, 92, 776, 399, 399, 399, + 400, 399, 933, 96, 418, 91, 943, 934, 928, 935, + 794, 112, 795, 113, 412, 412, 412, 413, 412, 97, + 92, 965, 401, 401, 401, 402, 401, 98, 92, 99, + 966, 934, 89, 935, 936, 757, 757, 757, 757, 167, + 162, 97, 945, 965, 100, 777, 620, 162, 621, 98, + 101, 403, 403, 403, 404, 403, 936, 154, 996, 405, + 405, 405, 406, 405, 799, 997, 100, 116, 777, 405, + 405, 405, 406, 405, 102, 103, 407, 407, 407, 408, + + 407, 996, 132, 412, 412, 412, 413, 412, 997, 92, + 757, 757, 757, 757, 948, 104, 102, 106, 430, 949, + 431, 965, 427, 629, 105, 630, 805, 106, 92, 952, + 966, 90, 107, 437, 930, 438, 428, 104, 89, 108, + 106, 970, 107, 965, 109, 427, 830, 87, 831, 110, + 106, 407, 407, 407, 408, 407, 116, 930, 967, 975, + 434, 108, 968, 462, 969, 463, 109, 940, 940, 940, + 941, 940, 950, 950, 950, 951, 950, 998, 435, 968, + 1039, 969, 1040, 434, 405, 405, 405, 406, 405, 809, + 809, 809, 809, 809, 108, 999, 81, 71, 972, 109, + + 998, 810, 91, 655, 110, 656, 407, 407, 407, 408, + 407, 986, 70, 459, 606, 987, 108, 988, 999, 460, + 607, 109, 106, 1002, 91, 808, 808, 808, 808, 808, + 808, 808, 808, 808, 808, 459, 606, 107, 1003, 808, + 808, 808, 808, 808, 808, 106, 1002, 69, 1017, 108, + 1005, 1007, 1022, 934, 109, 935, 609, 57, 610, 110, + 617, 1003, 808, 808, 808, 808, 808, 808, 639, 639, + 812, 108, 1053, 1005, 1007, 39, 109, 946, 946, 946, + 947, 946, 618, 617, 813, 813, 813, 813, 813, 813, + 813, 813, 813, 813, 1102, 1053, 1054, 1072, 813, 813, + + 813, 813, 813, 813, 1068, 1102, 1069, 1102, 617, 482, + 482, 482, 483, 482, 482, 482, 482, 483, 482, 1054, + 1072, 813, 813, 813, 813, 813, 813, 642, 642, 815, + 618, 617, 678, 678, 678, 679, 678, 502, 502, 502, + 503, 502, 1102, 816, 816, 816, 816, 816, 816, 816, + 816, 816, 816, 1102, 1073, 1102, 1102, 816, 816, 816, + 816, 816, 816, 638, 638, 638, 638, 638, 1023, 1102, + 1102, 1019, 794, 1102, 795, 454, 783, 1073, 784, 1102, + 816, 816, 816, 816, 816, 816, 817, 817, 817, 818, + 817, 606, 1102, 1102, 1102, 1026, 1102, 607, 454, 620, + + 1102, 621, 1102, 819, 819, 819, 819, 819, 819, 819, + 819, 819, 819, 606, 1102, 1102, 455, 819, 819, 819, + 819, 819, 819, 504, 504, 504, 505, 504, 502, 502, + 502, 503, 502, 865, 865, 865, 866, 865, 1102, 455, + 819, 819, 819, 819, 819, 819, 820, 821, 638, 638, + 638, 821, 822, 820, 822, 822, 822, 820, 820, 823, + 822, 822, 822, 822, 824, 824, 824, 824, 824, 824, + 824, 824, 824, 824, 822, 822, 822, 822, 824, 824, + 824, 824, 824, 824, 822, 822, 822, 822, 822, 822, + 822, 822, 822, 822, 822, 822, 822, 822, 822, 822, + + 825, 824, 824, 824, 824, 824, 824, 822, 822, 822, + 822, 822, 822, 822, 822, 822, 822, 822, 822, 822, + 822, 822, 822, 822, 822, 826, 826, 826, 826, 826, + 826, 826, 826, 826, 826, 1102, 1102, 1102, 1102, 826, + 826, 826, 826, 826, 826, 638, 817, 638, 638, 638, + 1027, 1102, 1102, 1044, 629, 1102, 630, 454, 830, 1102, + 831, 1102, 826, 826, 826, 826, 826, 826, 163, 78, + 78, 164, 163, 827, 28, 525, 525, 525, 526, 525, + 525, 525, 525, 526, 525, 839, 839, 839, 839, 839, + 839, 839, 839, 839, 839, 828, 827, 1102, 455, 839, + + 839, 839, 839, 839, 839, 646, 646, 646, 646, 646, + 973, 973, 973, 974, 973, 1102, 1036, 454, 1102, 1102, + 1037, 29, 839, 839, 839, 839, 839, 839, 840, 840, + 840, 840, 840, 840, 840, 840, 840, 840, 1036, 1102, + 1102, 1102, 840, 840, 840, 840, 840, 840, 638, 638, + 638, 638, 638, 517, 517, 517, 518, 517, 962, 652, + 454, 1102, 1102, 653, 1102, 840, 840, 840, 840, 840, + 840, 841, 841, 841, 841, 841, 841, 841, 841, 841, + 841, 652, 1102, 1102, 994, 841, 841, 841, 841, 841, + 841, 1102, 638, 638, 638, 638, 638, 1102, 1102, 1042, + + 1102, 962, 1102, 968, 454, 969, 194, 994, 841, 841, + 841, 841, 841, 841, 842, 842, 842, 842, 842, 842, + 842, 842, 842, 842, 1102, 1102, 1102, 1102, 842, 842, + 842, 842, 842, 842, 1102, 1102, 940, 940, 940, 941, + 940, 836, 1102, 1102, 1102, 455, 532, 532, 532, 533, + 532, 842, 842, 842, 842, 842, 842, 914, 914, 914, + 914, 914, 914, 914, 914, 914, 914, 1102, 1102, 1102, + 1102, 914, 914, 914, 914, 914, 914, 946, 646, 646, + 646, 646, 646, 606, 652, 1102, 1102, 459, 653, 607, + 454, 1102, 1102, 460, 914, 914, 914, 914, 914, 914, + + 409, 409, 409, 410, 409, 606, 652, 617, 1102, 459, + 163, 78, 78, 164, 163, 1102, 28, 532, 532, 532, + 533, 532, 724, 724, 724, 725, 724, 1102, 780, 618, + 617, 962, 781, 929, 724, 724, 724, 725, 724, 553, + 553, 553, 554, 553, 555, 555, 555, 556, 555, 112, + 780, 113, 1102, 114, 1102, 1102, 929, 553, 553, 553, + 554, 553, 1102, 29, 565, 565, 565, 566, 565, 1102, + 1102, 112, 1102, 113, 953, 953, 953, 953, 953, 953, + 953, 953, 953, 953, 1102, 1102, 1102, 1102, 953, 953, + 953, 953, 953, 953, 492, 492, 492, 493, 492, 567, + + 567, 567, 568, 567, 569, 569, 569, 570, 569, 1102, + 1102, 953, 953, 953, 953, 953, 953, 954, 811, 811, + 955, 954, 1102, 640, 750, 750, 750, 751, 750, 1102, + 1102, 181, 1102, 1102, 956, 956, 956, 956, 956, 956, + 956, 956, 956, 956, 1102, 1102, 1102, 182, 956, 956, + 956, 956, 956, 956, 181, 1024, 1024, 1024, 1025, 1024, + 148, 148, 148, 275, 148, 678, 678, 678, 679, 678, + 641, 956, 956, 956, 956, 956, 956, 957, 814, 814, + 958, 957, 1036, 1047, 1056, 1102, 1037, 640, 655, 934, + 656, 935, 1102, 1102, 959, 959, 959, 959, 959, 959, + + 959, 959, 959, 959, 1036, 1102, 1102, 1102, 959, 959, + 959, 959, 959, 959, 700, 700, 700, 701, 700, 1102, + 543, 543, 543, 544, 543, 865, 865, 865, 866, 865, + 643, 959, 959, 959, 959, 959, 959, 960, 960, 960, + 960, 960, 960, 960, 960, 960, 960, 1102, 875, 1102, + 1102, 960, 960, 960, 960, 960, 960, 117, 117, 117, + 232, 117, 1060, 1102, 1102, 811, 794, 324, 795, 1102, + 640, 875, 207, 208, 960, 960, 960, 960, 960, 960, + 821, 821, 821, 963, 821, 724, 724, 724, 725, 724, + 1102, 1102, 1102, 1102, 207, 1102, 1102, 964, 964, 964, + + 964, 964, 964, 964, 964, 964, 964, 1102, 1102, 1102, + 92, 964, 964, 964, 964, 964, 964, 641, 724, 724, + 724, 725, 724, 750, 750, 750, 751, 750, 1057, 1057, + 1057, 1058, 1057, 1102, 964, 964, 964, 964, 964, 964, + 644, 645, 646, 646, 646, 645, 647, 644, 647, 647, + 647, 644, 644, 648, 647, 647, 647, 647, 649, 649, + 649, 649, 649, 649, 649, 649, 649, 649, 647, 647, + 647, 647, 649, 649, 649, 649, 649, 649, 647, 647, + 647, 647, 647, 647, 647, 647, 647, 647, 647, 647, + 647, 647, 647, 647, 650, 649, 649, 649, 649, 649, + + 649, 647, 647, 647, 647, 647, 647, 647, 647, 647, + 647, 647, 647, 647, 647, 647, 647, 647, 647, 64, + 64, 64, 64, 64, 64, 64, 64, 64, 64, 1102, + 1102, 1102, 1102, 64, 64, 64, 64, 64, 64, 579, + 579, 579, 580, 579, 412, 412, 412, 413, 412, 1071, + 1036, 1102, 1102, 1039, 1037, 1040, 64, 64, 64, 64, + 64, 64, 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 1036, 1015, 1102, 115, 30, 30, 30, 30, + 30, 30, 394, 394, 394, 395, 394, 1102, 1102, 1038, + 1102, 1102, 228, 1039, 1102, 1040, 1015, 116, 115, 30, + + 30, 30, 30, 30, 30, 33, 33, 33, 33, 33, + 33, 33, 33, 33, 33, 1102, 1041, 95, 1102, 33, + 33, 33, 33, 33, 33, 1102, 392, 392, 392, 393, + 392, 1102, 1059, 1102, 1102, 96, 1102, 783, 1041, 784, + 95, 1102, 33, 33, 33, 33, 33, 33, 976, 976, + 976, 976, 976, 976, 976, 976, 976, 976, 1102, 1102, + 1102, 1102, 976, 976, 976, 976, 976, 976, 1102, 93, + 397, 397, 397, 398, 397, 1102, 1102, 973, 940, 94, + 399, 399, 399, 400, 399, 976, 976, 976, 976, 976, + 976, 93, 401, 401, 401, 402, 401, 403, 403, 403, + + 404, 403, 1102, 1102, 405, 405, 405, 406, 405, 1045, + 1102, 1102, 1102, 97, 1102, 1102, 407, 407, 407, 408, + 407, 98, 1074, 99, 606, 652, 968, 100, 969, 653, + 607, 1077, 1102, 101, 1102, 97, 830, 1102, 831, 827, + 1102, 104, 106, 98, 102, 103, 606, 652, 1102, 100, + 105, 415, 415, 415, 416, 415, 1102, 107, 1102, 108, + 1102, 828, 827, 104, 109, 106, 102, 1102, 1102, 110, + 405, 405, 405, 406, 405, 1102, 407, 407, 407, 408, + 407, 108, 1075, 1102, 1102, 1102, 109, 409, 409, 409, + 410, 409, 1102, 1102, 1102, 117, 117, 117, 232, 117, + + 1079, 1102, 1102, 1102, 92, 934, 1102, 935, 106, 117, + 117, 117, 232, 117, 117, 117, 117, 232, 117, 108, + 111, 1085, 1102, 107, 109, 965, 1068, 1102, 1069, 110, + 1102, 106, 181, 1087, 966, 1102, 112, 1039, 113, 1040, + 114, 108, 1102, 111, 1102, 1102, 109, 965, 182, 117, + 117, 117, 232, 117, 1102, 181, 1102, 1090, 112, 1095, + 113, 968, 92, 969, 1068, 1102, 1069, 92, 1020, 1020, + 1020, 1021, 1020, 646, 646, 646, 646, 646, 638, 821, + 638, 638, 638, 227, 1102, 454, 1102, 1102, 1102, 1102, + 454, 865, 865, 865, 866, 865, 1102, 1045, 1045, 1045, + + 1046, 1045, 228, 1102, 1102, 1102, 227, 175, 175, 175, + 300, 175, 482, 482, 482, 483, 482, 780, 1098, 1102, + 1067, 781, 1039, 1020, 1040, 1068, 962, 1069, 827, 1102, + 1102, 962, 1096, 1096, 1096, 1097, 1096, 1102, 1102, 780, + 1028, 1028, 1028, 1028, 1028, 1028, 1028, 1028, 1028, 1028, + 828, 827, 1070, 1102, 1028, 1028, 1028, 1028, 1028, 1028, + 92, 1102, 1102, 1102, 1102, 92, 482, 482, 482, 483, + 482, 780, 1102, 1102, 1070, 781, 1102, 1028, 1028, 1028, + 1028, 1028, 1028, 1029, 1029, 1029, 1029, 1029, 1029, 1029, + 1029, 1029, 1029, 780, 1102, 1102, 1102, 1029, 1029, 1029, + + 1029, 1029, 1029, 502, 502, 502, 503, 502, 504, 504, + 504, 505, 504, 821, 821, 821, 963, 821, 1102, 92, + 1029, 1029, 1029, 1029, 1029, 1029, 1030, 1030, 1030, 1030, + 1030, 1030, 1030, 1030, 1030, 1030, 1102, 1102, 1102, 1102, + 1030, 1030, 1030, 1030, 1030, 1030, 1100, 1102, 1102, 1102, + 1102, 1068, 1102, 1069, 1102, 1102, 92, 1102, 1102, 1102, + 1102, 92, 1102, 1030, 1030, 1030, 1030, 1030, 1030, 820, + 1031, 646, 646, 646, 1031, 1032, 820, 1032, 1032, 1032, + 820, 820, 823, 1032, 1032, 1032, 1032, 1033, 1033, 1033, + 1033, 1033, 1033, 1033, 1033, 1033, 1033, 1032, 1032, 1032, + + 1032, 1033, 1033, 1033, 1033, 1033, 1033, 1032, 1032, 1032, + 1032, 1032, 1032, 1032, 1032, 1032, 1032, 1032, 1032, 1032, + 1032, 1032, 1032, 1034, 1033, 1033, 1033, 1033, 1033, 1033, + 1032, 1032, 1032, 1032, 1032, 1032, 1032, 1032, 1032, 1032, + 1032, 1032, 1032, 1032, 1032, 1032, 1032, 1032, 1035, 1035, + 1035, 1035, 1035, 1035, 1035, 1035, 1035, 1035, 1102, 1102, + 1102, 1102, 1035, 1035, 1035, 1035, 1035, 1035, 492, 492, + 492, 493, 492, 502, 502, 502, 503, 502, 700, 700, + 700, 701, 700, 1102, 1102, 1035, 1035, 1035, 1035, 1035, + 1035, 517, 517, 517, 518, 517, 175, 175, 175, 300, + + 175, 1102, 1102, 1102, 1102, 181, 175, 175, 175, 300, + 175, 1102, 995, 525, 525, 525, 526, 525, 1102, 1102, + 1102, 182, 193, 1102, 1102, 1102, 92, 1102, 181, 1102, + 323, 324, 1102, 1102, 1102, 995, 525, 525, 525, 526, + 525, 1102, 1102, 1102, 194, 193, 1102, 1102, 1102, 324, + 1102, 1102, 1102, 323, 532, 532, 532, 533, 532, 92, + 532, 532, 532, 533, 532, 1102, 92, 543, 543, 543, + 544, 543, 553, 553, 553, 554, 553, 555, 555, 555, + 556, 555, 553, 553, 553, 554, 553, 1102, 1088, 92, + 565, 565, 565, 566, 565, 567, 567, 567, 568, 567, + + 569, 569, 569, 570, 569, 1102, 1102, 92, 579, 579, + 579, 580, 579, 92, 175, 175, 175, 300, 175, 207, + 208, 1102, 1102, 1102, 1102, 92, 1102, 1102, 1102, 1102, + 92, 1102, 1102, 1102, 1102, 92, 1036, 1102, 1102, 1102, + 1037, 207, 227, 92, 1102, 1102, 1102, 1102, 92, 1102, + 1102, 1102, 1102, 92, 1102, 1102, 1102, 1102, 1036, 1102, + 1102, 228, 1102, 1102, 1102, 227, 1102, 92, 1061, 1061, + 1061, 1061, 1061, 1061, 1061, 1061, 1061, 1061, 1102, 1102, + 1102, 1102, 1061, 1061, 1061, 1061, 1061, 1061, 646, 646, + 646, 646, 646, 678, 678, 678, 679, 678, 1102, 1102, + + 454, 1102, 1102, 1102, 1102, 1061, 1061, 1061, 1061, 1061, + 1061, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, + 1062, 1102, 1102, 1102, 1102, 1062, 1062, 1062, 1062, 1062, + 1062, 646, 646, 646, 646, 646, 1075, 1075, 1075, 1076, + 1075, 962, 1102, 454, 1102, 1102, 92, 1102, 1062, 1062, + 1062, 1062, 1062, 1062, 1063, 1063, 1063, 1063, 1063, 1063, + 1063, 1063, 1063, 1063, 1102, 1102, 1102, 1102, 1063, 1063, + 1063, 1063, 1063, 1063, 724, 724, 724, 725, 724, 1102, + 965, 1102, 1102, 1102, 962, 1102, 1102, 1102, 1102, 966, + 1102, 1063, 1063, 1063, 1063, 1063, 1063, 1031, 1031, 1031, + + 1064, 1031, 965, 1102, 1102, 1102, 1102, 1102, 1102, 454, + 1102, 1102, 1102, 1102, 1065, 1065, 1065, 1065, 1065, 1065, + 1065, 1065, 1065, 1065, 1102, 1102, 1102, 92, 1065, 1065, + 1065, 1065, 1065, 1065, 700, 700, 700, 701, 700, 724, + 724, 724, 725, 724, 1102, 1102, 1102, 1102, 1102, 1102, + 962, 1065, 1065, 1065, 1065, 1065, 1065, 1066, 1066, 1066, + 1066, 1066, 1066, 1066, 1066, 1066, 1066, 1102, 323, 1102, + 1102, 1066, 1066, 1066, 1066, 1066, 1066, 750, 750, 750, + 751, 750, 1102, 1102, 1102, 1102, 1102, 324, 1102, 1102, + 1102, 323, 92, 1102, 1066, 1066, 1066, 1066, 1066, 1066, + + 646, 1031, 646, 646, 646, 1102, 1102, 1102, 1102, 1102, + 1102, 1102, 454, 1088, 1088, 1088, 1089, 1088, 1102, 1102, + 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, + 92, 1080, 1080, 1080, 1080, 1080, 1080, 1080, 1080, 1080, + 1080, 1102, 1102, 1102, 1102, 1080, 1080, 1080, 1080, 1080, + 1080, 1102, 1102, 962, 1102, 1102, 1088, 1088, 1088, 1089, + 1088, 1102, 1036, 1102, 1102, 1102, 1037, 1102, 1080, 1080, + 1080, 1080, 1080, 1080, 1081, 1081, 1081, 1081, 1081, 1081, + 1081, 1081, 1081, 1081, 1036, 1102, 1102, 1102, 1081, 1081, + 1081, 1081, 1081, 1081, 865, 865, 865, 866, 865, 1102, + + 1102, 1102, 1102, 1102, 1102, 1036, 1102, 1102, 1102, 1037, + 1102, 1081, 1081, 1081, 1081, 1081, 1081, 1082, 1082, 1082, + 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1036, 1102, 1102, + 1102, 1082, 1082, 1082, 1082, 1082, 1082, 1031, 1031, 1031, + 1064, 1031, 1102, 1102, 1102, 1102, 1102, 92, 1102, 454, + 1102, 1102, 1102, 1102, 1082, 1082, 1082, 1082, 1082, 1082, + 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, + 1102, 1102, 1102, 1102, 1083, 1083, 1083, 1083, 1083, 1083, + 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, + 962, 1102, 1102, 1102, 1102, 1102, 1102, 1083, 1083, 1083, + + 1083, 1083, 1083, 1084, 1084, 1084, 1084, 1084, 1084, 1084, + 1084, 1084, 1084, 1102, 1102, 1102, 1102, 1084, 1084, 1084, + 1084, 1084, 1084, 1102, 1102, 1102, 1102, 1102, 1102, 1102, + 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, + 1084, 1084, 1084, 1084, 1084, 1084, 1091, 1091, 1091, 1091, + 1091, 1091, 1091, 1091, 1091, 1091, 1102, 1102, 1102, 1102, + 1091, 1091, 1091, 1091, 1091, 1091, 1102, 1102, 1102, 1102, + 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, + 1102, 1102, 1102, 1091, 1091, 1091, 1091, 1091, 1091, 1092, + 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1102, + + 1102, 1102, 1102, 1092, 1092, 1092, 1092, 1092, 1092, 1102, + 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, + 1102, 1102, 1102, 1102, 1102, 1102, 1092, 1092, 1092, 1092, + 1092, 1092, 451, 451, 451, 451, 451, 451, 451, 451, + 451, 451, 1102, 1102, 1102, 1102, 451, 451, 451, 451, + 451, 451, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, + 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 451, + 451, 451, 451, 451, 451, 1093, 1093, 1093, 1093, 1093, + 1093, 1093, 1093, 1093, 1093, 1102, 1102, 1102, 1102, 1093, + 1093, 1093, 1093, 1093, 1093, 1102, 1102, 1102, 1102, 1102, + + 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, + 1102, 1102, 1093, 1093, 1093, 1093, 1093, 1093, 1094, 1094, + 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1102, 1102, + 1102, 1102, 1094, 1094, 1094, 1094, 1094, 1094, 1102, 1102, + 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, + 1102, 1102, 1102, 1102, 1102, 1094, 1094, 1094, 1094, 1094, + 1094, 639, 639, 639, 639, 639, 639, 639, 639, 639, + 639, 1102, 1102, 1102, 1102, 639, 639, 639, 639, 639, + 639, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, + 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 639, 639, + + 639, 639, 639, 639, 642, 642, 642, 642, 642, 642, + 642, 642, 642, 642, 1102, 1102, 1102, 1102, 642, 642, + 642, 642, 642, 642, 1102, 1102, 1102, 1102, 1102, 1102, + 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, + 1102, 642, 642, 642, 642, 642, 642, 1099, 1099, 1099, + 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1102, 1102, 1102, + 1102, 1099, 1099, 1099, 1099, 1099, 1099, 1102, 1102, 1102, + 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, + 1102, 1102, 1102, 1102, 1099, 1099, 1099, 1099, 1099, 1099, + 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, + + 1102, 1102, 1102, 1102, 1101, 1101, 1101, 1101, 1101, 1101, + 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, + 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1101, 1101, 1101, + 1101, 1101, 1101, 27, 27, 1102, 27, 27, 27, 27, + 27, 27, 30, 30, 30, 30, 33, 33, 1102, 33, + 33, 33, 33, 33, 33, 36, 1102, 1102, 36, 64, + 64, 1102, 64, 64, 67, 67, 1102, 67, 67, 67, + 67, 67, 67, 78, 78, 78, 78, 78, 78, 78, + 78, 78, 82, 82, 1102, 82, 82, 82, 82, 82, + 82, 84, 84, 84, 84, 84, 84, 84, 84, 84, + + 88, 88, 88, 88, 88, 88, 88, 88, 88, 91, + 1102, 91, 91, 148, 148, 1102, 148, 148, 148, 148, + 148, 148, 153, 153, 153, 153, 153, 153, 153, 153, + 153, 166, 166, 166, 166, 166, 166, 166, 166, 166, + 173, 173, 173, 173, 173, 173, 173, 173, 173, 175, + 175, 1102, 175, 175, 175, 175, 175, 175, 279, 279, + 279, 279, 279, 279, 279, 279, 279, 294, 294, 294, + 294, 294, 294, 294, 294, 294, 298, 298, 298, 298, + 298, 298, 298, 298, 298, 451, 451, 451, 1102, 451, + 451, 451, 451, 457, 457, 457, 457, 457, 457, 457, + + 457, 457, 472, 472, 472, 472, 472, 472, 472, 472, + 472, 173, 173, 173, 173, 173, 173, 173, 173, 173, + 639, 639, 1102, 639, 639, 639, 639, 639, 639, 642, + 642, 1102, 642, 642, 642, 642, 642, 642, 457, 457, + 457, 457, 457, 457, 457, 457, 457, 279, 279, 279, + 279, 279, 279, 279, 279, 279, 27, 27, 27, 27, + 27, 27, 27, 27, 27, 472, 472, 472, 472, 472, + 472, 472, 472, 472, 294, 294, 294, 294, 294, 294, + 294, 294, 294, 811, 811, 811, 811, 811, 811, 811, + 811, 811, 814, 814, 814, 814, 814, 814, 814, 814, + + 814, 961, 961, 1102, 1102, 961, 961, 961, 961, 3, + 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, + 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, + 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, + 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, + 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, + 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, + 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, + 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102 + } ; + +static const flex_int16_t yy_chk[7190] = + { 0, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 5, + 5, 5, 5, 5, 6, 6, 6, 6, 6, 7, + 7, 7, 7, 7, 8, 9, 10, 11, 17, 22, + + 22, 22, 22, 22, 36, 7, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 25, 30, 82, 470, + 1113, 470, 58, 27, 16, 46, 25, 26, 7, 64, + 16, 26, 9, 26, 16, 1097, 11, 16, 25, 10, + 17, 8, 7, 46, 16, 58, 36, 16, 46, 26, + 133, 7, 14, 16, 30, 82, 16, 14, 14, 16, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 27, 64, 26, 133, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 18, 33, + 14, 38, 67, 38, 38, 38, 38, 38, 38, 38, + 38, 38, 38, 49, 49, 23, 23, 23, 23, 23, + 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, + 48, 23, 1069, 45, 18, 49, 48, 84, 78, 1068, + 18, 74, 33, 45, 67, 74, 89, 74, 154, 89, + 167, 154, 48, 167, 23, 45, 18, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 51, 23, 170, + 50, 19, 19, 19, 19, 19, 19, 23, 1058, 50, + + 84, 47, 51, 52, 54, 78, 61, 1050, 52, 47, + 51, 47, 50, 52, 19, 19, 19, 19, 19, 19, + 29, 29, 29, 47, 59, 52, 54, 54, 61, 61, + 52, 47, 170, 664, 59, 664, 29, 29, 29, 29, + 29, 29, 29, 29, 29, 29, 59, 60, 148, 72, + 29, 29, 29, 29, 29, 29, 72, 150, 79, 85, + 66, 299, 195, 79, 299, 60, 1049, 195, 85, 195, + 60, 72, 1025, 29, 29, 29, 29, 29, 29, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 53, + 148, 66, 126, 32, 32, 32, 32, 32, 32, 150, + + 73, 126, 66, 1012, 73, 53, 73, 53, 100, 53, + 79, 85, 53, 66, 126, 77, 32, 32, 32, 32, + 32, 32, 34, 34, 34, 77, 73, 53, 124, 53, + 100, 100, 222, 1011, 124, 95, 222, 77, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 73, 151, + 124, 95, 34, 34, 34, 34, 34, 34, 95, 151, + 224, 991, 990, 163, 224, 96, 105, 988, 453, 96, + 105, 96, 105, 987, 980, 34, 34, 34, 34, 34, + 34, 37, 37, 37, 37, 37, 37, 37, 37, 37, + 37, 96, 105, 105, 130, 37, 37, 37, 37, 37, + + 37, 151, 119, 979, 106, 106, 119, 119, 119, 119, + 163, 453, 969, 96, 105, 105, 130, 130, 37, 37, + 37, 37, 37, 37, 56, 56, 106, 968, 951, 56, + 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, + + 56, 56, 56, 62, 115, 935, 134, 62, 62, 62, + 62, 137, 669, 134, 669, 137, 158, 137, 116, 125, + 125, 253, 116, 115, 116, 62, 138, 115, 134, 62, + 127, 121, 62, 121, 121, 121, 121, 121, 121, 158, + 934, 125, 138, 253, 116, 127, 139, 932, 62, 138, + 139, 62, 139, 127, 62, 65, 65, 65, 65, 65, + 65, 65, 65, 65, 65, 911, 116, 159, 136, 65, + 65, 65, 65, 65, 65, 458, 157, 910, 458, 99, + 157, 141, 157, 99, 99, 99, 99, 136, 129, 141, + 159, 136, 65, 65, 65, 65, 65, 65, 68, 68, + + 68, 68, 68, 160, 129, 99, 129, 642, 129, 68, + 160, 129, 141, 99, 147, 68, 68, 68, 68, 68, + 68, 68, 68, 68, 68, 160, 129, 99, 129, 68, + 68, 68, 68, 68, 68, 99, 147, 147, 360, 103, + 908, 155, 360, 103, 103, 103, 103, 232, 452, 155, + 642, 68, 68, 68, 68, 68, 68, 68, 80, 80, + 80, 80, 80, 155, 80, 103, 123, 907, 123, 123, + 123, 123, 123, 123, 103, 80, 80, 80, 80, 80, + 80, 80, 80, 80, 80, 473, 178, 103, 473, 80, + 80, 80, 80, 80, 80, 452, 103, 135, 901, 232, + + 140, 135, 143, 135, 140, 140, 140, 140, 146, 178, + 143, 80, 80, 80, 80, 80, 80, 80, 83, 83, + 83, 83, 83, 135, 161, 179, 146, 680, 161, 680, + 161, 146, 899, 143, 83, 83, 83, 83, 83, 83, + 83, 83, 83, 83, 83, 135, 145, 187, 179, 83, + 83, 83, 83, 83, 83, 156, 145, 177, 895, 893, + 156, 177, 156, 177, 164, 703, 890, 703, 145, 164, + 187, 83, 83, 83, 83, 83, 83, 83, 86, 86, + 86, 86, 86, 183, 156, 189, 186, 183, 86, 183, + 186, 186, 186, 186, 300, 86, 86, 86, 86, 86, + + 86, 86, 86, 86, 86, 168, 156, 814, 189, 86, + 86, 86, 86, 86, 86, 194, 164, 198, 199, 194, + 168, 194, 101, 199, 200, 199, 101, 101, 101, 101, + 193, 86, 86, 86, 86, 86, 86, 86, 90, 198, + 198, 194, 90, 90, 90, 90, 300, 200, 101, 193, + 814, 128, 101, 193, 201, 889, 128, 168, 90, 90, + 90, 128, 90, 194, 90, 204, 171, 90, 90, 90, + 101, 872, 362, 128, 101, 171, 362, 201, 128, 205, + 214, 90, 90, 90, 90, 709, 90, 709, 204, 90, + 90, 90, 92, 92, 92, 92, 92, 92, 92, 92, + + 92, 92, 205, 214, 216, 257, 92, 92, 92, 92, + 92, 92, 871, 162, 162, 162, 162, 162, 171, 203, + 209, 869, 258, 203, 209, 203, 209, 216, 257, 92, + 92, 92, 92, 92, 92, 94, 94, 94, 94, 94, + 94, 94, 94, 94, 94, 258, 639, 868, 865, 94, + 94, 94, 94, 94, 94, 559, 162, 260, 107, 559, + 863, 94, 107, 110, 107, 862, 162, 110, 110, 110, + 110, 260, 94, 94, 94, 94, 94, 94, 162, 107, + 260, 114, 265, 94, 107, 114, 114, 114, 114, 110, + 212, 212, 213, 639, 110, 254, 213, 213, 213, 213, + + 265, 286, 107, 254, 182, 265, 107, 114, 182, 286, + 182, 110, 212, 114, 220, 114, 110, 254, 220, 220, + 220, 220, 229, 286, 182, 857, 229, 228, 229, 114, + 182, 228, 561, 228, 855, 114, 561, 114, 118, 118, + 118, 118, 118, 303, 234, 304, 852, 182, 234, 234, + 234, 234, 182, 228, 316, 118, 118, 118, 118, 118, + 118, 118, 118, 118, 118, 714, 303, 714, 304, 118, + 118, 118, 118, 118, 118, 228, 256, 316, 259, 255, + 256, 416, 256, 208, 255, 259, 255, 208, 208, 208, + 208, 118, 118, 118, 118, 118, 118, 118, 120, 851, + + 259, 120, 120, 120, 120, 120, 120, 120, 255, 208, + 261, 318, 333, 120, 261, 120, 261, 236, 208, 236, + 236, 236, 236, 236, 236, 242, 242, 242, 242, 242, + 255, 208, 849, 416, 318, 333, 120, 483, 120, 122, + 208, 334, 122, 122, 122, 122, 122, 122, 122, 305, + 305, 305, 305, 305, 122, 238, 122, 238, 238, 238, + 238, 238, 238, 262, 334, 275, 283, 262, 242, 262, + 267, 283, 242, 283, 267, 275, 267, 122, 242, 122, + 149, 149, 149, 149, 149, 848, 281, 266, 831, 483, + 242, 266, 281, 266, 242, 338, 830, 149, 149, 149, + + 149, 149, 149, 149, 149, 149, 149, 266, 281, 339, + 343, 149, 149, 149, 149, 149, 149, 275, 338, 249, + 249, 249, 249, 249, 726, 282, 726, 795, 344, 282, + 266, 282, 339, 343, 149, 149, 149, 149, 149, 149, + 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, + 249, 344, 794, 282, 152, 152, 152, 152, 152, 152, + 270, 752, 784, 752, 270, 270, 270, 270, 957, 783, + 287, 351, 249, 249, 287, 282, 287, 152, 152, 152, + 152, 152, 152, 165, 165, 165, 165, 165, 165, 165, + 165, 165, 165, 754, 351, 292, 417, 165, 165, 165, + + 165, 165, 165, 753, 272, 272, 272, 272, 272, 290, + 302, 957, 328, 290, 302, 290, 302, 328, 417, 328, + 165, 165, 165, 165, 165, 165, 169, 169, 169, 169, + 169, 169, 169, 169, 169, 169, 291, 292, 353, 272, + 169, 169, 169, 169, 169, 169, 291, 292, 750, 792, + 503, 792, 241, 241, 241, 241, 241, 272, 291, 292, + 779, 353, 272, 169, 169, 169, 169, 169, 169, 172, + 172, 172, 172, 172, 172, 172, 172, 172, 172, 401, + 401, 748, 779, 172, 172, 172, 172, 172, 172, 306, + 306, 306, 306, 306, 811, 241, 244, 244, 244, 244, + + 244, 401, 503, 241, 405, 241, 172, 172, 172, 172, + 172, 172, 176, 176, 176, 176, 176, 241, 307, 405, + 747, 332, 307, 741, 307, 241, 332, 405, 332, 176, + 176, 176, 176, 176, 176, 176, 176, 176, 176, 244, + 244, 811, 392, 176, 176, 176, 176, 176, 176, 244, + 739, 954, 392, 273, 273, 273, 273, 273, 734, 311, + 412, 244, 244, 311, 392, 311, 176, 176, 176, 176, + 176, 176, 233, 233, 233, 233, 233, 233, 233, 233, + 233, 233, 412, 412, 273, 462, 233, 233, 233, 233, + 233, 233, 240, 240, 240, 240, 240, 801, 954, 801, + + 505, 271, 271, 271, 271, 271, 273, 273, 462, 233, + 233, 233, 233, 233, 233, 235, 526, 533, 235, 235, + 235, 235, 235, 235, 235, 325, 732, 240, 463, 325, + 235, 325, 235, 728, 727, 240, 468, 243, 243, 243, + 243, 243, 315, 468, 271, 240, 315, 315, 315, 315, + 240, 463, 505, 235, 271, 235, 237, 240, 468, 237, + 237, 237, 237, 237, 237, 237, 271, 724, 526, 533, + 403, 237, 478, 237, 245, 245, 245, 245, 245, 403, + 243, 246, 246, 246, 246, 246, 402, 337, 705, 243, + 243, 337, 403, 337, 237, 478, 237, 239, 239, 239, + + 239, 239, 243, 704, 251, 251, 251, 251, 251, 346, + 479, 243, 245, 346, 239, 346, 554, 245, 239, 239, + 239, 239, 324, 698, 246, 342, 324, 245, 324, 246, + 342, 697, 342, 479, 246, 245, 556, 402, 402, 245, + 239, 250, 250, 250, 250, 250, 246, 251, 324, 350, + 239, 246, 251, 350, 350, 350, 350, 251, 759, 402, + 759, 759, 239, 247, 247, 247, 247, 247, 554, 251, + 324, 358, 250, 694, 251, 358, 358, 358, 358, 250, + 288, 288, 288, 288, 288, 807, 693, 807, 556, 274, + 274, 274, 274, 274, 250, 250, 247, 277, 277, 277, + + 277, 277, 250, 277, 366, 566, 247, 277, 366, 277, + 366, 369, 247, 397, 247, 369, 247, 369, 740, 247, + 688, 397, 740, 397, 274, 374, 288, 686, 247, 374, + 374, 374, 374, 288, 247, 397, 247, 248, 248, 248, + 248, 248, 274, 397, 838, 399, 838, 274, 288, 424, + 277, 399, 742, 424, 248, 424, 742, 566, 248, 248, + 248, 248, 320, 320, 320, 320, 320, 399, 248, 280, + 280, 280, 280, 280, 321, 321, 321, 321, 321, 322, + 322, 322, 322, 322, 495, 280, 583, 583, 583, 583, + 248, 248, 276, 276, 276, 276, 276, 335, 335, 335, + + 335, 335, 336, 336, 336, 336, 336, 495, 280, 276, + 276, 276, 276, 276, 276, 276, 276, 276, 276, 682, + 681, 423, 280, 276, 276, 276, 276, 276, 276, 423, + 678, 280, 289, 289, 289, 289, 289, 340, 340, 340, + 340, 340, 427, 423, 676, 675, 276, 276, 276, 276, + 276, 276, 278, 278, 278, 278, 278, 278, 278, 278, + 278, 278, 656, 492, 427, 427, 278, 278, 278, 278, + 278, 278, 341, 341, 341, 341, 341, 655, 289, 492, + 331, 331, 331, 331, 331, 289, 492, 630, 629, 278, + 278, 278, 278, 278, 278, 355, 355, 355, 355, 355, + + 289, 293, 293, 293, 293, 293, 293, 293, 293, 293, + 293, 331, 621, 447, 497, 293, 293, 293, 293, 293, + 293, 620, 577, 349, 349, 349, 349, 349, 356, 356, + 356, 356, 356, 331, 331, 447, 447, 497, 293, 293, + 293, 293, 293, 293, 296, 296, 296, 296, 296, 296, + 296, 296, 296, 296, 576, 517, 394, 521, 296, 296, + 296, 296, 296, 296, 357, 357, 357, 357, 357, 363, + 363, 363, 363, 363, 394, 349, 349, 517, 517, 394, + 521, 296, 296, 296, 296, 296, 296, 297, 297, 297, + 297, 297, 297, 297, 297, 297, 297, 349, 847, 573, + + 847, 297, 297, 297, 297, 297, 297, 364, 364, 364, + 364, 364, 572, 314, 314, 314, 314, 314, 365, 365, + 365, 365, 365, 393, 297, 297, 297, 297, 297, 297, + 301, 301, 301, 301, 301, 301, 301, 301, 301, 301, + 761, 522, 761, 761, 301, 301, 301, 301, 301, 301, + 314, 372, 372, 372, 372, 372, 376, 569, 376, 376, + 376, 376, 376, 376, 522, 393, 314, 301, 301, 301, + 301, 301, 301, 314, 378, 393, 378, 378, 378, 378, + 378, 378, 409, 568, 459, 372, 567, 393, 459, 565, + 389, 389, 389, 389, 389, 429, 560, 418, 409, 429, + + 409, 429, 409, 418, 372, 409, 459, 558, 372, 373, + 373, 373, 373, 373, 373, 373, 373, 373, 373, 418, + 409, 389, 409, 373, 373, 373, 373, 373, 373, 380, + 380, 380, 380, 380, 867, 568, 867, 555, 381, 381, + 381, 381, 381, 389, 389, 553, 373, 373, 373, 373, + 373, 373, 375, 549, 547, 375, 375, 375, 375, 375, + 375, 375, 900, 420, 380, 528, 900, 375, 420, 375, + 420, 395, 380, 400, 382, 382, 382, 382, 382, 411, + 398, 381, 380, 411, 411, 411, 411, 380, 528, 381, + 375, 381, 375, 377, 380, 541, 377, 377, 377, 377, + + 377, 377, 377, 381, 662, 395, 529, 884, 377, 884, + 377, 381, 662, 406, 419, 540, 532, 382, 419, 400, + 419, 382, 398, 395, 404, 400, 662, 382, 395, 529, + 398, 377, 398, 377, 379, 379, 379, 379, 379, 382, + 570, 400, 419, 382, 398, 383, 383, 383, 383, 383, + 406, 379, 398, 543, 543, 379, 379, 379, 379, 384, + 384, 384, 384, 384, 419, 406, 525, 404, 385, 385, + 385, 385, 385, 406, 679, 543, 404, 379, 464, 386, + 386, 386, 386, 386, 464, 515, 407, 379, 383, 404, + 413, 407, 570, 906, 514, 906, 407, 383, 383, 379, + + 464, 432, 384, 384, 493, 432, 385, 432, 407, 544, + 383, 385, 384, 407, 391, 391, 391, 391, 391, 383, + 413, 385, 386, 465, 384, 384, 679, 386, 465, 385, + 465, 511, 386, 385, 390, 390, 390, 390, 390, 510, + 493, 414, 413, 413, 386, 414, 414, 414, 414, 386, + 387, 387, 387, 387, 387, 535, 493, 391, 414, 410, + 544, 544, 391, 493, 435, 390, 408, 391, 435, 396, + 435, 536, 390, 396, 396, 396, 396, 414, 535, 391, + 725, 414, 544, 387, 391, 508, 436, 390, 390, 396, + 436, 410, 436, 387, 536, 390, 546, 507, 428, 387, + + 443, 387, 428, 387, 428, 396, 387, 410, 408, 410, + 443, 410, 396, 408, 410, 387, 504, 502, 408, 546, + 428, 387, 443, 387, 388, 388, 388, 388, 388, 410, + 408, 410, 725, 498, 496, 408, 425, 425, 425, 425, + 425, 388, 446, 428, 439, 388, 388, 388, 388, 426, + 426, 426, 426, 426, 444, 388, 433, 433, 433, 433, + 433, 490, 439, 448, 440, 548, 489, 439, 440, 445, + 440, 441, 441, 441, 441, 441, 446, 388, 388, 442, + 486, 485, 425, 442, 442, 442, 442, 445, 548, 425, + 433, 482, 445, 448, 446, 426, 444, 461, 472, 446, + + 513, 461, 426, 461, 425, 513, 444, 513, 441, 433, + 942, 457, 942, 433, 460, 448, 448, 426, 444, 460, + 438, 460, 467, 477, 441, 437, 467, 477, 467, 477, + 518, 441, 449, 449, 449, 449, 449, 449, 449, 449, + 449, 449, 605, 469, 460, 609, 449, 449, 449, 449, + 449, 449, 450, 450, 450, 450, 450, 484, 450, 431, + 518, 484, 450, 484, 450, 605, 460, 430, 609, 449, + 449, 449, 449, 449, 449, 451, 451, 451, 451, 451, + 488, 451, 518, 518, 488, 451, 488, 451, 469, 480, + 480, 480, 480, 480, 422, 469, 481, 481, 481, 481, + + 481, 421, 494, 610, 670, 450, 494, 494, 494, 494, + 469, 487, 487, 487, 487, 487, 499, 499, 499, 499, + 499, 500, 500, 500, 500, 500, 610, 670, 451, 455, + 455, 455, 455, 455, 455, 455, 455, 455, 455, 455, + 455, 455, 455, 455, 455, 455, 455, 455, 455, 455, + 455, 455, 455, 455, 455, 455, 455, 455, 455, 455, + 455, 455, 455, 455, 455, 455, 455, 455, 455, 455, + 455, 455, 455, 455, 455, 455, 455, 455, 455, 455, + 455, 455, 455, 455, 455, 455, 455, 455, 455, 455, + 455, 455, 455, 455, 455, 455, 455, 455, 455, 455, + + 455, 455, 455, 455, 455, 455, 455, 455, 456, 456, + 456, 456, 456, 415, 371, 466, 466, 466, 466, 466, + 491, 491, 491, 491, 491, 456, 456, 456, 456, 456, + 456, 456, 456, 456, 456, 602, 602, 602, 602, 456, + 456, 456, 456, 456, 456, 501, 501, 501, 501, 501, + 506, 519, 370, 368, 506, 509, 506, 491, 367, 509, + 466, 509, 456, 456, 456, 456, 456, 456, 466, 361, + 519, 520, 359, 491, 519, 527, 520, 354, 520, 527, + 491, 527, 466, 471, 471, 471, 471, 471, 352, 471, + 523, 523, 523, 523, 523, 512, 512, 512, 512, 512, + + 471, 471, 471, 471, 471, 471, 471, 471, 471, 471, + 604, 604, 604, 604, 471, 471, 471, 471, 471, 471, + 524, 524, 524, 524, 524, 948, 348, 948, 615, 512, + 530, 530, 530, 530, 530, 615, 471, 471, 471, 471, + 471, 471, 471, 474, 474, 474, 474, 474, 512, 534, + 615, 606, 512, 347, 534, 606, 534, 474, 345, 330, + 474, 474, 474, 474, 474, 474, 474, 474, 474, 474, + 952, 329, 952, 606, 474, 474, 474, 474, 474, 474, + 474, 474, 474, 474, 474, 474, 474, 474, 474, 474, + 474, 474, 474, 474, 474, 474, 474, 474, 474, 474, + + 474, 474, 474, 474, 474, 474, 474, 474, 474, 474, + 474, 474, 474, 474, 474, 474, 474, 474, 327, 622, + 474, 475, 475, 475, 475, 475, 475, 475, 475, 475, + 475, 636, 636, 636, 636, 475, 475, 475, 475, 475, + 475, 622, 622, 516, 516, 516, 516, 516, 531, 531, + 531, 531, 531, 537, 537, 537, 537, 537, 475, 475, + 475, 475, 475, 475, 476, 476, 476, 476, 476, 476, + 476, 476, 476, 476, 516, 975, 634, 975, 476, 476, + 476, 476, 476, 476, 538, 538, 538, 538, 538, 539, + 326, 652, 634, 539, 571, 539, 516, 516, 571, 634, + + 571, 476, 476, 476, 476, 476, 476, 542, 542, 542, + 542, 542, 545, 652, 652, 671, 545, 545, 545, 545, + 550, 550, 550, 550, 550, 551, 551, 551, 551, 551, + 552, 552, 552, 552, 552, 557, 580, 751, 671, 557, + 557, 557, 557, 562, 562, 562, 562, 562, 563, 563, + 563, 563, 563, 564, 564, 564, 564, 564, 323, 542, + 542, 574, 574, 574, 574, 574, 575, 579, 319, 580, + 575, 317, 575, 578, 578, 578, 578, 578, 608, 902, + 612, 542, 608, 902, 608, 612, 579, 612, 580, 751, + 579, 585, 580, 585, 585, 585, 585, 585, 585, 587, + + 313, 587, 587, 587, 587, 587, 587, 578, 614, 618, + 815, 654, 614, 618, 614, 618, 654, 312, 654, 815, + 598, 598, 598, 598, 598, 986, 578, 986, 310, 309, + 578, 582, 582, 582, 582, 582, 582, 582, 582, 582, + 582, 598, 598, 598, 598, 582, 582, 582, 582, 582, + 582, 584, 584, 584, 584, 584, 584, 584, 601, 601, + 601, 601, 815, 584, 308, 584, 616, 298, 582, 582, + 582, 582, 582, 582, 601, 586, 586, 586, 586, 586, + 586, 586, 684, 684, 684, 684, 584, 586, 584, 586, + 601, 603, 603, 603, 603, 607, 685, 601, 294, 611, + + 607, 661, 607, 619, 603, 611, 661, 619, 661, 619, + 586, 616, 586, 588, 588, 588, 588, 588, 616, 685, + 623, 611, 285, 603, 623, 607, 623, 603, 672, 672, + 672, 672, 672, 616, 588, 588, 588, 588, 626, 613, + 613, 613, 613, 613, 625, 657, 687, 607, 625, 657, + 625, 624, 624, 624, 624, 624, 588, 626, 628, 631, + 627, 626, 628, 631, 628, 631, 588, 657, 284, 687, + 632, 632, 632, 632, 632, 635, 279, 269, 588, 589, + 589, 589, 589, 589, 613, 633, 710, 711, 268, 633, + 624, 633, 613, 627, 264, 638, 638, 638, 638, 638, + + 589, 589, 589, 589, 624, 632, 613, 638, 263, 710, + 711, 635, 627, 624, 589, 231, 627, 640, 640, 640, + 640, 640, 1022, 632, 1022, 812, 653, 635, 632, 640, + 812, 653, 589, 653, 635, 230, 866, 589, 590, 590, + 590, 590, 590, 644, 644, 644, 644, 644, 658, 644, + 227, 226, 658, 644, 658, 644, 715, 225, 653, 590, + 590, 590, 590, 223, 645, 645, 645, 645, 645, 674, + 645, 221, 716, 674, 645, 674, 645, 812, 219, 715, + 653, 590, 646, 646, 646, 646, 646, 663, 866, 590, + 1026, 590, 1026, 218, 646, 716, 644, 217, 647, 647, + + 647, 647, 647, 590, 647, 1027, 215, 1027, 647, 720, + 647, 590, 591, 591, 591, 591, 591, 645, 648, 648, + 648, 648, 648, 692, 648, 211, 210, 692, 648, 692, + 648, 663, 720, 591, 591, 591, 591, 207, 206, 663, + 659, 659, 659, 659, 659, 660, 660, 660, 660, 660, + 1047, 647, 1047, 663, 673, 673, 673, 673, 673, 591, + 677, 677, 677, 677, 677, 591, 689, 689, 689, 689, + 689, 648, 700, 683, 683, 683, 683, 683, 707, 721, + 202, 591, 592, 592, 592, 592, 592, 659, 731, 733, + 696, 700, 660, 659, 696, 700, 696, 707, 660, 701, + + 197, 707, 721, 592, 592, 592, 592, 196, 192, 659, + 683, 731, 733, 191, 660, 690, 690, 690, 690, 690, + 691, 691, 691, 691, 691, 190, 683, 695, 695, 695, + 695, 695, 701, 683, 592, 592, 699, 699, 699, 699, + 699, 706, 706, 706, 706, 706, 712, 712, 712, 712, + 712, 701, 1059, 188, 1059, 701, 592, 593, 593, 593, + 593, 593, 713, 713, 713, 713, 713, 843, 185, 777, + 699, 184, 706, 717, 717, 717, 717, 717, 593, 593, + 593, 593, 718, 718, 718, 718, 718, 181, 777, 699, + 843, 719, 777, 699, 706, 706, 719, 1060, 719, 1060, + + 790, 593, 722, 722, 722, 722, 722, 958, 790, 180, + 593, 723, 723, 723, 723, 723, 958, 729, 729, 729, + 729, 729, 790, 593, 594, 594, 594, 594, 594, 730, + 730, 730, 730, 735, 735, 735, 735, 735, 736, 736, + 736, 736, 736, 175, 173, 594, 594, 594, 594, 737, + 737, 737, 737, 737, 738, 738, 738, 738, 166, 958, + 775, 844, 594, 743, 743, 743, 743, 743, 153, 729, + 729, 744, 744, 744, 744, 744, 775, 594, 745, 745, + 745, 745, 745, 775, 844, 594, 595, 595, 595, 595, + 595, 729, 746, 144, 142, 854, 746, 856, 746, 749, + + 749, 749, 749, 749, 132, 758, 758, 758, 799, 758, + 758, 758, 755, 755, 755, 755, 755, 758, 854, 758, + 856, 131, 799, 762, 762, 762, 762, 762, 782, 595, + 832, 799, 785, 782, 595, 782, 785, 595, 117, 595, + 758, 113, 758, 760, 760, 760, 755, 760, 760, 760, + 112, 595, 832, 832, 785, 760, 595, 760, 791, 595, + 596, 596, 596, 596, 596, 755, 762, 111, 874, 755, + 763, 763, 763, 763, 763, 1077, 762, 1077, 760, 109, + 760, 772, 772, 772, 772, 772, 786, 874, 762, 805, + 786, 874, 786, 596, 108, 104, 764, 764, 764, 764, + + 764, 789, 791, 596, 102, 763, 789, 805, 789, 596, + 791, 596, 805, 596, 98, 97, 596, 765, 765, 765, + 765, 765, 781, 763, 791, 596, 793, 781, 763, 781, + 793, 596, 793, 596, 597, 597, 597, 597, 597, 764, + 93, 827, 766, 766, 766, 766, 766, 764, 91, 764, + 827, 1079, 88, 1079, 781, 597, 597, 597, 597, 81, + 76, 764, 796, 827, 765, 597, 796, 75, 796, 764, + 765, 767, 767, 767, 767, 767, 781, 71, 876, 768, + 768, 768, 768, 768, 800, 877, 765, 597, 597, 599, + 599, 599, 599, 599, 766, 766, 769, 769, 769, 769, + + 769, 876, 57, 771, 771, 771, 771, 771, 877, 55, + 599, 599, 599, 599, 798, 767, 766, 768, 798, 802, + 798, 1075, 800, 802, 767, 802, 806, 599, 44, 804, + 1075, 41, 768, 804, 771, 804, 800, 767, 39, 769, + 768, 829, 599, 1075, 769, 800, 829, 35, 829, 769, + 599, 600, 600, 600, 600, 600, 771, 771, 828, 835, + 806, 769, 828, 835, 828, 835, 769, 787, 787, 787, + 787, 787, 803, 803, 803, 803, 803, 880, 806, 1090, + 1098, 1090, 1098, 806, 773, 773, 773, 773, 773, 809, + 809, 809, 809, 809, 600, 881, 31, 24, 833, 600, + + 880, 809, 600, 833, 600, 833, 774, 774, 774, 774, + 774, 861, 21, 836, 787, 861, 600, 861, 881, 836, + 787, 600, 773, 885, 600, 637, 637, 637, 637, 637, + 637, 637, 637, 637, 637, 836, 787, 773, 886, 637, + 637, 637, 637, 637, 637, 773, 885, 20, 933, 774, + 892, 894, 939, 933, 774, 933, 939, 15, 939, 774, + 946, 886, 637, 637, 637, 637, 637, 637, 641, 641, + 641, 774, 1000, 892, 894, 13, 774, 797, 797, 797, + 797, 797, 946, 946, 641, 641, 641, 641, 641, 641, + 641, 641, 641, 641, 3, 1000, 1001, 1039, 641, 641, + + 641, 641, 641, 641, 1100, 0, 1100, 0, 797, 845, + 845, 845, 845, 845, 846, 846, 846, 846, 846, 1001, + 1039, 641, 641, 641, 641, 641, 641, 643, 643, 643, + 797, 797, 850, 850, 850, 850, 850, 858, 858, 858, + 858, 858, 0, 643, 643, 643, 643, 643, 643, 643, + 643, 643, 643, 0, 1040, 0, 0, 643, 643, 643, + 643, 643, 643, 817, 817, 817, 817, 817, 943, 817, + 0, 937, 943, 817, 943, 817, 937, 1040, 937, 0, + 643, 643, 643, 643, 643, 643, 649, 649, 649, 649, + 649, 940, 649, 0, 0, 945, 649, 940, 649, 945, + + 0, 945, 0, 649, 649, 649, 649, 649, 649, 649, + 649, 649, 649, 940, 0, 0, 817, 649, 649, 649, + 649, 649, 649, 859, 859, 859, 859, 859, 860, 860, + 860, 860, 860, 864, 864, 864, 864, 864, 0, 649, + 649, 649, 649, 649, 649, 649, 650, 650, 650, 650, + 650, 650, 650, 650, 650, 650, 650, 650, 650, 650, + 650, 650, 650, 650, 650, 650, 650, 650, 650, 650, + 650, 650, 650, 650, 650, 650, 650, 650, 650, 650, + 650, 650, 650, 650, 650, 650, 650, 650, 650, 650, + 650, 650, 650, 650, 650, 650, 650, 650, 650, 650, + + 650, 650, 650, 650, 650, 650, 650, 650, 650, 650, + 650, 650, 650, 650, 650, 650, 650, 650, 650, 650, + 650, 650, 650, 650, 650, 651, 651, 651, 651, 651, + 651, 651, 651, 651, 651, 0, 0, 0, 0, 651, + 651, 651, 651, 651, 651, 818, 818, 818, 818, 818, + 949, 818, 0, 970, 949, 818, 949, 818, 970, 0, + 970, 0, 651, 651, 651, 651, 651, 651, 665, 665, + 665, 665, 665, 1045, 665, 878, 878, 878, 878, 878, + 879, 879, 879, 879, 879, 665, 665, 665, 665, 665, + 665, 665, 665, 665, 665, 1045, 1045, 0, 818, 665, + + 665, 665, 665, 665, 665, 820, 820, 820, 820, 820, + 834, 834, 834, 834, 834, 0, 965, 820, 0, 0, + 965, 665, 665, 665, 665, 665, 665, 665, 666, 666, + 666, 666, 666, 666, 666, 666, 666, 666, 965, 0, + 0, 0, 666, 666, 666, 666, 666, 666, 821, 821, + 821, 821, 821, 873, 873, 873, 873, 873, 820, 834, + 821, 0, 0, 834, 0, 666, 666, 666, 666, 666, + 666, 667, 667, 667, 667, 667, 667, 667, 667, 667, + 667, 834, 0, 0, 873, 667, 667, 667, 667, 667, + 667, 0, 822, 822, 822, 822, 822, 0, 822, 967, + + 0, 821, 822, 967, 822, 967, 873, 873, 667, 667, + 667, 667, 667, 667, 668, 668, 668, 668, 668, 668, + 668, 668, 668, 668, 0, 0, 0, 0, 668, 668, + 668, 668, 668, 668, 0, 0, 788, 788, 788, 788, + 788, 837, 0, 0, 0, 822, 882, 882, 882, 882, + 882, 668, 668, 668, 668, 668, 668, 757, 757, 757, + 757, 757, 757, 757, 757, 757, 757, 0, 0, 0, + 0, 757, 757, 757, 757, 757, 757, 947, 823, 823, + 823, 823, 823, 788, 973, 0, 0, 837, 973, 788, + 823, 0, 0, 837, 757, 757, 757, 757, 757, 757, + + 770, 770, 770, 770, 770, 788, 973, 947, 0, 837, + 839, 839, 839, 839, 839, 0, 839, 883, 883, 883, + 883, 883, 887, 887, 887, 887, 887, 0, 1020, 947, + 947, 823, 1020, 770, 888, 888, 888, 888, 888, 896, + 896, 896, 896, 896, 897, 897, 897, 897, 897, 770, + 1020, 770, 0, 770, 0, 0, 770, 898, 898, 898, + 898, 898, 0, 839, 903, 903, 903, 903, 903, 0, + 0, 770, 0, 770, 808, 808, 808, 808, 808, 808, + 808, 808, 808, 808, 0, 0, 0, 0, 808, 808, + 808, 808, 808, 808, 853, 853, 853, 853, 853, 904, + + 904, 904, 904, 904, 905, 905, 905, 905, 905, 0, + 0, 808, 808, 808, 808, 808, 808, 813, 813, 813, + 813, 813, 0, 813, 909, 909, 909, 909, 909, 0, + 0, 853, 0, 0, 813, 813, 813, 813, 813, 813, + 813, 813, 813, 813, 0, 0, 0, 853, 813, 813, + 813, 813, 813, 813, 853, 944, 944, 944, 944, 944, + 953, 953, 953, 953, 953, 981, 981, 981, 981, 981, + 813, 813, 813, 813, 813, 813, 813, 816, 816, 816, + 816, 816, 1041, 972, 1017, 0, 1041, 816, 972, 1017, + 972, 1017, 0, 0, 816, 816, 816, 816, 816, 816, + + 816, 816, 816, 816, 1041, 0, 0, 0, 816, 816, + 816, 816, 816, 816, 870, 870, 870, 870, 870, 0, + 891, 891, 891, 891, 891, 989, 989, 989, 989, 989, + 816, 816, 816, 816, 816, 816, 816, 819, 819, 819, + 819, 819, 819, 819, 819, 819, 819, 0, 870, 0, + 0, 819, 819, 819, 819, 819, 819, 914, 914, 914, + 914, 914, 1023, 0, 0, 955, 1023, 870, 1023, 0, + 955, 870, 891, 891, 819, 819, 819, 819, 819, 819, + 824, 824, 824, 824, 824, 1002, 1002, 1002, 1002, 1002, + 0, 0, 0, 0, 891, 0, 0, 824, 824, 824, + + 824, 824, 824, 824, 824, 824, 824, 0, 0, 0, + 914, 824, 824, 824, 824, 824, 824, 955, 1003, 1003, + 1003, 1003, 1003, 1013, 1013, 1013, 1013, 1013, 1018, 1018, + 1018, 1018, 1018, 0, 824, 824, 824, 824, 824, 824, + 825, 825, 825, 825, 825, 825, 825, 825, 825, 825, + 825, 825, 825, 825, 825, 825, 825, 825, 825, 825, + 825, 825, 825, 825, 825, 825, 825, 825, 825, 825, + 825, 825, 825, 825, 825, 825, 825, 825, 825, 825, + 825, 825, 825, 825, 825, 825, 825, 825, 825, 825, + 825, 825, 825, 825, 825, 825, 825, 825, 825, 825, + + 825, 825, 825, 825, 825, 825, 825, 825, 825, 825, + 825, 825, 825, 825, 825, 825, 825, 825, 825, 826, + 826, 826, 826, 826, 826, 826, 826, 826, 826, 0, + 0, 0, 0, 826, 826, 826, 826, 826, 826, 912, + 912, 912, 912, 912, 924, 924, 924, 924, 924, 1038, + 1088, 0, 0, 1038, 1088, 1038, 826, 826, 826, 826, + 826, 826, 840, 840, 840, 840, 840, 840, 840, 840, + 840, 840, 1088, 912, 0, 924, 840, 840, 840, 840, + 840, 840, 916, 916, 916, 916, 916, 0, 0, 966, + 0, 0, 912, 966, 0, 966, 912, 924, 924, 840, + + 840, 840, 840, 840, 840, 841, 841, 841, 841, 841, + 841, 841, 841, 841, 841, 0, 966, 916, 0, 841, + 841, 841, 841, 841, 841, 0, 915, 915, 915, 915, + 915, 0, 1019, 0, 0, 916, 0, 1019, 966, 1019, + 916, 0, 841, 841, 841, 841, 841, 841, 842, 842, + 842, 842, 842, 842, 842, 842, 842, 842, 0, 0, + 0, 0, 842, 842, 842, 842, 842, 842, 0, 915, + 917, 917, 917, 917, 917, 0, 0, 974, 941, 915, + 918, 918, 918, 918, 918, 842, 842, 842, 842, 842, + 842, 915, 919, 919, 919, 919, 919, 920, 920, 920, + + 920, 920, 0, 0, 921, 921, 921, 921, 921, 1046, + 0, 0, 0, 917, 0, 0, 922, 922, 922, 922, + 922, 917, 1042, 917, 941, 974, 1042, 918, 1042, 974, + 941, 1044, 0, 918, 0, 917, 1044, 0, 1044, 1046, + 0, 920, 921, 917, 919, 919, 941, 974, 0, 918, + 920, 925, 925, 925, 925, 925, 0, 921, 0, 922, + 0, 1046, 1046, 920, 922, 921, 919, 0, 0, 922, + 926, 926, 926, 926, 926, 0, 927, 927, 927, 927, + 927, 922, 1076, 0, 0, 0, 922, 923, 923, 923, + 923, 923, 0, 0, 0, 928, 928, 928, 928, 928, + + 1056, 0, 0, 0, 925, 1056, 0, 1056, 926, 929, + 929, 929, 929, 929, 931, 931, 931, 931, 931, 927, + 923, 1067, 0, 926, 927, 1076, 1067, 0, 1067, 927, + 0, 926, 928, 1071, 1076, 0, 923, 1071, 923, 1071, + 923, 927, 0, 923, 0, 0, 927, 1076, 928, 930, + 930, 930, 930, 930, 0, 928, 0, 1074, 923, 1085, + 923, 1074, 929, 1074, 1085, 0, 1085, 931, 938, 938, + 938, 938, 938, 961, 961, 961, 961, 961, 963, 963, + 963, 963, 963, 930, 0, 961, 0, 0, 0, 0, + 963, 1051, 1051, 1051, 1051, 1051, 0, 971, 971, 971, + + 971, 971, 930, 0, 0, 0, 930, 976, 976, 976, + 976, 976, 977, 977, 977, 977, 977, 938, 1087, 0, + 1037, 938, 1087, 1021, 1087, 1037, 961, 1037, 971, 0, + 0, 963, 1086, 1086, 1086, 1086, 1086, 0, 0, 938, + 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, + 971, 971, 1037, 0, 956, 956, 956, 956, 956, 956, + 976, 0, 0, 0, 0, 977, 978, 978, 978, 978, + 978, 1021, 0, 0, 1037, 1021, 0, 956, 956, 956, + 956, 956, 956, 959, 959, 959, 959, 959, 959, 959, + 959, 959, 959, 1021, 0, 0, 0, 959, 959, 959, + + 959, 959, 959, 983, 983, 983, 983, 983, 984, 984, + 984, 984, 984, 1094, 1094, 1094, 1094, 1094, 0, 978, + 959, 959, 959, 959, 959, 959, 960, 960, 960, 960, + 960, 960, 960, 960, 960, 960, 0, 0, 0, 0, + 960, 960, 960, 960, 960, 960, 1095, 0, 0, 0, + 0, 1095, 0, 1095, 0, 0, 983, 0, 0, 0, + 0, 984, 0, 960, 960, 960, 960, 960, 960, 962, + 962, 962, 962, 962, 962, 962, 962, 962, 962, 962, + 962, 962, 962, 962, 962, 962, 962, 962, 962, 962, + 962, 962, 962, 962, 962, 962, 962, 962, 962, 962, + + 962, 962, 962, 962, 962, 962, 962, 962, 962, 962, + 962, 962, 962, 962, 962, 962, 962, 962, 962, 962, + 962, 962, 962, 962, 962, 962, 962, 962, 962, 962, + 962, 962, 962, 962, 962, 962, 962, 962, 962, 962, + 962, 962, 962, 962, 962, 962, 962, 962, 964, 964, + 964, 964, 964, 964, 964, 964, 964, 964, 0, 0, + 0, 0, 964, 964, 964, 964, 964, 964, 982, 982, + 982, 982, 982, 985, 985, 985, 985, 985, 992, 992, + 992, 992, 992, 0, 0, 964, 964, 964, 964, 964, + 964, 993, 993, 993, 993, 993, 994, 994, 994, 994, + + 994, 0, 0, 0, 0, 982, 995, 995, 995, 995, + 995, 0, 992, 996, 996, 996, 996, 996, 0, 0, + 0, 982, 993, 0, 0, 0, 985, 0, 982, 0, + 994, 992, 0, 0, 0, 992, 997, 997, 997, 997, + 997, 0, 0, 0, 993, 993, 0, 0, 0, 994, + 0, 0, 0, 994, 998, 998, 998, 998, 998, 995, + 999, 999, 999, 999, 999, 0, 996, 1004, 1004, 1004, + 1004, 1004, 1005, 1005, 1005, 1005, 1005, 1006, 1006, 1006, + 1006, 1006, 1007, 1007, 1007, 1007, 1007, 0, 1089, 997, + 1008, 1008, 1008, 1008, 1008, 1009, 1009, 1009, 1009, 1009, + + 1010, 1010, 1010, 1010, 1010, 0, 0, 998, 1014, 1014, + 1014, 1014, 1014, 999, 1015, 1015, 1015, 1015, 1015, 1004, + 1004, 0, 0, 0, 0, 1005, 0, 0, 0, 0, + 1006, 0, 0, 0, 0, 1007, 1089, 0, 0, 0, + 1089, 1004, 1014, 1008, 0, 0, 0, 0, 1009, 0, + 0, 0, 0, 1010, 0, 0, 0, 0, 1089, 0, + 0, 1014, 0, 0, 0, 1014, 0, 1015, 1028, 1028, + 1028, 1028, 1028, 1028, 1028, 1028, 1028, 1028, 0, 0, + 0, 0, 1028, 1028, 1028, 1028, 1028, 1028, 1031, 1031, + 1031, 1031, 1031, 1048, 1048, 1048, 1048, 1048, 0, 0, + + 1031, 0, 0, 0, 0, 1028, 1028, 1028, 1028, 1028, + 1028, 1029, 1029, 1029, 1029, 1029, 1029, 1029, 1029, 1029, + 1029, 0, 0, 0, 0, 1029, 1029, 1029, 1029, 1029, + 1029, 1032, 1032, 1032, 1032, 1032, 1043, 1043, 1043, 1043, + 1043, 1031, 0, 1032, 0, 0, 1048, 0, 1029, 1029, + 1029, 1029, 1029, 1029, 1030, 1030, 1030, 1030, 1030, 1030, + 1030, 1030, 1030, 1030, 0, 0, 0, 0, 1030, 1030, + 1030, 1030, 1030, 1030, 1053, 1053, 1053, 1053, 1053, 0, + 1043, 0, 0, 0, 1032, 0, 0, 0, 0, 1043, + 0, 1030, 1030, 1030, 1030, 1030, 1030, 1033, 1033, 1033, + + 1033, 1033, 1043, 0, 0, 0, 0, 0, 0, 1033, + 0, 0, 0, 0, 1033, 1033, 1033, 1033, 1033, 1033, + 1033, 1033, 1033, 1033, 0, 0, 0, 1053, 1033, 1033, + 1033, 1033, 1033, 1033, 1052, 1052, 1052, 1052, 1052, 1054, + 1054, 1054, 1054, 1054, 0, 0, 0, 0, 0, 0, + 1033, 1033, 1033, 1033, 1033, 1033, 1033, 1035, 1035, 1035, + 1035, 1035, 1035, 1035, 1035, 1035, 1035, 0, 1052, 0, + 0, 1035, 1035, 1035, 1035, 1035, 1035, 1055, 1055, 1055, + 1055, 1055, 0, 0, 0, 0, 0, 1052, 0, 0, + 0, 1052, 1054, 0, 1035, 1035, 1035, 1035, 1035, 1035, + + 1064, 1064, 1064, 1064, 1064, 0, 0, 0, 0, 0, + 0, 0, 1064, 1072, 1072, 1072, 1072, 1072, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1055, 1061, 1061, 1061, 1061, 1061, 1061, 1061, 1061, 1061, + 1061, 0, 0, 0, 0, 1061, 1061, 1061, 1061, 1061, + 1061, 0, 0, 1064, 0, 0, 1073, 1073, 1073, 1073, + 1073, 0, 1072, 0, 0, 0, 1072, 0, 1061, 1061, + 1061, 1061, 1061, 1061, 1062, 1062, 1062, 1062, 1062, 1062, + 1062, 1062, 1062, 1062, 1072, 0, 0, 0, 1062, 1062, + 1062, 1062, 1062, 1062, 1078, 1078, 1078, 1078, 1078, 0, + + 0, 0, 0, 0, 0, 1073, 0, 0, 0, 1073, + 0, 1062, 1062, 1062, 1062, 1062, 1062, 1063, 1063, 1063, + 1063, 1063, 1063, 1063, 1063, 1063, 1063, 1073, 0, 0, + 0, 1063, 1063, 1063, 1063, 1063, 1063, 1101, 1101, 1101, + 1101, 1101, 0, 0, 0, 0, 0, 1078, 0, 1101, + 0, 0, 0, 0, 1063, 1063, 1063, 1063, 1063, 1063, + 1065, 1065, 1065, 1065, 1065, 1065, 1065, 1065, 1065, 1065, + 0, 0, 0, 0, 1065, 1065, 1065, 1065, 1065, 1065, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1101, 0, 0, 0, 0, 0, 0, 1065, 1065, 1065, + + 1065, 1065, 1065, 1066, 1066, 1066, 1066, 1066, 1066, 1066, + 1066, 1066, 1066, 0, 0, 0, 0, 1066, 1066, 1066, + 1066, 1066, 1066, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1066, 1066, 1066, 1066, 1066, 1066, 1080, 1080, 1080, 1080, + 1080, 1080, 1080, 1080, 1080, 1080, 0, 0, 0, 0, + 1080, 1080, 1080, 1080, 1080, 1080, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1080, 1080, 1080, 1080, 1080, 1080, 1081, + 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 0, + + 0, 0, 0, 1081, 1081, 1081, 1081, 1081, 1081, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 1081, 1081, 1081, 1081, + 1081, 1081, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, + 1082, 1082, 0, 0, 0, 0, 1082, 1082, 1082, 1082, + 1082, 1082, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 1082, + 1082, 1082, 1082, 1082, 1082, 1083, 1083, 1083, 1083, 1083, + 1083, 1083, 1083, 1083, 1083, 0, 0, 0, 0, 1083, + 1083, 1083, 1083, 1083, 1083, 0, 0, 0, 0, 0, + + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1083, 1083, 1083, 1083, 1083, 1083, 1084, 1084, + 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 0, 0, + 0, 0, 1084, 1084, 1084, 1084, 1084, 1084, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 1084, 1084, 1084, 1084, 1084, + 1084, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, + 1091, 0, 0, 0, 0, 1091, 1091, 1091, 1091, 1091, + 1091, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 1091, 1091, + + 1091, 1091, 1091, 1091, 1092, 1092, 1092, 1092, 1092, 1092, + 1092, 1092, 1092, 1092, 0, 0, 0, 0, 1092, 1092, + 1092, 1092, 1092, 1092, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1092, 1092, 1092, 1092, 1092, 1092, 1093, 1093, 1093, + 1093, 1093, 1093, 1093, 1093, 1093, 1093, 0, 0, 0, + 0, 1093, 1093, 1093, 1093, 1093, 1093, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1093, 1093, 1093, 1093, 1093, 1093, + 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, + + 0, 0, 0, 0, 1099, 1099, 1099, 1099, 1099, 1099, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 1099, 1099, 1099, + 1099, 1099, 1099, 1103, 1103, 0, 1103, 1103, 1103, 1103, + 1103, 1103, 1104, 1104, 1104, 1104, 1105, 1105, 0, 1105, + 1105, 1105, 1105, 1105, 1105, 1106, 0, 0, 1106, 1107, + 1107, 0, 1107, 1107, 1108, 1108, 0, 1108, 1108, 1108, + 1108, 1108, 1108, 1109, 1109, 1109, 1109, 1109, 1109, 1109, + 1109, 1109, 1110, 1110, 0, 1110, 1110, 1110, 1110, 1110, + 1110, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, + + 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1114, + 0, 1114, 1114, 1115, 1115, 0, 1115, 1115, 1115, 1115, + 1115, 1115, 1116, 1116, 1116, 1116, 1116, 1116, 1116, 1116, + 1116, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, + 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1119, + 1119, 0, 1119, 1119, 1119, 1119, 1119, 1119, 1120, 1120, + 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1121, 1121, 1121, + 1121, 1121, 1121, 1121, 1121, 1121, 1122, 1122, 1122, 1122, + 1122, 1122, 1122, 1122, 1122, 1123, 1123, 1123, 0, 1123, + 1123, 1123, 1123, 1124, 1124, 1124, 1124, 1124, 1124, 1124, + + 1124, 1124, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, + 1125, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, + 1127, 1127, 0, 1127, 1127, 1127, 1127, 1127, 1127, 1128, + 1128, 0, 1128, 1128, 1128, 1128, 1128, 1128, 1129, 1129, + 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1130, 1130, 1130, + 1130, 1130, 1130, 1130, 1130, 1130, 1131, 1131, 1131, 1131, + 1131, 1131, 1131, 1131, 1131, 1132, 1132, 1132, 1132, 1132, + 1132, 1132, 1132, 1132, 1133, 1133, 1133, 1133, 1133, 1133, + 1133, 1133, 1133, 1134, 1134, 1134, 1134, 1134, 1134, 1134, + 1134, 1134, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, + + 1135, 1136, 1136, 0, 0, 1136, 1136, 1136, 1136, 1102, + 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, + 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, + 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, + 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, + 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, + 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, + 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, + 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102 + } ; + +static yy_state_type yy_last_accepting_state; +static char *yy_last_accepting_cpos; + +extern int yy_flex_debug; +int yy_flex_debug = 0; + +/* The intent behind this definition is that it'll catch + * any uses of REJECT which flex missed. + */ +#define REJECT reject_used_but_not_detected +#define yymore() yymore_used_but_not_detected +#define YY_MORE_ADJ 0 +#define YY_RESTORE_YY_MORE_OFFSET +char *yytext; +#line 1 "css.l" + +#line 13 "css.l" +/* Lex source for CSS tokenizing. + Taken from http://www.w3.org/TR/CSS21/grammar.html#q2 + Copyright (C) 2006, 2009-2011, 2015, 2018-2020 Free Software + Foundation, Inc. + +This file is part of GNU Wget. + +GNU Wget is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 3 of the License, or (at +your option) any later version. + +GNU Wget 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 Wget. If not, see . + +Additional permission under GNU GPL version 3 section 7 + +If you modify this program, or any covered work, by linking or +combining it with the OpenSSL project's OpenSSL library (or a +modified version of that library), containing parts covered by the +terms of the OpenSSL or SSLeay licenses, the Free Software Foundation +grants you additional permission to convey the resulting work. +Corresponding Source for a non-source form of such a combination +shall include the source code for the parts of OpenSSL used as well +as that of the covered work. */ + +#define YY_NO_INPUT + +#include "css-tokens.h" + +#if defined __clang__ || __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5) + #pragma GCC diagnostic ignored "-Wunknown-pragmas" // clang mourns about the next one + #pragma GCC diagnostic ignored "-Wunused-function" + #pragma GCC diagnostic ignored "-Wunused-macros" + #pragma GCC diagnostic ignored "-Wunused-parameter" + #pragma GCC diagnostic ignored "-Wsign-compare" + #pragma GCC diagnostic ignored "-Wswitch-default" + #pragma GCC diagnostic ignored "-Wunreachable-code" // clang + #pragma clang diagnostic ignored "-Wshorten-64-to-32" + #ifndef __clang__ + #pragma GCC diagnostic ignored "-Wsuggest-attribute=pure" + #endif +#endif + +#line 2452 "css.c" +#line 2453 "css.c" + +#define INITIAL 0 + +#ifndef YY_NO_UNISTD_H +/* Special case for "unistd.h", since it is non-ANSI. We include it way + * down here because we want the user's section 1 to have been scanned first. + * The user has a chance to override it with an option. + */ +#include +#endif + +#ifndef YY_EXTRA_TYPE +#define YY_EXTRA_TYPE void * +#endif + +static int yy_init_globals ( void ); + +/* Accessor methods to globals. + These are made visible to non-reentrant scanners for convenience. */ + +int yylex_destroy ( void ); + +int yyget_debug ( void ); + +void yyset_debug ( int debug_flag ); + +YY_EXTRA_TYPE yyget_extra ( void ); + +void yyset_extra ( YY_EXTRA_TYPE user_defined ); + +FILE *yyget_in ( void ); + +void yyset_in ( FILE * _in_str ); + +FILE *yyget_out ( void ); + +void yyset_out ( FILE * _out_str ); + + int yyget_leng ( void ); + +char *yyget_text ( void ); + +int yyget_lineno ( void ); + +void yyset_lineno ( int _line_number ); + +/* Macros after this point can all be overridden by user definitions in + * section 1. + */ + +#ifndef YY_SKIP_YYWRAP +#ifdef __cplusplus +extern "C" int yywrap ( void ); +#else +extern int yywrap ( void ); +#endif +#endif + +#ifndef YY_NO_UNPUT + +#endif + +#ifndef yytext_ptr +static void yy_flex_strncpy ( char *, const char *, int ); +#endif + +#ifdef YY_NEED_STRLEN +static int yy_flex_strlen ( const char * ); +#endif + +#ifndef YY_NO_INPUT +#ifdef __cplusplus +static int yyinput ( void ); +#else +static int input ( void ); +#endif + +#endif + +/* Amount of stuff to slurp up with each read. */ +#ifndef YY_READ_BUF_SIZE +#ifdef __ia64__ +/* On IA-64, the buffer size is 16k, not 8k */ +#define YY_READ_BUF_SIZE 16384 +#else +#define YY_READ_BUF_SIZE 8192 +#endif /* __ia64__ */ +#endif + +/* Copy whatever the last rule matched to the standard output. */ +#ifndef ECHO +/* This used to be an fputs(), but since the string might contain NUL's, + * we now use fwrite(). + */ +#define ECHO do { if (fwrite( yytext, (size_t) yyleng, 1, yyout )) {} } while (0) +#endif + +/* Gets input and stuffs it into "buf". number of characters read, or YY_NULL, + * is returned in "result". + */ +#ifndef YY_INPUT +#define YY_INPUT(buf,result,max_size) \ + if ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \ + { \ + int c = '*'; \ + int n; \ + for ( n = 0; n < max_size && \ + (c = getc( yyin )) != EOF && c != '\n'; ++n ) \ + buf[n] = (char) c; \ + if ( c == '\n' ) \ + buf[n++] = (char) c; \ + if ( c == EOF && ferror( yyin ) ) \ + YY_FATAL_ERROR( "input in flex scanner failed" ); \ + result = n; \ + } \ + else \ + { \ + errno=0; \ + while ( (result = (int) fread(buf, 1, (yy_size_t) max_size, yyin)) == 0 && ferror(yyin)) \ + { \ + if( errno != EINTR) \ + { \ + YY_FATAL_ERROR( "input in flex scanner failed" ); \ + break; \ + } \ + errno=0; \ + clearerr(yyin); \ + } \ + }\ +\ + +#endif + +/* No semi-colon after return; correct usage is to write "yyterminate();" - + * we don't want an extra ';' after the "return" because that will cause + * some compilers to complain about unreachable statements. + */ +#ifndef yyterminate +#define yyterminate() return YY_NULL +#endif + +/* Number of entries by which start-condition stack grows. */ +#ifndef YY_START_STACK_INCR +#define YY_START_STACK_INCR 25 +#endif + +/* Report a fatal error. */ +#ifndef YY_FATAL_ERROR +#define YY_FATAL_ERROR(msg) yy_fatal_error( msg ) +#endif + +/* end tables serialization structures and prototypes */ + +/* Default declaration of generated scanner - a define so the user can + * easily add parameters. + */ +#ifndef YY_DECL +#define YY_DECL_IS_OURS 1 + +extern int yylex (void); + +#define YY_DECL int yylex (void) +#endif /* !YY_DECL */ + +/* Code executed at the beginning of each rule, after yytext and yyleng + * have been set up. + */ +#ifndef YY_USER_ACTION +#define YY_USER_ACTION +#endif + +/* Code executed at the end of each rule. */ +#ifndef YY_BREAK +#define YY_BREAK /*LINTED*/break; +#endif + +#define YY_RULE_SETUP \ + YY_USER_ACTION + +/** The main scanner function which does all the work. + */ +YY_DECL +{ + yy_state_type yy_current_state; + char *yy_cp, *yy_bp; + int yy_act; + + if ( !(yy_init) ) + { + (yy_init) = 1; + +#ifdef YY_USER_INIT + YY_USER_INIT; +#endif + + if ( ! (yy_start) ) + (yy_start) = 1; /* first start state */ + + if ( ! yyin ) + yyin = stdin; + + if ( ! yyout ) + yyout = stdout; + + if ( ! YY_CURRENT_BUFFER ) { + yyensure_buffer_stack (); + YY_CURRENT_BUFFER_LVALUE = + yy_create_buffer( yyin, YY_BUF_SIZE ); + } + + yy_load_buffer_state( ); + } + + { +#line 112 "css.l" + + +#line 2671 "css.c" + + while ( /*CONSTCOND*/1 ) /* loops until end-of-file is reached */ + { + yy_cp = (yy_c_buf_p); + + /* Support of yytext. */ + *yy_cp = (yy_hold_char); + + /* yy_bp points to the position in yy_ch_buf of the start of + * the current run. + */ + yy_bp = yy_cp; + + yy_current_state = (yy_start); +yy_match: + do + { + YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)] ; + if ( yy_accept[yy_current_state] ) + { + (yy_last_accepting_state) = yy_current_state; + (yy_last_accepting_cpos) = yy_cp; + } + while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) + { + yy_current_state = (int) yy_def[yy_current_state]; + if ( yy_current_state >= 1103 ) + yy_c = yy_meta[yy_c]; + } + yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c]; + ++yy_cp; + } + while ( yy_current_state != 1102 ); + yy_cp = (yy_last_accepting_cpos); + yy_current_state = (yy_last_accepting_state); + +yy_find_action: + yy_act = yy_accept[yy_current_state]; + + YY_DO_BEFORE_ACTION; + +do_action: /* This label is used only to access EOF actions. */ + + switch ( yy_act ) + { /* beginning of action switch */ + case 0: /* must back up */ + /* undo the effects of YY_DO_BEFORE_ACTION */ + *yy_cp = (yy_hold_char); + yy_cp = (yy_last_accepting_cpos); + yy_current_state = (yy_last_accepting_state); + goto yy_find_action; + +case 1: +/* rule 1 can match eol */ +YY_RULE_SETUP +#line 114 "css.l" +{return S;} + YY_BREAK +case 2: +/* rule 2 can match eol */ +YY_RULE_SETUP +#line 116 "css.l" +{return COMMENT;} + YY_BREAK +case 3: +/* rule 3 can match eol */ +YY_RULE_SETUP +#line 117 "css.l" +/* ignore comments */ + YY_BREAK +case 4: +/* rule 4 can match eol */ +YY_RULE_SETUP +#line 118 "css.l" +/* unclosed comment at EOF */ + YY_BREAK +case 5: +YY_RULE_SETUP +#line 120 "css.l" +{return CDO;} + YY_BREAK +case 6: +YY_RULE_SETUP +#line 121 "css.l" +{return CDC;} + YY_BREAK +case 7: +YY_RULE_SETUP +#line 122 "css.l" +{return INCLUDES;} + YY_BREAK +case 8: +YY_RULE_SETUP +#line 123 "css.l" +{return DASHMATCH;} + YY_BREAK +case 9: +/* rule 9 can match eol */ +YY_RULE_SETUP +#line 125 "css.l" +{return STRING;} + YY_BREAK +case 10: +/* rule 10 can match eol */ +YY_RULE_SETUP +#line 126 "css.l" +{return BAD_STRING;} + YY_BREAK +case 11: +/* rule 11 can match eol */ +YY_RULE_SETUP +#line 128 "css.l" +{return IDENT;} + YY_BREAK +case 12: +/* rule 12 can match eol */ +YY_RULE_SETUP +#line 130 "css.l" +{return HASH;} + YY_BREAK +case 13: +/* rule 13 can match eol */ +YY_RULE_SETUP +#line 132 "css.l" +{return IMPORT_SYM;} + YY_BREAK +case 14: +/* rule 14 can match eol */ +YY_RULE_SETUP +#line 133 "css.l" +{return PAGE_SYM;} + YY_BREAK +case 15: +/* rule 15 can match eol */ +YY_RULE_SETUP +#line 134 "css.l" +{return MEDIA_SYM;} + YY_BREAK +case 16: +YY_RULE_SETUP +#line 135 "css.l" +{return CHARSET_SYM;} + YY_BREAK +case 17: +/* rule 17 can match eol */ +YY_RULE_SETUP +#line 137 "css.l" +{return IMPORTANT_SYM;} + YY_BREAK +case 18: +/* rule 18 can match eol */ +YY_RULE_SETUP +#line 139 "css.l" +{return EMS;} + YY_BREAK +case 19: +/* rule 19 can match eol */ +YY_RULE_SETUP +#line 140 "css.l" +{return EXS;} + YY_BREAK +case 20: +/* rule 20 can match eol */ +YY_RULE_SETUP +#line 141 "css.l" +{return LENGTH;} + YY_BREAK +case 21: +/* rule 21 can match eol */ +YY_RULE_SETUP +#line 142 "css.l" +{return LENGTH;} + YY_BREAK +case 22: +/* rule 22 can match eol */ +YY_RULE_SETUP +#line 143 "css.l" +{return LENGTH;} + YY_BREAK +case 23: +/* rule 23 can match eol */ +YY_RULE_SETUP +#line 144 "css.l" +{return LENGTH;} + YY_BREAK +case 24: +/* rule 24 can match eol */ +YY_RULE_SETUP +#line 145 "css.l" +{return LENGTH;} + YY_BREAK +case 25: +/* rule 25 can match eol */ +YY_RULE_SETUP +#line 146 "css.l" +{return LENGTH;} + YY_BREAK +case 26: +/* rule 26 can match eol */ +YY_RULE_SETUP +#line 147 "css.l" +{return ANGLE;} + YY_BREAK +case 27: +/* rule 27 can match eol */ +YY_RULE_SETUP +#line 148 "css.l" +{return ANGLE;} + YY_BREAK +case 28: +/* rule 28 can match eol */ +YY_RULE_SETUP +#line 149 "css.l" +{return ANGLE;} + YY_BREAK +case 29: +/* rule 29 can match eol */ +YY_RULE_SETUP +#line 150 "css.l" +{return TIME;} + YY_BREAK +case 30: +/* rule 30 can match eol */ +YY_RULE_SETUP +#line 151 "css.l" +{return TIME;} + YY_BREAK +case 31: +/* rule 31 can match eol */ +YY_RULE_SETUP +#line 152 "css.l" +{return FREQ;} + YY_BREAK +case 32: +/* rule 32 can match eol */ +YY_RULE_SETUP +#line 153 "css.l" +{return FREQ;} + YY_BREAK +case 33: +/* rule 33 can match eol */ +YY_RULE_SETUP +#line 154 "css.l" +{return DIMENSION;} + YY_BREAK +case 34: +YY_RULE_SETUP +#line 156 "css.l" +{return PERCENTAGE;} + YY_BREAK +case 35: +YY_RULE_SETUP +#line 157 "css.l" +{return NUMBER;} + YY_BREAK +case 36: +/* rule 36 can match eol */ +YY_RULE_SETUP +#line 159 "css.l" +{return URI;} + YY_BREAK +case 37: +/* rule 37 can match eol */ +YY_RULE_SETUP +#line 160 "css.l" +{return URI;} + YY_BREAK +case 38: +/* rule 38 can match eol */ +YY_RULE_SETUP +#line 161 "css.l" +{return BAD_URI;} + YY_BREAK +case 39: +/* rule 39 can match eol */ +YY_RULE_SETUP +#line 163 "css.l" +{return FUNCTION;} + YY_BREAK +case 40: +YY_RULE_SETUP +#line 165 "css.l" +{return *yytext;} + YY_BREAK +case 41: +YY_RULE_SETUP +#line 167 "css.l" +ECHO; + YY_BREAK +#line 2961 "css.c" +case YY_STATE_EOF(INITIAL): + yyterminate(); + + case YY_END_OF_BUFFER: + { + /* Amount of text matched not including the EOB char. */ + int yy_amount_of_matched_text = (int) (yy_cp - (yytext_ptr)) - 1; + + /* Undo the effects of YY_DO_BEFORE_ACTION. */ + *yy_cp = (yy_hold_char); + YY_RESTORE_YY_MORE_OFFSET + + if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_NEW ) + { + /* We're scanning a new file or input source. It's + * possible that this happened because the user + * just pointed yyin at a new source and called + * yylex(). If so, then we have to assure + * consistency between YY_CURRENT_BUFFER and our + * globals. Here is the right place to do so, because + * this is the first action (other than possibly a + * back-up) that will match for the new input source. + */ + (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; + YY_CURRENT_BUFFER_LVALUE->yy_input_file = yyin; + YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_NORMAL; + } + + /* Note that here we test for yy_c_buf_p "<=" to the position + * of the first EOB in the buffer, since yy_c_buf_p will + * already have been incremented past the NUL character + * (since all states make transitions on EOB to the + * end-of-buffer state). Contrast this with the test + * in input(). + */ + if ( (yy_c_buf_p) <= &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] ) + { /* This was really a NUL. */ + yy_state_type yy_next_state; + + (yy_c_buf_p) = (yytext_ptr) + yy_amount_of_matched_text; + + yy_current_state = yy_get_previous_state( ); + + /* Okay, we're now positioned to make the NUL + * transition. We couldn't have + * yy_get_previous_state() go ahead and do it + * for us because it doesn't know how to deal + * with the possibility of jamming (and we don't + * want to build jamming into it because then it + * will run more slowly). + */ + + yy_next_state = yy_try_NUL_trans( yy_current_state ); + + yy_bp = (yytext_ptr) + YY_MORE_ADJ; + + if ( yy_next_state ) + { + /* Consume the NUL. */ + yy_cp = ++(yy_c_buf_p); + yy_current_state = yy_next_state; + goto yy_match; + } + + else + { + yy_cp = (yy_last_accepting_cpos); + yy_current_state = (yy_last_accepting_state); + goto yy_find_action; + } + } + + else switch ( yy_get_next_buffer( ) ) + { + case EOB_ACT_END_OF_FILE: + { + (yy_did_buffer_switch_on_eof) = 0; + + if ( yywrap( ) ) + { + /* Note: because we've taken care in + * yy_get_next_buffer() to have set up + * yytext, we can now set up + * yy_c_buf_p so that if some total + * hoser (like flex itself) wants to + * call the scanner after we return the + * YY_NULL, it'll still work - another + * YY_NULL will get returned. + */ + (yy_c_buf_p) = (yytext_ptr) + YY_MORE_ADJ; + + yy_act = YY_STATE_EOF(YY_START); + goto do_action; + } + + else + { + if ( ! (yy_did_buffer_switch_on_eof) ) + YY_NEW_FILE; + } + break; + } + + case EOB_ACT_CONTINUE_SCAN: + (yy_c_buf_p) = + (yytext_ptr) + yy_amount_of_matched_text; + + yy_current_state = yy_get_previous_state( ); + + yy_cp = (yy_c_buf_p); + yy_bp = (yytext_ptr) + YY_MORE_ADJ; + goto yy_match; + + case EOB_ACT_LAST_MATCH: + (yy_c_buf_p) = + &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)]; + + yy_current_state = yy_get_previous_state( ); + + yy_cp = (yy_c_buf_p); + yy_bp = (yytext_ptr) + YY_MORE_ADJ; + goto yy_find_action; + } + break; + } + + default: + YY_FATAL_ERROR( + "fatal flex scanner internal error--no action found" ); + } /* end of action switch */ + } /* end of scanning one token */ + } /* end of user's declarations */ +} /* end of yylex */ + +/* yy_get_next_buffer - try to read in a new buffer + * + * Returns a code representing an action: + * EOB_ACT_LAST_MATCH - + * EOB_ACT_CONTINUE_SCAN - continue scanning from current position + * EOB_ACT_END_OF_FILE - end of file + */ +static int yy_get_next_buffer (void) +{ + char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf; + char *source = (yytext_ptr); + int number_to_move, i; + int ret_val; + + if ( (yy_c_buf_p) > &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] ) + YY_FATAL_ERROR( + "fatal flex scanner internal error--end of buffer missed" ); + + if ( YY_CURRENT_BUFFER_LVALUE->yy_fill_buffer == 0 ) + { /* Don't try to fill the buffer, so this is an EOF. */ + if ( (yy_c_buf_p) - (yytext_ptr) - YY_MORE_ADJ == 1 ) + { + /* We matched a single character, the EOB, so + * treat this as a final EOF. + */ + return EOB_ACT_END_OF_FILE; + } + + else + { + /* We matched some text prior to the EOB, first + * process it. + */ + return EOB_ACT_LAST_MATCH; + } + } + + /* Try to read more data. */ + + /* First move last chars to start of buffer. */ + number_to_move = (int) ((yy_c_buf_p) - (yytext_ptr) - 1); + + for ( i = 0; i < number_to_move; ++i ) + *(dest++) = *(source++); + + if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_EOF_PENDING ) + /* don't do the read, it's not guaranteed to return an EOF, + * just force an EOF + */ + YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars) = 0; + + else + { + int num_to_read = + YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1; + + while ( num_to_read <= 0 ) + { /* Not enough room in the buffer - grow it. */ + + /* just a shorter name for the current buffer */ + YY_BUFFER_STATE b = YY_CURRENT_BUFFER_LVALUE; + + int yy_c_buf_p_offset = + (int) ((yy_c_buf_p) - b->yy_ch_buf); + + if ( b->yy_is_our_buffer ) + { + int new_size = b->yy_buf_size * 2; + + if ( new_size <= 0 ) + b->yy_buf_size += b->yy_buf_size / 8; + else + b->yy_buf_size *= 2; + + b->yy_ch_buf = (char *) + /* Include room in for 2 EOB chars. */ + yyrealloc( (void *) b->yy_ch_buf, + (yy_size_t) (b->yy_buf_size + 2) ); + } + else + /* Can't grow it, we don't own it. */ + b->yy_ch_buf = NULL; + + if ( ! b->yy_ch_buf ) + YY_FATAL_ERROR( + "fatal error - scanner input buffer overflow" ); + + (yy_c_buf_p) = &b->yy_ch_buf[yy_c_buf_p_offset]; + + num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size - + number_to_move - 1; + + } + + if ( num_to_read > YY_READ_BUF_SIZE ) + num_to_read = YY_READ_BUF_SIZE; + + /* Read in more data. */ + YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]), + (yy_n_chars), num_to_read ); + + YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); + } + + if ( (yy_n_chars) == 0 ) + { + if ( number_to_move == YY_MORE_ADJ ) + { + ret_val = EOB_ACT_END_OF_FILE; + yyrestart( yyin ); + } + + else + { + ret_val = EOB_ACT_LAST_MATCH; + YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = + YY_BUFFER_EOF_PENDING; + } + } + + else + ret_val = EOB_ACT_CONTINUE_SCAN; + + if (((yy_n_chars) + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) { + /* Extend the array by 50%, plus the number we really need. */ + int new_size = (yy_n_chars) + number_to_move + ((yy_n_chars) >> 1); + YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) yyrealloc( + (void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf, (yy_size_t) new_size ); + if ( ! YY_CURRENT_BUFFER_LVALUE->yy_ch_buf ) + YY_FATAL_ERROR( "out of dynamic memory in yy_get_next_buffer()" ); + /* "- 2" to take care of EOB's */ + YY_CURRENT_BUFFER_LVALUE->yy_buf_size = (int) (new_size - 2); + } + + (yy_n_chars) += number_to_move; + YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] = YY_END_OF_BUFFER_CHAR; + YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] = YY_END_OF_BUFFER_CHAR; + + (yytext_ptr) = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[0]; + + return ret_val; +} + +/* yy_get_previous_state - get the state just before the EOB char was reached */ + + static yy_state_type yy_get_previous_state (void) +{ + yy_state_type yy_current_state; + char *yy_cp; + + yy_current_state = (yy_start); + + for ( yy_cp = (yytext_ptr) + YY_MORE_ADJ; yy_cp < (yy_c_buf_p); ++yy_cp ) + { + YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1); + if ( yy_accept[yy_current_state] ) + { + (yy_last_accepting_state) = yy_current_state; + (yy_last_accepting_cpos) = yy_cp; + } + while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) + { + yy_current_state = (int) yy_def[yy_current_state]; + if ( yy_current_state >= 1103 ) + yy_c = yy_meta[yy_c]; + } + yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c]; + } + + return yy_current_state; +} + +/* yy_try_NUL_trans - try to make a transition on the NUL character + * + * synopsis + * next_state = yy_try_NUL_trans( current_state ); + */ + static yy_state_type yy_try_NUL_trans (yy_state_type yy_current_state ) +{ + int yy_is_jam; + char *yy_cp = (yy_c_buf_p); + + YY_CHAR yy_c = 1; + if ( yy_accept[yy_current_state] ) + { + (yy_last_accepting_state) = yy_current_state; + (yy_last_accepting_cpos) = yy_cp; + } + while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) + { + yy_current_state = (int) yy_def[yy_current_state]; + if ( yy_current_state >= 1103 ) + yy_c = yy_meta[yy_c]; + } + yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c]; + yy_is_jam = (yy_current_state == 1102); + + return yy_is_jam ? 0 : yy_current_state; +} + +#ifndef YY_NO_UNPUT + +#endif + +#ifndef YY_NO_INPUT +#ifdef __cplusplus + static int yyinput (void) +#else + static int input (void) +#endif + +{ + int c; + + *(yy_c_buf_p) = (yy_hold_char); + + if ( *(yy_c_buf_p) == YY_END_OF_BUFFER_CHAR ) + { + /* yy_c_buf_p now points to the character we want to return. + * If this occurs *before* the EOB characters, then it's a + * valid NUL; if not, then we've hit the end of the buffer. + */ + if ( (yy_c_buf_p) < &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] ) + /* This was really a NUL. */ + *(yy_c_buf_p) = '\0'; + + else + { /* need more input */ + int offset = (int) ((yy_c_buf_p) - (yytext_ptr)); + ++(yy_c_buf_p); + + switch ( yy_get_next_buffer( ) ) + { + case EOB_ACT_LAST_MATCH: + /* This happens because yy_g_n_b() + * sees that we've accumulated a + * token and flags that we need to + * try matching the token before + * proceeding. But for input(), + * there's no matching to consider. + * So convert the EOB_ACT_LAST_MATCH + * to EOB_ACT_END_OF_FILE. + */ + + /* Reset buffer status. */ + yyrestart( yyin ); + + /*FALLTHROUGH*/ + + case EOB_ACT_END_OF_FILE: + { + if ( yywrap( ) ) + return 0; + + if ( ! (yy_did_buffer_switch_on_eof) ) + YY_NEW_FILE; +#ifdef __cplusplus + return yyinput(); +#else + return input(); +#endif + } + + case EOB_ACT_CONTINUE_SCAN: + (yy_c_buf_p) = (yytext_ptr) + offset; + break; + } + } + } + + c = *(unsigned char *) (yy_c_buf_p); /* cast for 8-bit char's */ + *(yy_c_buf_p) = '\0'; /* preserve yytext */ + (yy_hold_char) = *++(yy_c_buf_p); + + return c; +} +#endif /* ifndef YY_NO_INPUT */ + +/** Immediately switch to a different input stream. + * @param input_file A readable stream. + * + * @note This function does not reset the start condition to @c INITIAL . + */ + void yyrestart (FILE * input_file ) +{ + + if ( ! YY_CURRENT_BUFFER ){ + yyensure_buffer_stack (); + YY_CURRENT_BUFFER_LVALUE = + yy_create_buffer( yyin, YY_BUF_SIZE ); + } + + yy_init_buffer( YY_CURRENT_BUFFER, input_file ); + yy_load_buffer_state( ); +} + +/** Switch to a different input buffer. + * @param new_buffer The new input buffer. + * + */ + void yy_switch_to_buffer (YY_BUFFER_STATE new_buffer ) +{ + + /* TODO. We should be able to replace this entire function body + * with + * yypop_buffer_state(); + * yypush_buffer_state(new_buffer); + */ + yyensure_buffer_stack (); + if ( YY_CURRENT_BUFFER == new_buffer ) + return; + + if ( YY_CURRENT_BUFFER ) + { + /* Flush out information for old buffer. */ + *(yy_c_buf_p) = (yy_hold_char); + YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p); + YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); + } + + YY_CURRENT_BUFFER_LVALUE = new_buffer; + yy_load_buffer_state( ); + + /* We don't actually know whether we did this switch during + * EOF (yywrap()) processing, but the only time this flag + * is looked at is after yywrap() is called, so it's safe + * to go ahead and always set it. + */ + (yy_did_buffer_switch_on_eof) = 1; +} + +static void yy_load_buffer_state (void) +{ + (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; + (yytext_ptr) = (yy_c_buf_p) = YY_CURRENT_BUFFER_LVALUE->yy_buf_pos; + yyin = YY_CURRENT_BUFFER_LVALUE->yy_input_file; + (yy_hold_char) = *(yy_c_buf_p); +} + +/** Allocate and initialize an input buffer state. + * @param file A readable stream. + * @param size The character buffer size in bytes. When in doubt, use @c YY_BUF_SIZE. + * + * @return the allocated buffer state. + */ + YY_BUFFER_STATE yy_create_buffer (FILE * file, int size ) +{ + YY_BUFFER_STATE b; + + b = (YY_BUFFER_STATE) yyalloc( sizeof( struct yy_buffer_state ) ); + if ( ! b ) + YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); + + b->yy_buf_size = size; + + /* yy_ch_buf has to be 2 characters longer than the size given because + * we need to put in 2 end-of-buffer characters. + */ + b->yy_ch_buf = (char *) yyalloc( (yy_size_t) (b->yy_buf_size + 2) ); + if ( ! b->yy_ch_buf ) + YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); + + b->yy_is_our_buffer = 1; + + yy_init_buffer( b, file ); + + return b; +} + +/** Destroy the buffer. + * @param b a buffer created with yy_create_buffer() + * + */ + void yy_delete_buffer (YY_BUFFER_STATE b ) +{ + + if ( ! b ) + return; + + if ( b == YY_CURRENT_BUFFER ) /* Not sure if we should pop here. */ + YY_CURRENT_BUFFER_LVALUE = (YY_BUFFER_STATE) 0; + + if ( b->yy_is_our_buffer ) + yyfree( (void *) b->yy_ch_buf ); + + yyfree( (void *) b ); +} + +/* Initializes or reinitializes a buffer. + * This function is sometimes called more than once on the same buffer, + * such as during a yyrestart() or at EOF. + */ + static void yy_init_buffer (YY_BUFFER_STATE b, FILE * file ) + +{ + int oerrno = errno; + + yy_flush_buffer( b ); + + b->yy_input_file = file; + b->yy_fill_buffer = 1; + + /* If b is the current buffer, then yy_init_buffer was _probably_ + * called from yyrestart() or through yy_get_next_buffer. + * In that case, we don't want to reset the lineno or column. + */ + if (b != YY_CURRENT_BUFFER){ + b->yy_bs_lineno = 1; + b->yy_bs_column = 0; + } + + b->yy_is_interactive = 0; + + errno = oerrno; +} + +/** Discard all buffered characters. On the next scan, YY_INPUT will be called. + * @param b the buffer state to be flushed, usually @c YY_CURRENT_BUFFER. + * + */ + void yy_flush_buffer (YY_BUFFER_STATE b ) +{ + if ( ! b ) + return; + + b->yy_n_chars = 0; + + /* We always need two end-of-buffer characters. The first causes + * a transition to the end-of-buffer state. The second causes + * a jam in that state. + */ + b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR; + b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR; + + b->yy_buf_pos = &b->yy_ch_buf[0]; + + b->yy_at_bol = 1; + b->yy_buffer_status = YY_BUFFER_NEW; + + if ( b == YY_CURRENT_BUFFER ) + yy_load_buffer_state( ); +} + +/** Pushes the new state onto the stack. The new state becomes + * the current state. This function will allocate the stack + * if necessary. + * @param new_buffer The new state. + * + */ +void yypush_buffer_state (YY_BUFFER_STATE new_buffer ) +{ + if (new_buffer == NULL) + return; + + yyensure_buffer_stack(); + + /* This block is copied from yy_switch_to_buffer. */ + if ( YY_CURRENT_BUFFER ) + { + /* Flush out information for old buffer. */ + *(yy_c_buf_p) = (yy_hold_char); + YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p); + YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); + } + + /* Only push if top exists. Otherwise, replace top. */ + if (YY_CURRENT_BUFFER) + (yy_buffer_stack_top)++; + YY_CURRENT_BUFFER_LVALUE = new_buffer; + + /* copied from yy_switch_to_buffer. */ + yy_load_buffer_state( ); + (yy_did_buffer_switch_on_eof) = 1; +} + +/** Removes and deletes the top of the stack, if present. + * The next element becomes the new top. + * + */ +void yypop_buffer_state (void) +{ + if (!YY_CURRENT_BUFFER) + return; + + yy_delete_buffer(YY_CURRENT_BUFFER ); + YY_CURRENT_BUFFER_LVALUE = NULL; + if ((yy_buffer_stack_top) > 0) + --(yy_buffer_stack_top); + + if (YY_CURRENT_BUFFER) { + yy_load_buffer_state( ); + (yy_did_buffer_switch_on_eof) = 1; + } +} + +/* Allocates the stack if it does not exist. + * Guarantees space for at least one push. + */ +static void yyensure_buffer_stack (void) +{ + yy_size_t num_to_alloc; + + if (!(yy_buffer_stack)) { + + /* First allocation is just for 2 elements, since we don't know if this + * scanner will even need a stack. We use 2 instead of 1 to avoid an + * immediate realloc on the next call. + */ + num_to_alloc = 1; /* After all that talk, this was set to 1 anyways... */ + (yy_buffer_stack) = (struct yy_buffer_state**)yyalloc + (num_to_alloc * sizeof(struct yy_buffer_state*) + ); + if ( ! (yy_buffer_stack) ) + YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" ); + + memset((yy_buffer_stack), 0, num_to_alloc * sizeof(struct yy_buffer_state*)); + + (yy_buffer_stack_max) = num_to_alloc; + (yy_buffer_stack_top) = 0; + return; + } + + if ((yy_buffer_stack_top) >= ((yy_buffer_stack_max)) - 1){ + + /* Increase the buffer to prepare for a possible push. */ + yy_size_t grow_size = 8 /* arbitrary grow size */; + + num_to_alloc = (yy_buffer_stack_max) + grow_size; + (yy_buffer_stack) = (struct yy_buffer_state**)yyrealloc + ((yy_buffer_stack), + num_to_alloc * sizeof(struct yy_buffer_state*) + ); + if ( ! (yy_buffer_stack) ) + YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" ); + + /* zero only the new slots.*/ + memset((yy_buffer_stack) + (yy_buffer_stack_max), 0, grow_size * sizeof(struct yy_buffer_state*)); + (yy_buffer_stack_max) = num_to_alloc; + } +} + +/** Setup the input buffer state to scan directly from a user-specified character buffer. + * @param base the character buffer + * @param size the size in bytes of the character buffer + * + * @return the newly allocated buffer state object. + */ +YY_BUFFER_STATE yy_scan_buffer (char * base, yy_size_t size ) +{ + YY_BUFFER_STATE b; + + if ( size < 2 || + base[size-2] != YY_END_OF_BUFFER_CHAR || + base[size-1] != YY_END_OF_BUFFER_CHAR ) + /* They forgot to leave room for the EOB's. */ + return NULL; + + b = (YY_BUFFER_STATE) yyalloc( sizeof( struct yy_buffer_state ) ); + if ( ! b ) + YY_FATAL_ERROR( "out of dynamic memory in yy_scan_buffer()" ); + + b->yy_buf_size = (int) (size - 2); /* "- 2" to take care of EOB's */ + b->yy_buf_pos = b->yy_ch_buf = base; + b->yy_is_our_buffer = 0; + b->yy_input_file = NULL; + b->yy_n_chars = b->yy_buf_size; + b->yy_is_interactive = 0; + b->yy_at_bol = 1; + b->yy_fill_buffer = 0; + b->yy_buffer_status = YY_BUFFER_NEW; + + yy_switch_to_buffer( b ); + + return b; +} + +/** Setup the input buffer state to scan a string. The next call to yylex() will + * scan from a @e copy of @a str. + * @param yystr a NUL-terminated string to scan + * + * @return the newly allocated buffer state object. + * @note If you want to scan bytes that may contain NUL values, then use + * yy_scan_bytes() instead. + */ +YY_BUFFER_STATE yy_scan_string (const char * yystr ) +{ + + return yy_scan_bytes( yystr, (int) strlen(yystr) ); +} + +/** Setup the input buffer state to scan the given bytes. The next call to yylex() will + * scan from a @e copy of @a bytes. + * @param yybytes the byte buffer to scan + * @param _yybytes_len the number of bytes in the buffer pointed to by @a bytes. + * + * @return the newly allocated buffer state object. + */ +YY_BUFFER_STATE yy_scan_bytes (const char * yybytes, int _yybytes_len ) +{ + YY_BUFFER_STATE b; + char *buf; + yy_size_t n; + int i; + + /* Get memory for full buffer, including space for trailing EOB's. */ + n = (yy_size_t) (_yybytes_len + 2); + buf = (char *) yyalloc( n ); + if ( ! buf ) + YY_FATAL_ERROR( "out of dynamic memory in yy_scan_bytes()" ); + + for ( i = 0; i < _yybytes_len; ++i ) + buf[i] = yybytes[i]; + + buf[_yybytes_len] = buf[_yybytes_len+1] = YY_END_OF_BUFFER_CHAR; + + b = yy_scan_buffer( buf, n ); + if ( ! b ) + YY_FATAL_ERROR( "bad buffer in yy_scan_bytes()" ); + + /* It's okay to grow etc. this buffer, and we should throw it + * away when we're done. + */ + b->yy_is_our_buffer = 1; + + return b; +} + +#ifndef YY_EXIT_FAILURE +#define YY_EXIT_FAILURE 2 +#endif + +static void yynoreturn yy_fatal_error (const char* msg ) +{ + fprintf( stderr, "%s\n", msg ); + exit( YY_EXIT_FAILURE ); +} + +/* Redefine yyless() so it works in section 3 code. */ + +#undef yyless +#define yyless(n) \ + do \ + { \ + /* Undo effects of setting up yytext. */ \ + int yyless_macro_arg = (n); \ + YY_LESS_LINENO(yyless_macro_arg);\ + yytext[yyleng] = (yy_hold_char); \ + (yy_c_buf_p) = yytext + yyless_macro_arg; \ + (yy_hold_char) = *(yy_c_buf_p); \ + *(yy_c_buf_p) = '\0'; \ + yyleng = yyless_macro_arg; \ + } \ + while ( 0 ) + +/* Accessor methods (get/set functions) to struct members. */ + +/** Get the current line number. + * + */ +int yyget_lineno (void) +{ + + return yylineno; +} + +/** Get the input stream. + * + */ +FILE *yyget_in (void) +{ + return yyin; +} + +/** Get the output stream. + * + */ +FILE *yyget_out (void) +{ + return yyout; +} + +/** Get the length of the current token. + * + */ +int yyget_leng (void) +{ + return yyleng; +} + +/** Get the current token. + * + */ + +char *yyget_text (void) +{ + return yytext; +} + +/** Set the current line number. + * @param _line_number line number + * + */ +void yyset_lineno (int _line_number ) +{ + + yylineno = _line_number; +} + +/** Set the input stream. This does not discard the current + * input buffer. + * @param _in_str A readable stream. + * + * @see yy_switch_to_buffer + */ +void yyset_in (FILE * _in_str ) +{ + yyin = _in_str ; +} + +void yyset_out (FILE * _out_str ) +{ + yyout = _out_str ; +} + +int yyget_debug (void) +{ + return yy_flex_debug; +} + +void yyset_debug (int _bdebug ) +{ + yy_flex_debug = _bdebug ; +} + +static int yy_init_globals (void) +{ + /* Initialization is the same as for the non-reentrant scanner. + * This function is called from yylex_destroy(), so don't allocate here. + */ + + (yy_buffer_stack) = NULL; + (yy_buffer_stack_top) = 0; + (yy_buffer_stack_max) = 0; + (yy_c_buf_p) = NULL; + (yy_init) = 0; + (yy_start) = 0; + +/* Defined in main.c */ +#ifdef YY_STDINIT + yyin = stdin; + yyout = stdout; +#else + yyin = NULL; + yyout = NULL; +#endif + + /* For future reference: Set errno on error, since we are called by + * yylex_init() + */ + return 0; +} + +/* yylex_destroy is for both reentrant and non-reentrant scanners. */ +int yylex_destroy (void) +{ + + /* Pop the buffer stack, destroying each element. */ + while(YY_CURRENT_BUFFER){ + yy_delete_buffer( YY_CURRENT_BUFFER ); + YY_CURRENT_BUFFER_LVALUE = NULL; + yypop_buffer_state(); + } + + /* Destroy the stack itself. */ + yyfree((yy_buffer_stack) ); + (yy_buffer_stack) = NULL; + + /* Reset the globals. This is important in a non-reentrant scanner so the next time + * yylex() is called, initialization will occur. */ + yy_init_globals( ); + + return 0; +} + +/* + * Internal utility routines. + */ + +#ifndef yytext_ptr +static void yy_flex_strncpy (char* s1, const char * s2, int n ) +{ + + int i; + for ( i = 0; i < n; ++i ) + s1[i] = s2[i]; +} +#endif + +#ifdef YY_NEED_STRLEN +static int yy_flex_strlen (const char * s ) +{ + int n; + for ( n = 0; s[n]; ++n ) + ; + + return n; +} +#endif + +void *yyalloc (yy_size_t size ) +{ + return malloc(size); +} + +void *yyrealloc (void * ptr, yy_size_t size ) +{ + + /* The cast to (char *) in the following accommodates both + * implementations that use char* generic pointers, and those + * that use void* generic pointers. It works with the latter + * because both ANSI C and C++ allow castless assignment from + * any pointer type to void*, and deal with argument conversions + * as though doing an assignment. + */ + return realloc(ptr, size); +} + +void yyfree (void * ptr ) +{ + free( (char *) ptr ); /* see yyrealloc() for (char *) cast */ +} + +#define YYTABLES_NAME "yytables" + +#line 167 "css.l" + + diff --git a/src/exits.c b/src/exits.c new file mode 100644 index 0000000..56a7eb7 --- /dev/null +++ b/src/exits.c @@ -0,0 +1,93 @@ +/* Exit status handling. + Copyright (C) 2009-2012, 2015, 2018-2020 Free Software Foundation, + Inc. + + This file is part of GNU Wget. + + GNU Wget is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + GNU Wget 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 Wget. If not, see . +*/ + +#include "wget.h" +#include "exits.h" + +static int final_exit_status = WGET_EXIT_SUCCESS; + +/* XXX: I don't like that newly-added uerr_t codes will doubtless fall + through the craccks, or the fact that we seem to have way more + codes than we know what to do with. Need to go through and sort + through the truly essential codes, and merge the rest with + those. Quite a few are never even used! + + Quite a few of the codes below would have no business being + returned to retrieve_url's caller, but since it's very difficult to + determine which do and which don't, I grab virtually all of them to + be safe. */ +static int +get_status_for_err (uerr_t err) +{ + switch (err) + { + case RETROK: + return WGET_EXIT_SUCCESS; + case FOPENERR: case FOPEN_EXCL_ERR: case FWRITEERR: case WRITEFAILED: + case UNLINKERR: case CLOSEFAILED: case FILEBADFILE: + return WGET_EXIT_IO_FAIL; + case NOCONERROR: case HOSTERR: case CONSOCKERR: case CONERROR: + case CONSSLERR: case CONIMPOSSIBLE: case FTPRERR: case FTPINVPASV: + case READERR: case TRYLIMEXC: + return WGET_EXIT_NETWORK_FAIL; + case VERIFCERTERR: + return WGET_EXIT_SSL_AUTH_FAIL; + case FTPLOGINC: case FTPLOGREFUSED: case AUTHFAILED: + return WGET_EXIT_SERVER_AUTH_FAIL; + case HEOF: case HERR: case ATTRMISSING: + return WGET_EXIT_PROTOCOL_ERROR; + case WRONGCODE: case FTPPORTERR: case FTPSYSERR: + case FTPNSFOD: case FTPUNKNOWNTYPE: case FTPSRVERR: + case FTPRETRINT: case FTPRESTFAIL: case FTPNOPASV: + case CONTNOTSUPPORTED: case RANGEERR: case RETRBADPATTERN: + case PROXERR: case GATEWAYTIMEOUT: + return WGET_EXIT_SERVER_ERROR; + case URLERROR: case QUOTEXC: case SSLINITFAILED: case UNKNOWNATTR: + default: + return WGET_EXIT_UNKNOWN; + } +} + +/* inform_exit_status + * + * Ensure that Wget's exit status will reflect the problem indicated + * by ERR, unless the exit status has already been set to reflect a more + * important problem. */ +void +inform_exit_status (uerr_t err) +{ + int new_status = get_status_for_err (err); + + if (new_status != WGET_EXIT_SUCCESS + && (final_exit_status == WGET_EXIT_SUCCESS + || new_status < final_exit_status)) + { + final_exit_status = new_status; + } +} + +int +get_exit_status (void) +{ + return + (final_exit_status == WGET_EXIT_UNKNOWN) + ? 1 + : final_exit_status; +} diff --git a/src/exits.h b/src/exits.h new file mode 100644 index 0000000..169ade1 --- /dev/null +++ b/src/exits.h @@ -0,0 +1,48 @@ +/* Exit status related declarations. + Copyright (C) 2009-2012, 2015, 2018-2020 Free Software Foundation, + Inc. + +This file is part of GNU Wget. + +GNU Wget is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 3 of the License, or +(at your option) any later version. + +GNU Wget 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 Wget. If not, see . */ + +#ifndef WGET_EXITS_H +#define WGET_EXITS_H + +#include "wget.h" + +/* Final exit code possibilities. Exit codes 1 and 2 are reserved + * for situations that lead to direct exits from Wget, not using the + * value of final_exit_status. */ +enum + { + WGET_EXIT_SUCCESS = 0, + WGET_EXIT_GENERIC_ERROR = 1, + WGET_EXIT_PARSE_ERROR = 2, + WGET_EXIT_IO_FAIL = 3, + WGET_EXIT_NETWORK_FAIL = 4, + WGET_EXIT_SSL_AUTH_FAIL = 5, + WGET_EXIT_SERVER_AUTH_FAIL = 6, + WGET_EXIT_PROTOCOL_ERROR = 7, + WGET_EXIT_SERVER_ERROR = 8, + + WGET_EXIT_UNKNOWN + }; + +void inform_exit_status (uerr_t err); + +int get_exit_status (void); + + +#endif /* WGET_EXITS_H */ diff --git a/src/ftp-basic.c b/src/ftp-basic.c new file mode 100644 index 0000000..197cd83 --- /dev/null +++ b/src/ftp-basic.c @@ -0,0 +1,1342 @@ +/* Basic FTP routines. + Copyright (C) 1996-2011, 2014-2015, 2018-2020 Free Software + Foundation, Inc. + +This file is part of GNU Wget. + +GNU Wget is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + +GNU Wget 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 Wget. If not, see . + +Additional permission under GNU GPL version 3 section 7 + +If you modify this program, or any covered work, by linking or +combining it with the OpenSSL project's OpenSSL library (or a +modified version of that library), containing parts covered by the +terms of the OpenSSL or SSLeay licenses, the Free Software Foundation +grants you additional permission to convey the resulting work. +Corresponding Source for a non-source form of such a combination +shall include the source code for the parts of OpenSSL used as well +as that of the covered work. */ + +#include "wget.h" + +#include +#include +#include +#include + +#include +#include +#include "utils.h" +#include "connect.h" +#include "host.h" +#include "ftp.h" +#include "retr.h" +#include "c-strcase.h" + + +/* Get the response of FTP server and allocate enough room to handle + it. and characters are stripped from the line, and the + line is 0-terminated. All the response lines but the last one are + skipped. The last line is determined as described in RFC959. + + If the line is successfully read, FTPOK is returned, and *ret_line + is assigned a freshly allocated line. Otherwise, FTPRERR is + returned, and the value of *ret_line should be ignored. */ + +uerr_t +ftp_response (int fd, char **ret_line) +{ + for (;;) + { + char *p; + char *line = fd_read_line (fd); + if (!line) + return FTPRERR; + + /* Strip trailing CRLF before printing the line, so that + quoting doesn't include bogus \012 and \015. */ + if ((p = strpbrk(line , "\r\n"))) + *p = 0; + + if (opt.server_response) + logprintf (LOG_NOTQUIET, "%s\n", + quotearg_style (escape_quoting_style, line)); + else + DEBUGP (("%s\n", quotearg_style (escape_quoting_style, line))); + + /* The last line of output is the one that begins with "ddd ". */ + if (c_isdigit (line[0]) && c_isdigit (line[1]) && c_isdigit (line[2]) + && line[3] == ' ') + { + *ret_line = line; + return FTPOK; + } + xfree (line); + } +} + +/* Returns the malloc-ed FTP request, ending with , printing + it if printing is required. If VALUE is NULL, just use + command. */ +static char * +ftp_request (const char *command, const char *value) +{ + char *res; + + if (value) + { + char *defanged = NULL, buf[256]; + + /* Check for newlines in VALUE (possibly injected by the %0A URL + escape) making the callers inadvertently send multiple FTP + commands at once. Without this check an attacker could + intentionally redirect to ftp://server/fakedir%0Acommand.../ + and execute arbitrary FTP command on a remote FTP server. */ + if (strpbrk (value, "\r\n")) + { + /* Copy VALUE to the stack and modify CR/LF to space. */ + char *p; + size_t len = strlen(value); + + if (len < sizeof (buf)) + defanged = buf; + else + defanged = xmalloc (len + 1); + + memcpy (defanged, value, len + 1); + + for (p = defanged; *p; p++) + if (*p == '\r' || *p == '\n') + *p = ' '; + + DEBUGP (("\nDetected newlines in %s \"%s\"; changing to %s \"%s\"\n", + command, quotearg_style (escape_quoting_style, value), + command, quotearg_style (escape_quoting_style, defanged))); + + /* Make VALUE point to the defanged copy of the string. */ + value = defanged; + } + res = concat_strings (command, " ", value, "\r\n", (char *) 0); + + if (defanged != buf) + xfree (defanged); + } + else + res = concat_strings (command, "\r\n", (char *) 0); + if (opt.server_response) + { + /* Hack: don't print out password. */ + if (strncmp (res, "PASS", 4) != 0) + logprintf (LOG_ALWAYS, "--> %s\n", res); + else + logputs (LOG_ALWAYS, "--> PASS Turtle Power!\n\n"); + } + else + DEBUGP (("\n--> %s\n", res)); + return res; +} + +uerr_t +ftp_greeting (int csock) +{ + uerr_t err = FTPOK; + char *response = NULL; + + err = ftp_response (csock, &response); + if (err != FTPOK) + goto bail; + if (*response != '2') + err = FTPSRVERR; + +bail: + if (response) + xfree (response); + return err; +} +/* Sends the USER and PASS commands to the server, to control + connection socket csock. */ +uerr_t +ftp_login (int csock, const char *acc, const char *pass) +{ + uerr_t err; + char *request, *respline; + int nwritten; + + /* Send USER username. */ + request = ftp_request ("USER", acc); + nwritten = fd_write (csock, request, strlen (request), -1); + if (nwritten < 0) + { + xfree (request); + return WRITEFAILED; + } + xfree (request); + /* Get appropriate response. */ + err = ftp_response (csock, &respline); + if (err != FTPOK) + return err; + /* An unprobable possibility of logging without a password. */ + if (*respline == '2') + { + xfree (respline); + return FTPOK; + } + /* Else, only response 3 is appropriate. */ + if (*respline != '3') + { + xfree (respline); + return FTPLOGREFUSED; + } +#ifdef ENABLE_OPIE + { + static const char *skey_head[] = { + "331 s/key ", + "331 opiekey " + }; + size_t i; + const char *seed = NULL; + + for (i = 0; i < countof (skey_head); i++) + { + int l = strlen (skey_head[i]); + if (0 == c_strncasecmp (skey_head[i], respline, l)) + { + seed = respline + l; + break; + } + } + if (seed) + { + int skey_sequence = 0; + + /* Extract the sequence from SEED. */ + for (; c_isdigit (*seed); seed++) + skey_sequence = 10 * skey_sequence + *seed - '0'; + if (*seed == ' ') + ++seed; + else + { + xfree (respline); + return FTPLOGREFUSED; + } + /* Replace the password with the SKEY response to the + challenge. */ + pass = skey_response (skey_sequence, seed, pass); + } + } +#endif /* ENABLE_OPIE */ + xfree (respline); + /* Send PASS password. */ + request = ftp_request ("PASS", pass); + nwritten = fd_write (csock, request, strlen (request), -1); + if (nwritten < 0) + { + xfree (request); + return WRITEFAILED; + } + xfree (request); + /* Get appropriate response. */ + err = ftp_response (csock, &respline); + if (err != FTPOK) + return err; + if (*respline != '2') + { + xfree (respline); + return FTPLOGINC; + } + xfree (respline); + /* All OK. */ + return FTPOK; +} + +static void +ip_address_to_port_repr (const ip_address *addr, int port, char *buf, + size_t buflen) +{ + unsigned char *ptr; + + assert (addr->family == AF_INET); + /* buf must contain the argument of PORT (of the form a,b,c,d,e,f). */ + assert (buflen >= 6 * 4); + + ptr = IP_INADDR_DATA (addr); + snprintf (buf, buflen, "%d,%d,%d,%d,%d,%d", ptr[0], ptr[1], + ptr[2], ptr[3], (port & 0xff00) >> 8, port & 0xff); + buf[buflen - 1] = '\0'; +} + +/* Bind a port and send the appropriate PORT command to the FTP + server. Use acceptport after RETR, to get the socket of data + connection. */ +uerr_t +ftp_port (int csock, int *local_sock) +{ + uerr_t err; + char *request, *respline; + ip_address addr; + int nwritten; + int port; + /* Must contain the argument of PORT (of the form a,b,c,d,e,f). */ + char bytes[6 * 4 + 1]; + + /* Get the address of this side of the connection. */ + if (!socket_ip_address (csock, &addr, ENDPOINT_LOCAL)) + return FTPSYSERR; + + assert (addr.family == AF_INET); + + /* Setting port to 0 lets the system choose a free port. */ + port = 0; + + /* Bind the port. */ + *local_sock = bind_local (&addr, &port); + if (*local_sock < 0) + return FTPSYSERR; + + /* Construct the argument of PORT (of the form a,b,c,d,e,f). */ + ip_address_to_port_repr (&addr, port, bytes, sizeof (bytes)); + + /* Send PORT request. */ + request = ftp_request ("PORT", bytes); + nwritten = fd_write (csock, request, strlen (request), -1); + if (nwritten < 0) + { + xfree (request); + fd_close (*local_sock); + return WRITEFAILED; + } + xfree (request); + + /* Get appropriate response. */ + err = ftp_response (csock, &respline); + if (err != FTPOK) + { + fd_close (*local_sock); + return err; + } + if (*respline != '2') + { + xfree (respline); + fd_close (*local_sock); + return FTPPORTERR; + } + xfree (respline); + return FTPOK; +} + +#ifdef ENABLE_IPV6 +static void +ip_address_to_lprt_repr (const ip_address *addr, int port, char *buf, + size_t buflen) +{ + unsigned char *ptr = IP_INADDR_DATA (addr); + + /* buf must contain the argument of LPRT (of the form af,n,h1,h2,...,hn,p1,p2). */ + assert (buflen >= 21 * 4); + + /* Construct the argument of LPRT (of the form af,n,h1,h2,...,hn,p1,p2). */ + switch (addr->family) + { + case AF_INET: + snprintf (buf, buflen, "%d,%d,%d,%d,%d,%d,%d,%d,%d", 4, 4, + ptr[0], ptr[1], ptr[2], ptr[3], 2, + (port & 0xff00) >> 8, port & 0xff); + break; + case AF_INET6: + snprintf (buf, buflen, + "%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d", + 6, 16, + ptr[0], ptr[1], ptr[2], ptr[3], ptr[4], ptr[5], ptr[6], ptr[7], + ptr[8], ptr[9], ptr[10], ptr[11], ptr[12], ptr[13], ptr[14], ptr[15], + 2, (port & 0xff00) >> 8, port & 0xff); + break; + default: + abort (); + } +} + +/* Bind a port and send the appropriate PORT command to the FTP + server. Use acceptport after RETR, to get the socket of data + connection. */ +uerr_t +ftp_lprt (int csock, int *local_sock) +{ + uerr_t err; + char *request, *respline; + ip_address addr; + int nwritten; + int port; + /* Must contain the argument of LPRT (of the form af,n,h1,h2,...,hn,p1,p2). */ + char bytes[21 * 4 + 1]; + + /* Get the address of this side of the connection. */ + if (!socket_ip_address (csock, &addr, ENDPOINT_LOCAL)) + return FTPSYSERR; + + assert (addr.family == AF_INET || addr.family == AF_INET6); + + /* Setting port to 0 lets the system choose a free port. */ + port = 0; + + /* Bind the port. */ + *local_sock = bind_local (&addr, &port); + if (*local_sock < 0) + return FTPSYSERR; + + /* Construct the argument of LPRT (of the form af,n,h1,h2,...,hn,p1,p2). */ + ip_address_to_lprt_repr (&addr, port, bytes, sizeof (bytes)); + + /* Send PORT request. */ + request = ftp_request ("LPRT", bytes); + nwritten = fd_write (csock, request, strlen (request), -1); + if (nwritten < 0) + { + xfree (request); + fd_close (*local_sock); + return WRITEFAILED; + } + xfree (request); + /* Get appropriate response. */ + err = ftp_response (csock, &respline); + if (err != FTPOK) + { + fd_close (*local_sock); + return err; + } + if (*respline != '2') + { + xfree (respline); + fd_close (*local_sock); + return FTPPORTERR; + } + xfree (respline); + return FTPOK; +} + +static void +ip_address_to_eprt_repr (const ip_address *addr, int port, char *buf, + size_t buflen) +{ + int afnum; + + /* buf must contain the argument of EPRT (of the form |af|addr|port|). + * 4 chars for the | separators, INET6_ADDRSTRLEN chars for addr + * 1 char for af (1-2) and 5 chars for port (0-65535) */ + assert (buflen >= 4 + INET6_ADDRSTRLEN + 1 + 5); + + /* Construct the argument of EPRT (of the form |af|addr|port|). */ + afnum = (addr->family == AF_INET ? 1 : 2); + snprintf (buf, buflen, "|%d|%s|%d|", afnum, print_address (addr), port); + buf[buflen - 1] = '\0'; +} + +/* Bind a port and send the appropriate PORT command to the FTP + server. Use acceptport after RETR, to get the socket of data + connection. */ +uerr_t +ftp_eprt (int csock, int *local_sock) +{ + uerr_t err; + char *request, *respline; + ip_address addr; + int nwritten; + int port; + /* Must contain the argument of EPRT (of the form |af|addr|port|). + * 4 chars for the | separators, INET6_ADDRSTRLEN chars for addr + * 1 char for af (1-2) and 5 chars for port (0-65535) */ + char bytes[4 + INET6_ADDRSTRLEN + 1 + 5 + 1]; + + /* Get the address of this side of the connection. */ + if (!socket_ip_address (csock, &addr, ENDPOINT_LOCAL)) + return FTPSYSERR; + + /* Setting port to 0 lets the system choose a free port. */ + port = 0; + + /* Bind the port. */ + *local_sock = bind_local (&addr, &port); + if (*local_sock < 0) + return FTPSYSERR; + + /* Construct the argument of EPRT (of the form |af|addr|port|). */ + ip_address_to_eprt_repr (&addr, port, bytes, sizeof (bytes)); + + /* Send PORT request. */ + request = ftp_request ("EPRT", bytes); + nwritten = fd_write (csock, request, strlen (request), -1); + if (nwritten < 0) + { + xfree (request); + fd_close (*local_sock); + return WRITEFAILED; + } + xfree (request); + /* Get appropriate response. */ + err = ftp_response (csock, &respline); + if (err != FTPOK) + { + fd_close (*local_sock); + return err; + } + if (*respline != '2') + { + xfree (respline); + fd_close (*local_sock); + return FTPPORTERR; + } + xfree (respline); + return FTPOK; +} +#endif + +#ifdef HAVE_SSL +/* + * The following three functions defined into this #ifdef block + * wrap the extended FTP commands defined in RFC 2228 (FTP Security Extensions). + * Currently, only FTPS is supported, so these functions are only compiled when SSL + * support is available, because there's no point in using FTPS when there's no SSL. + * Shall someone add new secure FTP protocols in the future, feel free to remove this + * #ifdef, or add new constants to it. + */ + +/* + * Sends an AUTH command as defined by RFC 2228, + * deriving its argument from the scheme. For example, if the provided scheme + * is SCHEME_FTPS, the command sent will be "AUTH TLS". Currently, this is the only + * scheme supported, so this function will return FTPNOAUTH when supplied a different + * one. It will also return FTPNOAUTH if the target server does not support FTPS. + */ +uerr_t +ftp_auth (int csock, enum url_scheme scheme) +{ + uerr_t err = 0; + int written = 0; + char *request = NULL, *response = NULL; + + if (scheme == SCHEME_FTPS) + { + request = ftp_request ("AUTH", "TLS"); + written = fd_write (csock, request, strlen (request), -1); + if (written < 0) + { + err = WRITEFAILED; + goto bail; + } + err = ftp_response (csock, &response); + if (err != FTPOK) + goto bail; + if (*response != '2') + err = FTPNOAUTH; + } + else + err = FTPNOAUTH; + +bail: + xfree (request); + xfree (response); + + return err; +} + +uerr_t +ftp_pbsz (int csock, int pbsz) +{ + uerr_t err = 0; + int written = 0; + char spbsz[5]; + char *request = NULL, *response = NULL; + + snprintf (spbsz, 5, "%d", pbsz); + request = ftp_request ("PBSZ", spbsz); + written = fd_write (csock, request, strlen (request), -1); + if (written < 0) + { + err = WRITEFAILED; + goto bail; + } + + err = ftp_response (csock, &response); + if (err != FTPOK) + goto bail; + if (*response != '2') + err = FTPNOPBSZ; + +bail: + xfree (request); + xfree (response); + + return err; +} + +uerr_t +ftp_prot (int csock, enum prot_level prot) +{ + uerr_t err = 0; + int written = 0; + char *request = NULL, *response = NULL; + /* value must be a single character value */ + char value[2]; + + value[0] = prot; + value[1] = '\0'; + + request = ftp_request ("PROT", value); + written = fd_write (csock, request, strlen (request), -1); + if (written < 0) + { + err = WRITEFAILED; + goto bail; + } + + err = ftp_response (csock, &response); + if (err != FTPOK) + goto bail; + if (*response != '2') + err = FTPNOPROT; + +bail: + xfree (request); + xfree (response); + + return err; +} +#endif /* HAVE_SSL */ + +/* Similar to ftp_port, but uses `PASV' to initiate the passive FTP + transfer. Reads the response from server and parses it. Reads the + host and port addresses and returns them. */ +uerr_t +ftp_pasv (int csock, ip_address *addr, int *port) +{ + char *request, *respline, *s; + int nwritten, i; + uerr_t err; + unsigned char tmp[6]; + + assert (addr != NULL); + assert (port != NULL); + + xzero (*addr); + + /* Form the request. */ + request = ftp_request ("PASV", NULL); + /* And send it. */ + nwritten = fd_write (csock, request, strlen (request), -1); + if (nwritten < 0) + { + xfree (request); + return WRITEFAILED; + } + xfree (request); + /* Get the server response. */ + err = ftp_response (csock, &respline); + if (err != FTPOK) + return err; + if (*respline != '2') + { + xfree (respline); + return FTPNOPASV; + } + /* Parse the request. */ + s = respline; + for (s += 4; *s && !c_isdigit (*s); s++) + ; + if (!*s) + { + xfree (respline); + return FTPINVPASV; + } + for (i = 0; i < 6; i++) + { + tmp[i] = 0; + for (; c_isdigit (*s); s++) + tmp[i] = (*s - '0') + 10 * tmp[i]; + if (*s == ',') + s++; + else if (i < 5) + { + /* When on the last number, anything can be a terminator. */ + xfree (respline); + return FTPINVPASV; + } + } + xfree (respline); + + addr->family = AF_INET; + memcpy (IP_INADDR_DATA (addr), tmp, 4); + *port = ((tmp[4] << 8) & 0xff00) + tmp[5]; + + return FTPOK; +} + +#ifdef ENABLE_IPV6 +/* Similar to ftp_lprt, but uses `LPSV' to initiate the passive FTP + transfer. Reads the response from server and parses it. Reads the + host and port addresses and returns them. */ +uerr_t +ftp_lpsv (int csock, ip_address *addr, int *port) +{ + char *request, *respline, *s; + int nwritten, i, af, addrlen, portlen; + uerr_t err; + unsigned char tmp[16]; + unsigned char tmpprt[2]; + + assert (addr != NULL); + assert (port != NULL); + + xzero (*addr); + + /* Form the request. */ + request = ftp_request ("LPSV", NULL); + + /* And send it. */ + nwritten = fd_write (csock, request, strlen (request), -1); + if (nwritten < 0) + { + xfree (request); + return WRITEFAILED; + } + xfree (request); + + /* Get the server response. */ + err = ftp_response (csock, &respline); + if (err != FTPOK) + return err; + if (*respline != '2') + { + xfree (respline); + return FTPNOPASV; + } + + /* Parse the response. */ + s = respline; + for (s += 4; *s && !c_isdigit (*s); s++) + ; + if (!*s) + { + xfree (respline); + return FTPINVPASV; + } + + /* First, get the address family */ + af = 0; + for (; c_isdigit (*s); s++) + af = (*s - '0') + 10 * af; + + if (af != 4 && af != 6) + { + xfree (respline); + return FTPINVPASV; + } + + if (!*s || *s++ != ',') + { + xfree (respline); + return FTPINVPASV; + } + + /* Then, get the address length */ + addrlen = 0; + for (; c_isdigit (*s); s++) + addrlen = (*s - '0') + 10 * addrlen; + + if (!*s || *s++ != ',') + { + xfree (respline); + return FTPINVPASV; + } + + if (addrlen > 16) + { + xfree (respline); + return FTPINVPASV; + } + + if ((af == 4 && addrlen != 4) + || (af == 6 && addrlen != 16)) + { + xfree (respline); + return FTPINVPASV; + } + + /* Now, we get the actual address */ + for (i = 0; i < addrlen; i++) + { + tmp[i] = 0; + for (; c_isdigit (*s); s++) + tmp[i] = (*s - '0') + 10 * tmp[i]; + if (*s == ',') + s++; + else + { + xfree (respline); + return FTPINVPASV; + } + } + + /* Now, get the port length */ + portlen = 0; + for (; c_isdigit (*s); s++) + portlen = (*s - '0') + 10 * portlen; + + if (!*s || *s++ != ',') + { + xfree (respline); + return FTPINVPASV; + } + + if (portlen > 2) + { + xfree (respline); + return FTPINVPASV; + } + + /* Finally, we get the port number */ + tmpprt[0] = 0; + for (; c_isdigit (*s); s++) + tmpprt[0] = (*s - '0') + 10 * tmpprt[0]; + + if (!*s || *s++ != ',') + { + xfree (respline); + return FTPINVPASV; + } + + tmpprt[1] = 0; + for (; c_isdigit (*s); s++) + tmpprt[1] = (*s - '0') + 10 * tmpprt[1]; + + assert (s != NULL); + + if (af == 4) + { + addr->family = AF_INET; + memcpy (IP_INADDR_DATA (addr), tmp, 4); + *port = ((tmpprt[0] << 8) & 0xff00) + tmpprt[1]; + DEBUGP (("lpsv addr is: %s\n", print_address(addr))); + DEBUGP (("tmpprt[0] is: %d\n", tmpprt[0])); + DEBUGP (("tmpprt[1] is: %d\n", tmpprt[1])); + DEBUGP (("*port is: %d\n", *port)); + } + else + { + assert (af == 6); + addr->family = AF_INET6; + memcpy (IP_INADDR_DATA (addr), tmp, 16); + *port = ((tmpprt[0] << 8) & 0xff00) + tmpprt[1]; + DEBUGP (("lpsv addr is: %s\n", print_address(addr))); + DEBUGP (("tmpprt[0] is: %d\n", tmpprt[0])); + DEBUGP (("tmpprt[1] is: %d\n", tmpprt[1])); + DEBUGP (("*port is: %d\n", *port)); + } + + xfree (respline); + return FTPOK; +} + +/* Similar to ftp_eprt, but uses `EPSV' to initiate the passive FTP + transfer. Reads the response from server and parses it. Reads the + host and port addresses and returns them. */ +uerr_t +ftp_epsv (int csock, ip_address *ip, int *port) +{ + char *request, *respline, *start, delim, *s; + int nwritten, i; + uerr_t err; + int tport; + + assert (ip != NULL); + assert (port != NULL); + + /* IP already contains the IP address of the control connection's + peer, so we don't need to call socket_ip_address here. */ + + /* Form the request. */ + /* EPSV 1 means that we ask for IPv4 and EPSV 2 means that we ask for IPv6. */ + request = ftp_request ("EPSV", (ip->family == AF_INET ? "1" : "2")); + + /* And send it. */ + nwritten = fd_write (csock, request, strlen (request), -1); + if (nwritten < 0) + { + xfree (request); + return WRITEFAILED; + } + xfree (request); + + /* Get the server response. */ + err = ftp_response (csock, &respline); + if (err != FTPOK) + return err; + if (*respline != '2') + { + xfree (respline); + return FTPNOPASV; + } + + assert (respline != NULL); + + DEBUGP(("respline is %s\n", respline)); + + /* Skip the useless stuff and get what's inside the parentheses */ + start = strchr (respline, '('); + if (start == NULL) + { + xfree (respline); + return FTPINVPASV; + } + + /* Skip the first two void fields */ + s = start + 1; + delim = *s++; + if (delim < 33 || delim > 126) + { + xfree (respline); + return FTPINVPASV; + } + + for (i = 0; i < 2; i++) + { + if (*s++ != delim) + { + xfree (respline); + return FTPINVPASV; + } + } + + /* Finally, get the port number */ + for (tport = 0, i = 0; i < 5 && c_isdigit (*s); i++, s++) + tport = (*s - '0') + 10 * tport; + + /* Make sure that the response terminates correctly */ + if (*s++ != delim) + { + xfree (respline); + return FTPINVPASV; + } + + if (*s != ')') + { + xfree (respline); + return FTPINVPASV; + } + + *port = tport; + + xfree (respline); + return FTPOK; +} +#endif + +/* Sends the TYPE request to the server. */ +uerr_t +ftp_type (int csock, int type) +{ + char *request, *respline; + int nwritten; + uerr_t err; + char stype[2]; + + /* Construct argument. */ + stype[0] = type; + stype[1] = 0; + /* Send TYPE request. */ + request = ftp_request ("TYPE", stype); + nwritten = fd_write (csock, request, strlen (request), -1); + if (nwritten < 0) + { + xfree (request); + return WRITEFAILED; + } + xfree (request); + /* Get appropriate response. */ + err = ftp_response (csock, &respline); + if (err != FTPOK) + return err; + if (*respline != '2') + { + xfree (respline); + return FTPUNKNOWNTYPE; + } + xfree (respline); + /* All OK. */ + return FTPOK; +} + +/* Changes the working directory by issuing a CWD command to the + server. */ +uerr_t +ftp_cwd (int csock, const char *dir) +{ + char *request, *respline; + int nwritten; + uerr_t err; + + /* Send CWD request. */ + request = ftp_request ("CWD", dir); + nwritten = fd_write (csock, request, strlen (request), -1); + if (nwritten < 0) + { + xfree (request); + return WRITEFAILED; + } + xfree (request); + /* Get appropriate response. */ + err = ftp_response (csock, &respline); + if (err != FTPOK) + return err; + if (*respline == '5') + { + xfree (respline); + return FTPNSFOD; + } + if (*respline != '2') + { + xfree (respline); + return FTPRERR; + } + xfree (respline); + /* All OK. */ + return FTPOK; +} + +/* Sends REST command to the FTP server. */ +uerr_t +ftp_rest (int csock, wgint offset) +{ + char *request, *respline; + int nwritten; + uerr_t err; + + request = ftp_request ("REST", number_to_static_string (offset)); + nwritten = fd_write (csock, request, strlen (request), -1); + if (nwritten < 0) + { + xfree (request); + return WRITEFAILED; + } + xfree (request); + /* Get appropriate response. */ + err = ftp_response (csock, &respline); + if (err != FTPOK) + return err; + if (*respline != '3') + { + xfree (respline); + return FTPRESTFAIL; + } + xfree (respline); + /* All OK. */ + return FTPOK; +} + +/* Sends RETR command to the FTP server. */ +uerr_t +ftp_retr (int csock, const char *file) +{ + char *request, *respline; + int nwritten; + uerr_t err; + + /* Send RETR request. */ + request = ftp_request ("RETR", file); + nwritten = fd_write (csock, request, strlen (request), -1); + if (nwritten < 0) + { + xfree (request); + return WRITEFAILED; + } + xfree (request); + /* Get appropriate response. */ + err = ftp_response (csock, &respline); + if (err != FTPOK) + return err; + if (*respline == '5') + { + xfree (respline); + return FTPNSFOD; + } + if (*respline != '1') + { + xfree (respline); + return FTPRERR; + } + xfree (respline); + /* All OK. */ + return FTPOK; +} + +/* Sends the LIST command to the server. If FILE is NULL, send just + `LIST' (no space). */ +uerr_t +ftp_list (int csock, const char *file, bool avoid_list_a, bool avoid_list, + bool *list_a_used) +{ + char *request, *respline; + int nwritten; + uerr_t err; + bool ok = false; + size_t i = 0; + + /* 2013-10-12 Andrea Urbani (matfanjol) + For more information about LIST and "LIST -a" please look at ftp.c, + function getftp, text "__LIST_A_EXPLANATION__". + + If somebody changes the following commands, please, checks also the + later "i" variable. */ + static const char *list_commands[] = { + "LIST -a", + "LIST" + }; + + *list_a_used = false; + + if (avoid_list_a) + { + i = countof (list_commands)- 1; + DEBUGP (("(skipping \"LIST -a\")")); + } + + + do { + /* Send request. */ + request = ftp_request (list_commands[i], file); + nwritten = fd_write (csock, request, strlen (request), -1); + if (nwritten < 0) + { + xfree (request); + return WRITEFAILED; + } + xfree (request); + /* Get appropriate response. */ + err = ftp_response (csock, &respline); + if (err == FTPOK) + { + if (*respline == '5') + { + err = FTPNSFOD; + } + else if (*respline == '1') + { + err = FTPOK; + ok = true; + /* Which list command was used? */ + *list_a_used = (i == 0); + } + else + { + err = FTPRERR; + } + xfree (respline); + } + ++i; + if ((avoid_list) && (i == 1)) + { + /* I skip LIST */ + ++i; + DEBUGP (("(skipping \"LIST\")")); + } + } while (i < countof (list_commands) && !ok); + + return err; +} + +/* Sends the SYST command to the server. */ +uerr_t +ftp_syst (int csock, enum stype *server_type, enum ustype *unix_type) +{ + char *request, *respline; + int nwritten; + uerr_t err; + char *ftp_last_respline; + + /* Send SYST request. */ + request = ftp_request ("SYST", NULL); + nwritten = fd_write (csock, request, strlen (request), -1); + if (nwritten < 0) + { + xfree (request); + return WRITEFAILED; + } + xfree (request); + + /* Get appropriate response. */ + err = ftp_response (csock, &respline); + if (err != FTPOK) + return err; + if (*respline == '5') + { + xfree (respline); + return FTPSRVERR; + } + + ftp_last_respline = strdup (respline); + + /* Skip the number (215, but 200 (!!!) in case of VMS) */ + strtok (respline, " "); + + /* Which system type has been reported (we are interested just in the + first word of the server response)? */ + request = strtok (NULL, " "); + + *unix_type = UST_OTHER; + + if (request == NULL) + *server_type = ST_OTHER; + else if (!c_strcasecmp (request, "VMS")) + *server_type = ST_VMS; + else if (!c_strcasecmp (request, "UNIX")) + { + *server_type = ST_UNIX; + /* 2013-10-17 Andrea Urbani (matfanjol) + I check more in depth the system type */ + if (!c_strncasecmp (ftp_last_respline, "215 UNIX Type: L8", 17)) + *unix_type = UST_TYPE_L8; + else if (!c_strncasecmp (ftp_last_respline, + "215 UNIX MultiNet Unix Emulation V5.3(93)", 41)) + *unix_type = UST_MULTINET; + } + else if (!c_strcasecmp (request, "WINDOWS_NT") + || !c_strcasecmp (request, "WINDOWS2000")) + *server_type = ST_WINNT; + else if (!c_strcasecmp (request, "MACOS")) + *server_type = ST_MACOS; + else if (!c_strcasecmp (request, "OS/400")) + *server_type = ST_OS400; + else + *server_type = ST_OTHER; + + xfree (ftp_last_respline); + xfree (respline); + /* All OK. */ + return FTPOK; +} + +/* Sends the PWD command to the server. */ +uerr_t +ftp_pwd (int csock, char **pwd) +{ + char *request, *respline; + int nwritten; + uerr_t err; + + /* Send PWD request. */ + request = ftp_request ("PWD", NULL); + nwritten = fd_write (csock, request, strlen (request), -1); + if (nwritten < 0) + { + xfree (request); + return WRITEFAILED; + } + xfree (request); + /* Get appropriate response. */ + err = ftp_response (csock, &respline); + if (err != FTPOK) + return err; + if (*respline == '5') + { + err: + xfree (respline); + return FTPSRVERR; + } + + /* Skip the number (257), leading citation mark, trailing citation mark + and everything following it. */ + strtok (respline, "\""); + request = strtok (NULL, "\""); + if (!request) + /* Treat the malformed response as an error, which the caller has + to handle gracefully anyway. */ + goto err; + + /* Has the `pwd' been already allocated? Free! */ + xfree (*pwd); + + *pwd = xstrdup (request); + + xfree (respline); + /* All OK. */ + return FTPOK; +} + +/* Sends the SIZE command to the server, and returns the value in 'size'. + * If an error occurs, size is set to zero. */ +uerr_t +ftp_size (int csock, const char *file, wgint *size) +{ + char *request, *respline; + int nwritten; + uerr_t err; + + /* Send PWD request. */ + request = ftp_request ("SIZE", file); + nwritten = fd_write (csock, request, strlen (request), -1); + if (nwritten < 0) + { + xfree (request); + *size = 0; + return WRITEFAILED; + } + xfree (request); + /* Get appropriate response. */ + err = ftp_response (csock, &respline); + if (err != FTPOK) + { + *size = 0; + return err; + } + if (*respline == '5') + { + /* + * Probably means SIZE isn't supported on this server. + * Error is nonfatal since SIZE isn't in RFC 959 + */ + xfree (respline); + *size = 0; + return FTPOK; + } + + errno = 0; + *size = str_to_wgint (respline + 4, NULL, 10); + if (errno) + { + /* + * Couldn't parse the response for some reason. On the (few) + * tests I've done, the response is 213 with nothing else - + * maybe something a bit more resilient is necessary. It's not a + * fatal error, however. + */ + xfree (respline); + *size = 0; + return FTPOK; + } + + xfree (respline); + /* All OK. */ + return FTPOK; +} + +/* If URL's params are of the form "type=X", return character X. + Otherwise, return 'I' (the default type). */ +char +ftp_process_type (const char *params) +{ + if (params + && 0 == strncasecmp (params, "type=", 5) + && params[5] != '\0') + return c_toupper (params[5]); + else + return 'I'; +} diff --git a/src/ftp-ls.c b/src/ftp-ls.c new file mode 100644 index 0000000..bb25754 --- /dev/null +++ b/src/ftp-ls.c @@ -0,0 +1,1175 @@ +/* Parsing FTP `ls' output. + Copyright (C) 1996-2011, 2015, 2018-2020 Free Software Foundation, + Inc. + +This file is part of GNU Wget. + +GNU Wget is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 3 of the License, or +(at your option) any later version. + +GNU Wget 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 Wget. If not, see . + +Additional permission under GNU GPL version 3 section 7 + +If you modify this program, or any covered work, by linking or +combining it with the OpenSSL project's OpenSSL library (or a +modified version of that library), containing parts covered by the +terms of the OpenSSL or SSLeay licenses, the Free Software Foundation +grants you additional permission to convey the resulting work. +Corresponding Source for a non-source form of such a combination +shall include the source code for the parts of OpenSSL used as well +as that of the covered work. */ + +#include "wget.h" + +#include +#include +#include +#include +#include +#include +#include "utils.h" +#include "ftp.h" +#include "url.h" +#include "convert.h" /* for html_quote_string prototype */ +#include "retr.h" /* for output_stream */ +#include "c-strcase.h" + +/* Converts symbolic permissions to number-style ones, e.g. string + rwxr-xr-x to 755. For now, it knows nothing of + setuid/setgid/sticky. ACLs are ignored. */ +static int +symperms (const char *s) +{ + int perms = 0, i; + + if (strlen (s) < 9) + return 0; + for (i = 0; i < 3; i++, s += 3) + { + perms <<= 3; + perms += (((s[0] == 'r') << 2) + ((s[1] == 'w') << 1) + + (s[2] == 'x' || s[2] == 's')); + } + return perms; +} + + +/* Cleans a line of text so that it can be consistently parsed. Destroys + and in case that they occur at the end of the line and + replaces all character with . Returns the length of the + modified line. */ +static int +clean_line (char *line, int len) +{ + if (len <= 0) return 0; + + while (len > 0 && (line[len - 1] == '\n' || line[len - 1] == '\r')) + line[--len] = '\0'; + + if (!len) return 0; + + for ( ; *line ; line++ ) if (*line == '\t') *line = ' '; + + return len; +} + +/* Convert the Un*x-ish style directory listing stored in FILE to a + linked list of fileinfo (system-independent) entries. The contents + of FILE are considered to be produced by the standard Unix `ls -la' + output (whatever that might be). BSD (no group) and SYSV (with + group) listings are handled. + + The time stamps are stored in a separate variable, time_t + compatible (I hope). The timezones are ignored. */ +static struct fileinfo * +ftp_parse_unix_ls (FILE *fp, int ignore_perms) +{ + static const char *months[] = { + "Jan", "Feb", "Mar", "Apr", "May", "Jun", + "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" + }; + int next, len, i, error, ignore; + int year, month, day; /* for time analysis */ + int hour, min, sec, ptype; + struct tm timestruct, *tnow; + time_t timenow; + size_t bufsize = 0; + + char *line = NULL, *tok, *ptok; /* tokenizer */ + struct fileinfo *dir, *l, cur; /* list creation */ + + dir = l = NULL; + + /* Line loop to end of file: */ + while ((len = getline (&line, &bufsize, fp)) > 0) + { + len = clean_line (line, len); + /* Skip if total... */ + if (!c_strncasecmp (line, "total", 5)) + continue; + /* Get the first token (permissions). */ + tok = strtok (line, " "); + if (!tok) + continue; + + cur.name = NULL; + cur.linkto = NULL; + + /* Decide whether we deal with a file or a directory. */ + switch (*tok) + { + case '-': + cur.type = FT_PLAINFILE; + DEBUGP (("PLAINFILE; ")); + break; + case 'd': + cur.type = FT_DIRECTORY; + DEBUGP (("DIRECTORY; ")); + break; + case 'l': + cur.type = FT_SYMLINK; + DEBUGP (("SYMLINK; ")); + break; + default: + cur.type = FT_UNKNOWN; + DEBUGP (("UNKNOWN; ")); + break; + } + + if (ignore_perms) + { + switch (cur.type) + { + case FT_PLAINFILE: + cur.perms = 0644; + break; + case FT_DIRECTORY: + cur.perms = 0755; + break; + default: + /*cur.perms = 1023;*/ /* #### What is this? --hniksic */ + cur.perms = 0644; + } + DEBUGP (("implicit perms %0o; ", (unsigned) cur.perms)); + } + else + { + cur.perms = symperms (tok + 1); + DEBUGP (("perms %0o; ", (unsigned) cur.perms)); + } + + error = ignore = 0; /* Erroneous and ignoring entries are + treated equally for now. */ + year = hour = min = sec = 0; /* Silence the compiler. */ + month = day = 0; + ptype = TT_DAY; + next = -1; + /* While there are tokens on the line, parse them. Next is the + number of tokens left until the filename. + + Use the month-name token as the "anchor" (the place where the + position wrt the file name is "known"). When a month name is + encountered, `next' is set to 5. Also, the preceding + characters are parsed to get the file size. + + This tactic is quite dubious when it comes to + internationalization issues (non-English month names), but it + works for now. */ + tok = line; + while (ptok = tok, + (tok = strtok (NULL, " ")) != NULL) + { + --next; + if (next < 0) /* a month name was not encountered */ + { + for (i = 0; i < 12; i++) + if (!c_strcasecmp (tok, months[i])) + break; + /* If we got a month, it means the token before it is the + size, and the filename is three tokens away. */ + if (i != 12) + { + wgint size; + + /* Parse the previous token with str_to_wgint. */ + if (ptok == line) + { + /* Something has gone wrong during parsing. */ + error = 1; + break; + } + errno = 0; + size = str_to_wgint (ptok, NULL, 10); + if (size == WGINT_MAX && errno == ERANGE) + /* Out of range -- ignore the size. #### Should + we refuse to start the download. */ + cur.size = 0; + else + cur.size = size; + DEBUGP (("size: %s; ", number_to_static_string(cur.size))); + + month = i; + next = 5; + DEBUGP (("month: %s; ", months[month])); + } + } + else if (next == 4) /* days */ + { + if (tok[1]) /* two-digit... */ + day = 10 * (*tok - '0') + tok[1] - '0'; + else /* ...or one-digit */ + day = *tok - '0'; + DEBUGP (("day: %d; ", day)); + } + else if (next == 3) + { + /* This ought to be either the time, or the year. Let's + be flexible! + + If we have a number x, it's a year. If we have x:y, + it's hours and minutes. If we have x:y:z, z are + seconds. */ + year = 0; + min = hour = sec = 0; + /* We must deal with digits. */ + if (c_isdigit (*tok)) + { + /* Suppose it's year. Limit to year 99999 to avoid integer overflow. */ + for (; c_isdigit (*tok) && year <= 99999; tok++) + year = (*tok - '0') + 10 * year; + if (*tok == ':') + { + int n; + /* This means these were hours! */ + hour = year; + year = 0; + ptype = TT_HOUR_MIN; + ++tok; + /* Get the minutes... */ + for (n = 0; c_isdigit (*tok) && n < 2; tok++, n++) + min = (*tok - '0') + 10 * min; + if (*tok == ':') + { + /* ...and the seconds. */ + ++tok; + for (n = 0; c_isdigit (*tok) && n < 2; tok++, n++) + sec = (*tok - '0') + 10 * sec; + } + } + } + if (year) + DEBUGP (("year: %d (no tm); ", year)); + else + DEBUGP (("time: %02d:%02d:%02d (no yr); ", hour, min, sec)); + } + else if (next == 2) /* The file name */ + { + int fnlen; + char *p; + + /* Since the file name may contain a SPC, it is possible + for strtok to handle it wrong. */ + fnlen = strlen (tok); + if (fnlen < len - (tok - line)) + { + /* So we have a SPC in the file name. Restore the + original. */ + tok[fnlen] = ' '; + /* If the file is a symbolic link, it should have a + ` -> ' somewhere. */ + if (cur.type == FT_SYMLINK) + { + p = strstr (tok, " -> "); + if (!p) + { + error = 1; + break; + } + cur.linkto = xstrdup (p + 4); + DEBUGP (("link to: %s\n", cur.linkto)); + /* And separate it from the file name. */ + *p = '\0'; + } + } + /* If we have the filename, add it to the list of files or + directories. */ + /* "." and ".." are an exception! */ + if (!strcmp (tok, ".") || !strcmp (tok, "..")) + { + DEBUGP (("\nIgnoring `.' and `..'; ")); + ignore = 1; + break; + } + /* Some FTP sites choose to have ls -F as their default + LIST output, which marks the symlinks with a trailing + `@', directory names with a trailing `/' and + executables with a trailing `*'. This is no problem + unless encountering a symbolic link ending with `@', + or an executable ending with `*' on a server without + default -F output. I believe these cases are very + rare. */ + fnlen = strlen (tok); /* re-calculate `fnlen' */ + cur.name = xmalloc (fnlen + 1); + memcpy (cur.name, tok, fnlen + 1); + if (fnlen) + { + if (cur.type == FT_DIRECTORY && cur.name[fnlen - 1] == '/') + { + cur.name[fnlen - 1] = '\0'; + DEBUGP (("trailing `/' on dir.\n")); + } + else if (cur.type == FT_SYMLINK && cur.name[fnlen - 1] == '@') + { + cur.name[fnlen - 1] = '\0'; + DEBUGP (("trailing `@' on link.\n")); + } + else if (cur.type == FT_PLAINFILE + && (cur.perms & 0111) + && cur.name[fnlen - 1] == '*') + { + cur.name[fnlen - 1] = '\0'; + DEBUGP (("trailing `*' on exec.\n")); + } + } /* if (fnlen) */ + else + error = 1; + break; + } + else + abort (); + } /* while */ + + if (!cur.name || (cur.type == FT_SYMLINK && !cur.linkto)) + error = 1; + + DEBUGP (("%s\n", cur.name ? cur.name : "")); + + if (error || ignore) + { + DEBUGP (("Skipping.\n")); + xfree (cur.name); + xfree (cur.linkto); + continue; + } + + if (!dir) + { + l = dir = xnew (struct fileinfo); + memcpy (l, &cur, sizeof (cur)); + l->prev = l->next = NULL; + } + else + { + cur.prev = l; + l->next = xnew (struct fileinfo); + l = l->next; + memcpy (l, &cur, sizeof (cur)); + l->next = NULL; + } + /* Get the current time. */ + timenow = time (NULL); + tnow = localtime (&timenow); + /* Build the time-stamp (the idea by zaga@fly.cc.fer.hr). */ + timestruct.tm_sec = sec; + timestruct.tm_min = min; + timestruct.tm_hour = hour; + timestruct.tm_mday = day; + timestruct.tm_mon = month; + if (year == 0) + { + /* Some listings will not specify the year if it is "obvious" + that the file was from the previous year. E.g. if today + is 97-01-12, and you see a file of Dec 15th, its year is + 1996, not 1997. Thanks to Vladimir Volovich for + mentioning this! */ + if (month > tnow->tm_mon) + timestruct.tm_year = tnow->tm_year - 1; + else + timestruct.tm_year = tnow->tm_year; + } + else + timestruct.tm_year = year; + if (timestruct.tm_year >= 1900) + timestruct.tm_year -= 1900; + timestruct.tm_wday = 0; + timestruct.tm_yday = 0; + timestruct.tm_isdst = -1; + l->tstamp = mktime (×truct); /* store the time-stamp */ + l->ptype = ptype; + } + + xfree (line); + return dir; +} + +static struct fileinfo * +ftp_parse_winnt_ls (FILE *fp) +{ + int len; + int year, month, day; /* for time analysis */ + int hour, min; + size_t bufsize = 0; + struct tm timestruct; + + char *line = NULL, *tok; /* tokenizer */ + char *filename; + struct fileinfo *dir, *l, cur; /* list creation */ + + dir = l = NULL; + cur.name = NULL; + + /* Line loop to end of file: */ + while ((len = getline (&line, &bufsize, fp)) > 0) + { + len = clean_line (line, len); + + /* Name begins at 39 column of the listing if date presented in `mm-dd-yy' + format or at 41 column if date presented in `mm-dd-yyyy' format. Thus, + we cannot extract name before we parse date. Using this information we + also can recognize filenames that begin with a series of space + characters (but who really wants to use such filenames anyway?). */ + if (len < 40) continue; + filename = line + 39; + + /* First column: mm-dd-yy or mm-dd-yyyy. Should atoi() on the month fail, + january will be assumed. */ + tok = strtok(line, "-"); + if (tok == NULL) continue; + month = atoi(tok); + if (month < 0) month = 0; else month--; + tok = strtok(NULL, "-"); + if (tok == NULL) continue; + day = atoi(tok); + tok = strtok(NULL, " "); + if (tok == NULL) continue; + year = atoi(tok); + /* Assuming the epoch starting at 1.1.1970 */ + if (year <= 70) + { + year += 100; + } + else if (year >= 1900) + { + year -= 1900; + if (len < 42) continue; + filename += 2; + } + /* Now it is possible to determine the position of the first symbol in + filename. */ + xfree (cur.name); + memset(&cur, 0, sizeof (cur)); + cur.name = xstrdup(filename); + DEBUGP (("Name: '%s'\n", cur.name)); + + + /* Second column: hh:mm[AP]M, listing does not contain value for + seconds */ + tok = strtok(NULL, ":"); + if (tok == NULL) continue; + hour = atoi(tok); + tok = strtok(NULL, "M"); + if (tok == NULL) continue; + min = atoi(tok); + /* Adjust hour from AM/PM. Just for the record, the sequence goes + 11:00AM, 12:00PM, 01:00PM ... 11:00PM, 12:00AM, 01:00AM . */ + if (tok[0] && tok[1]) tok+=2; + if (hour >= 12 || hour < 0) hour = 0; + if (*tok == 'P') hour += 12; + + DEBUGP (("YYYY/MM/DD HH:MM - %d/%02d/%02d %02d:%02d\n", + year+1900, month, day, hour, min)); + + /* Build the time-stamp (copy & paste from above) */ + timestruct.tm_sec = 0; + timestruct.tm_min = min; + timestruct.tm_hour = hour; + timestruct.tm_mday = day; + timestruct.tm_mon = month; + timestruct.tm_year = year; + timestruct.tm_wday = 0; + timestruct.tm_yday = 0; + timestruct.tm_isdst = -1; + cur.tstamp = mktime (×truct); /* store the time-stamp */ + cur.ptype = TT_HOUR_MIN; + + DEBUGP (("Timestamp: %ld\n", cur.tstamp)); + + /* Third column: Either file length, or . We also set the + permissions (guessed as 0644 for plain files and 0755 for + directories as the listing does not give us a clue) and filetype + here. */ + tok = strtok(NULL, " "); + if (tok == NULL) continue; + while ((tok != NULL) && (*tok == '\0')) tok = strtok(NULL, " "); + if (tok == NULL) continue; + if (*tok == '<') + { + cur.type = FT_DIRECTORY; + cur.size = 0; + cur.perms = 0755; + DEBUGP (("Directory\n")); + } + else + { + wgint size; + cur.type = FT_PLAINFILE; + errno = 0; + size = str_to_wgint (tok, NULL, 10); + if (size == WGINT_MAX && errno == ERANGE) + cur.size = 0; /* overflow */ + else + cur.size = size; + cur.perms = 0644; + DEBUGP (("File, size %s bytes\n", number_to_static_string (cur.size))); + } + + cur.linkto = NULL; + + /* And put everything into the linked list */ + if (!dir) + { + l = dir = xnew (struct fileinfo); + memcpy (l, &cur, sizeof (cur)); + l->prev = l->next = NULL; + } + else + { + cur.prev = l; + l->next = xnew (struct fileinfo); + l = l->next; + memcpy (l, &cur, sizeof (cur)); + l->next = NULL; + } + cur.name = NULL; + } + + xfree (cur.name); + xfree (line); + return dir; +} + + + +/* Convert the VMS-style directory listing stored in "file" to a + linked list of fileinfo (system-independent) entries. The contents + of FILE are considered to be produced by the standard VMS + "DIRECTORY [/SIZE [= ALL]] /DATE [/OWNER] [/PROTECTION]" command, + more or less. (Different VMS FTP servers may have different headers, + and may not supply the same data, but all should be subsets of this.) + + VMS normally provides local (server) time and date information. + Define the logical name or environment variable + "WGET_TIMEZONE_DIFFERENTIAL" (seconds) to adjust the receiving local + times if different from the remote local times. + + 2005-02-23 SMS. + Added code to eliminate "^" escape characters from ODS5 extended file + names. The TCPIP FTP server (V5.4) seems to prefer requests which do + not use the escaped names which it provides. +*/ + +#define VMS_DEFAULT_PROT_FILE 0644 +#define VMS_DEFAULT_PROT_DIR 0755 + +/* 2005-02-23 SMS. + eat_carets(). + + Delete ODS5 extended file name escape characters ("^") in the + original buffer. + Note that the current scheme does not handle all EFN cases, but it + could be made more complicated. +*/ + +static void eat_carets( char *str) +/* char *str; Source pointer. */ +{ + char *strd; /* Destination pointer. */ + char hdgt; + unsigned char uchr; + + /* Skip ahead to the first "^", if any. */ + while ((*str != '\0') && (*str != '^')) + str++; + + /* If no caret was found, quit early. */ + if (*str != '\0') + { + /* Shift characters leftward as carets are found. */ + strd = str; + while (*str != '\0') + { + uchr = *str; + if (uchr == '^') + { + /* Found a caret. Skip it, and check the next character. */ + if ((char_prop[(unsigned char) str[1]] & 64) && (char_prop[(unsigned char) str[2]] & 64)) + { + /* Hex digit. Get char code from this and next hex digit. */ + uchr = *(++str); + if (uchr <= '9') + { + hdgt = uchr - '0'; /* '0' - '9' -> 0 - 9. */ + } + else + { + hdgt = ((uchr - 'A') & 7) + 10; /* [Aa] - [Ff] -> 10 - 15. */ + } + hdgt <<= 4; /* X16. */ + uchr = *(++str); /* Next char must be hex digit. */ + if (uchr <= '9') + { + uchr = hdgt + uchr - '0'; + } + else + { + uchr = hdgt + ((uchr - 'A') & 15) + 10; + } + } + else if (uchr == '_') + { + /* Convert escaped "_" to " ". */ + uchr = ' '; + } + else if (uchr == '/') + { + /* Convert escaped "/" (invalid Zip) to "?" (invalid VMS). */ + /* Note that this is a left-over from Info-ZIP code, and is + probably of little value here, except perhaps to avoid + directory confusion which an unconverted slash might cause. + */ + uchr = '?'; + } + /* Else, not a hex digit. Must be a simple escaped character + (or Unicode, which is not yet handled here). + */ + } + /* Else, not a caret. Use as-is. */ + *strd = uchr; + + /* Advance destination and source pointers. */ + strd++; + str++; + } + /* Terminate the destination string. */ + *strd = '\0'; + } +} + + +static struct fileinfo * +ftp_parse_vms_ls (FILE *fp) +{ + int dt, i, j, len; + int perms; + size_t bufsize = 0; + time_t timenow; + struct tm *timestruct; + char date_str[32]; + + char *line = NULL, *tok; /* tokenizer */ + struct fileinfo *dir, *l, cur; /* list creation */ + + dir = l = NULL; + + /* Skip blank lines, Directory heading, and more blank lines. */ + + for (j = 0; (i = getline (&line, &bufsize, fp)) > 0; ) + { + i = clean_line (line, i); + if (i <= 0) + continue; /* Ignore blank line. */ + + if ((j == 0) && (line[i - 1] == ']')) + { + /* Found Directory heading line. Next non-blank line + is significant. */ + j = 1; + } + else if (!strncmp (line, "Total of ", 9)) + { + /* Found "Total of ..." footing line. No valid data + will follow (empty directory). */ + i = 0; /* Arrange for early exit. */ + break; + } + else + { + break; /* Must be significant data. */ + } + } + + /* Read remainder of file until the next blank line or EOF. */ + + cur.name = NULL; + while (i > 0) + { + char *p; + + /* The first token is the file name. After a long name, other + data may be on the following line. A valid directory name ends + in ".DIR;1" (any case), although some VMS FTP servers may omit + the version number (";1"). + */ + + tok = strtok(line, " "); + if (tok == NULL) tok = line; + DEBUGP (("file name: '%s'\n", tok)); + + /* Stripping the version number on a VMS system would be wrong. + It may be foolish on a non-VMS system, too, but that's someone + else's problem. (Define PRESERVE_VMS_VERSIONS for proper + operation on other operating systems.) + + 2005-02-23 SMS. + ODS5 extended file names may contain escaped semi-colons, so + the version number is identified as right-side decimal digits + led by a non-escaped semi-colon. It may be absent. + */ + +#if (!defined( __VMS) && !defined( PRESERVE_VMS_VERSIONS)) + for (p = tok + strlen (tok); (--p > tok) && c_isdigit(*p); ); + if (p > tok && (*p == ';') && (*(p - 1) != '^')) + { + *p = '\0'; + } +#endif /* (!defined( __VMS) && !defined( PRESERVE_VMS_VERSIONS)) */ + + /* 2005-02-23 SMS. + Eliminate "^" escape characters from ODS5 extended file name. + (A caret is invalid in an ODS2 name, so this is always safe.) + */ + eat_carets (tok); + DEBUGP (("file name-^: '%s'\n", tok)); + + /* Differentiate between a directory and any other file. A VMS + listing may not include file protections (permissions). Set a + default permissions value (according to the file type), which + may be overwritten later. Store directory names without the + ".DIR;1" file type and version number, as the plain name is + what will work in a CWD command. + */ + len = strlen (tok); + if (len >= 4 && !c_strncasecmp(tok + (len - 4), ".DIR", 4)) + { + *(tok + (len - 4)) = '\0'; /* Discard ".DIR". */ + cur.type = FT_DIRECTORY; + cur.perms = VMS_DEFAULT_PROT_DIR; + DEBUGP (("Directory (nv)\n")); + } + else if (len >= 6 && !c_strncasecmp (tok + len - 6, ".DIR;1", 6)) + { + *(tok + (len - 6)) = '\0'; /* Discard ".DIR;1". */ + cur.type = FT_DIRECTORY; + cur.perms = VMS_DEFAULT_PROT_DIR; + DEBUGP (("Directory (v)\n")); + } + else + { + cur.type = FT_PLAINFILE; + cur.perms = VMS_DEFAULT_PROT_FILE; + DEBUGP (("File\n")); + } + xfree (cur.name); + cur.name = xstrdup (tok); + DEBUGP (("Name: '%s'\n", cur.name)); + + /* Null the date and time string. */ + *date_str = '\0'; + + /* VMS lacks symbolic links. */ + cur.linkto = NULL; + + /* VMS reports file sizes in (512-byte) disk blocks, not bytes, + hence useless for an integrity check based on byte-count. + Set size to unknown. + */ + cur.size = 0; + + /* Get token 2, if any. A long name may force all other data onto + a second line. If needed, read the second line. + */ + + tok = strtok (NULL, " "); + if (tok == NULL) + { + DEBUGP (("Getting additional line.\n")); + i = getline (&line, &bufsize, fp); + if (i <= 0) + { + DEBUGP (("EOF. Leaving listing parser.\n")); + break; + } + + /* Second line must begin with " ". Otherwise, it's a first + line (and we may be confused). + */ + i = clean_line (line, i); + if (i <= 0) + { + /* Blank line. End of significant file listing. */ + DEBUGP (("Blank line. Leaving listing parser.\n")); + break; + } + else if (line[0] != ' ') + { + DEBUGP (("Non-blank in column 1. Must be a new file name?\n")); + continue; + } + else + { + tok = strtok (line, " "); + if (tok == NULL) + { + /* Unexpected non-empty but apparently blank line. */ + DEBUGP (("Null token. Leaving listing parser.\n")); + break; + } + } + } + + /* Analyze tokens. (Order is not significant, except date must + precede time.) + + Size: ddd or ddd/ddd (where "ddd" is a decimal number) + Date: DD-MMM-YYYY + Time: HH:MM or HH:MM:SS or HH:MM:SS.CC + Owner: [user] or [user,group] + Protection: (ppp,ppp,ppp,ppp) (where "ppp" is "RWED" or some + subset thereof, for System, Owner, Group, World. + + If permission is lacking, info may be replaced by the string: + "No privilege for attempted operation". + */ + while (tok != NULL) + { + DEBUGP (("Token: >%s<: ", tok)); + + if ((strlen (tok) < 12) && (strchr( tok, '-') != NULL)) + { + /* Date. */ + DEBUGP (("Date.\n")); + snprintf(date_str, sizeof(date_str), "%s ", tok); + } + else if ((strlen (tok) < 12) && (strchr( tok, ':') != NULL)) + { + /* Time. */ + DEBUGP (("Time. ")); + strncat( date_str, + tok, + (sizeof( date_str)- strlen (date_str) - 1)); + DEBUGP (("Date time: >%s<\n", date_str)); + } + else if (strchr (tok, '[') != NULL) + { + /* Owner. (Ignore.) */ + DEBUGP (("Owner.\n")); + } + else if (strchr (tok, '(') != NULL) + { + /* Protections (permissions). */ + perms = 0; + j = 0; + /*FIXME: Should not be using the variable like this. */ + for (i = 0; i < (int) strlen(tok); i++) + { + switch (tok[ i]) + { + case '(': + break; + case ')': + break; + case ',': + if (j == 0) + { + perms = 0; + } + else if (j < 4) + { + perms <<= 3; + } + j++; + break; + case 'R': + perms |= 4; + break; + case 'W': + perms |= 2; + break; + case 'E': + perms |= 1; + break; + case 'D': + perms |= 2; + break; + } + } + cur.perms = perms; + DEBUGP (("Prot. perms = %0o.\n", (unsigned) cur.perms)); + } + else + { + /* Nondescript. Probably size(s), probably in blocks. + Could be "No privilege ..." message. (Ignore.) + */ + DEBUGP (("Ignored (size?).\n")); + } + + tok = strtok (NULL, " "); + } + + /* Tokens exhausted. Interpret the data, and fill in the + structure. + */ + /* Fill tm timestruct according to date-time string. Fractional + seconds are ignored. Default to current time, if conversion + fails. + */ + timenow = time( NULL); + timestruct = localtime( &timenow ); + strptime( date_str, "%d-%b-%Y %H:%M:%S", timestruct); + + /* Convert struct tm local time to time_t local time. */ + timenow = mktime (timestruct); + /* Offset local time according to environment variable (seconds). */ + if ((tok = getenv ( "WGET_TIMEZONE_DIFFERENTIAL")) != NULL) + { + dt = atoi (tok); + DEBUGP (("Time differential = %d.\n", dt)); + } + else + dt = 0; + + if (dt >= 0) + timenow += dt; + else + timenow -= (-dt); + + cur.tstamp = timenow; /* Store the time-stamp. */ + DEBUGP (("Timestamp: %ld\n", cur.tstamp)); + cur.ptype = TT_HOUR_MIN; + + /* Add the data for this item to the linked list, */ + if (!dir) + { + l = dir = (struct fileinfo *)xmalloc (sizeof (struct fileinfo)); + cur.prev = cur.next = NULL; + memcpy (l, &cur, sizeof (cur)); + } + else + { + cur.prev = l; + cur.next = NULL; + l->next = (struct fileinfo *)xmalloc (sizeof (struct fileinfo)); + l = l->next; + memcpy (l, &cur, sizeof (cur)); + } + cur.name = NULL; + + i = getline (&line, &bufsize, fp); + if (i > 0) + { + i = clean_line (line, i); + if (i <= 0) + { + /* Blank line. End of significant file listing. */ + break; + } + } + } + + xfree (cur.name); + xfree (line); + return dir; +} + + +/* This function switches between the correct parsing routine depending on + the SYSTEM_TYPE. The system type should be based on the result of the + "SYST" response of the FTP server. According to this response we will + use on of the three different listing parsers that cover the most of FTP + servers used nowadays. */ + +struct fileinfo * +ftp_parse_ls (const char *file, const enum stype system_type) +{ + FILE *fp; + struct fileinfo *fi; + + fp = fopen (file, "rb"); + if (!fp) + { + logprintf (LOG_NOTQUIET, "%s: %s\n", file, strerror (errno)); + return NULL; + } + + fi = ftp_parse_ls_fp (fp, system_type); + fclose(fp); + + return fi; +} + +struct fileinfo * +ftp_parse_ls_fp (FILE *fp, const enum stype system_type) +{ + switch (system_type) + { + case ST_UNIX: + return ftp_parse_unix_ls (fp, 0); + case ST_WINNT: + { + /* Detect whether the listing is simulating the UNIX format */ + int c = fgetc(fp); + rewind(fp); + + /* If the first character of the file is '0'-'9', it's WINNT + format. */ + if (c >= '0' && c <='9') + return ftp_parse_winnt_ls (fp); + else + return ftp_parse_unix_ls (fp, 1); + } + case ST_VMS: + return ftp_parse_vms_ls (fp); + case ST_MACOS: + return ftp_parse_unix_ls (fp, 1); + default: + logprintf (LOG_NOTQUIET, _("\ +Unsupported listing type, trying Unix listing parser.\n")); + return ftp_parse_unix_ls (fp, 0); + } +} + +/* Stuff for creating FTP index. */ + +/* The function creates an HTML index containing references to given + directories and files on the appropriate host. The references are + FTP. */ +uerr_t +ftp_index (const char *file, struct url *u, struct fileinfo *f) +{ + FILE *fp; + char *upwd; + char *htcldir; /* HTML-clean dir name */ + char *htclfile; /* HTML-clean file name */ + char *urlclfile; /* URL-clean file name */ + + if (!output_stream) + { + fp = fopen (file, "wb"); + if (!fp) + { + logprintf (LOG_NOTQUIET, "%s: %s\n", file, strerror (errno)); + return FOPENERR; + } + } + else + fp = output_stream; + if (u->user) + { + char *tmpu, *tmpp; /* temporary, clean user and passwd */ + + tmpu = url_escape (u->user); + tmpp = u->passwd ? url_escape (u->passwd) : NULL; + if (tmpp) + upwd = concat_strings (tmpu, ":", tmpp, "@", (char *) 0); + else + upwd = concat_strings (tmpu, "@", (char *) 0); + xfree (tmpu); + xfree (tmpp); + } + else + upwd = xstrdup (""); + + htcldir = html_quote_string (u->dir); + + fprintf (fp, "\n"); + fprintf (fp, "\n\n"); + fprintf (fp, _("Index of /%s on %s:%d"), htcldir, u->host, u->port); + fprintf (fp, "\n\n\n

"); + fprintf (fp, _("Index of /%s on %s:%d"), htcldir, u->host, u->port); + fprintf (fp, "

\n
\n
\n");
+
+  while (f)
+    {
+      fprintf (fp, "  ");
+      if (f->tstamp != -1)
+        {
+          /* #### Should we translate the months?  Or, even better, use
+             ISO 8601 dates?  */
+          static const char *months[] = {
+            "Jan", "Feb", "Mar", "Apr", "May", "Jun",
+            "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
+          };
+          time_t tstamp = f->tstamp;
+          struct tm *ptm = localtime (&tstamp);
+
+          fprintf (fp, "%d %s %02d ", ptm->tm_year + 1900, months[ptm->tm_mon],
+                  ptm->tm_mday);
+          if (f->ptype == TT_HOUR_MIN)
+            fprintf (fp, "%02d:%02d  ", ptm->tm_hour, ptm->tm_min);
+          else
+            fprintf (fp, "       ");
+        }
+      else
+        fprintf (fp, _("time unknown       "));
+      switch (f->type)
+        {
+        case FT_PLAINFILE:
+          fprintf (fp, _("File        "));
+          break;
+        case FT_DIRECTORY:
+          fprintf (fp, _("Directory   "));
+          break;
+        case FT_SYMLINK:
+          fprintf (fp, _("Link        "));
+          break;
+        default:
+          fprintf (fp, _("Not sure    "));
+          break;
+        }
+      htclfile = html_quote_string (f->name);
+      urlclfile = url_escape_unsafe_and_reserved (f->name);
+      fprintf (fp, "host, u->port);
+      if (*u->dir != '/')
+        putc ('/', fp);
+      /* XXX: Should probably URL-escape dir components here, rather
+       * than just HTML-escape, for consistency with the next bit where
+       * we use urlclfile for the file component. Anyway, this is safer
+       * than what we had... */
+      fprintf (fp, "%s", htcldir);
+      if (*u->dir)
+        putc ('/', fp);
+      fprintf (fp, "%s", urlclfile);
+      if (f->type == FT_DIRECTORY)
+        putc ('/', fp);
+      fprintf (fp, "\">%s", htclfile);
+      if (f->type == FT_DIRECTORY)
+        putc ('/', fp);
+      fprintf (fp, " ");
+      if (f->type == FT_PLAINFILE)
+        fprintf (fp, _(" (%s bytes)"), number_to_static_string (f->size));
+      else if (f->type == FT_SYMLINK)
+        fprintf (fp, "-> %s", f->linkto ? f->linkto : "(nil)");
+      putc ('\n', fp);
+      xfree (htclfile);
+      xfree (urlclfile);
+      f = f->next;
+    }
+  fprintf (fp, "
\n\n\n"); + xfree (htcldir); + xfree (upwd); + if (!output_stream) + fclose (fp); + else + fflush (fp); + return FTPOK; +} diff --git a/src/ftp-opie.c b/src/ftp-opie.c new file mode 100644 index 0000000..abe174b --- /dev/null +++ b/src/ftp-opie.c @@ -0,0 +1,2220 @@ +/* Opie (s/key) support for FTP. + Copyright (C) 1998-2011, 2015, 2018-2020 Free Software Foundation, + Inc. + +This file is part of GNU Wget. + +GNU Wget is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 3 of the License, or +(at your option) any later version. + +GNU Wget 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 Wget. If not, see . + +Additional permission under GNU GPL version 3 section 7 + +If you modify this program, or any covered work, by linking or +combining it with the OpenSSL project's OpenSSL library (or a +modified version of that library), containing parts covered by the +terms of the OpenSSL or SSLeay licenses, the Free Software Foundation +grants you additional permission to convey the resulting work. +Corresponding Source for a non-source form of such a combination +shall include the source code for the parts of OpenSSL used as well +as that of the covered work. */ + +#include "wget.h" + +#include +#include +#include + +#include "md5.h" +#include "ftp.h" + +/* Dictionary for integer-word translations. Available in appendix D + of rfc2289. */ + static char Wp[2048][4] = { + { 'A', '\0', '\0', '\0' }, + { 'A', 'B', 'E', '\0' }, + { 'A', 'C', 'E', '\0' }, + { 'A', 'C', 'T', '\0' }, + { 'A', 'D', '\0', '\0' }, + { 'A', 'D', 'A', '\0' }, + { 'A', 'D', 'D', '\0' }, + { 'A', 'G', 'O', '\0' }, + { 'A', 'I', 'D', '\0' }, + { 'A', 'I', 'M', '\0' }, + { 'A', 'I', 'R', '\0' }, + { 'A', 'L', 'L', '\0' }, + { 'A', 'L', 'P', '\0' }, + { 'A', 'M', '\0', '\0' }, + { 'A', 'M', 'Y', '\0' }, + { 'A', 'N', '\0', '\0' }, + { 'A', 'N', 'A', '\0' }, + { 'A', 'N', 'D', '\0' }, + { 'A', 'N', 'N', '\0' }, + { 'A', 'N', 'T', '\0' }, + { 'A', 'N', 'Y', '\0' }, + { 'A', 'P', 'E', '\0' }, + { 'A', 'P', 'S', '\0' }, + { 'A', 'P', 'T', '\0' }, + { 'A', 'R', 'C', '\0' }, + { 'A', 'R', 'E', '\0' }, + { 'A', 'R', 'K', '\0' }, + { 'A', 'R', 'M', '\0' }, + { 'A', 'R', 'T', '\0' }, + { 'A', 'S', '\0', '\0' }, + { 'A', 'S', 'H', '\0' }, + { 'A', 'S', 'K', '\0' }, + { 'A', 'T', '\0', '\0' }, + { 'A', 'T', 'E', '\0' }, + { 'A', 'U', 'G', '\0' }, + { 'A', 'U', 'K', '\0' }, + { 'A', 'V', 'E', '\0' }, + { 'A', 'W', 'E', '\0' }, + { 'A', 'W', 'K', '\0' }, + { 'A', 'W', 'L', '\0' }, + { 'A', 'W', 'N', '\0' }, + { 'A', 'X', '\0', '\0' }, + { 'A', 'Y', 'E', '\0' }, + { 'B', 'A', 'D', '\0' }, + { 'B', 'A', 'G', '\0' }, + { 'B', 'A', 'H', '\0' }, + { 'B', 'A', 'M', '\0' }, + { 'B', 'A', 'N', '\0' }, + { 'B', 'A', 'R', '\0' }, + { 'B', 'A', 'T', '\0' }, + { 'B', 'A', 'Y', '\0' }, + { 'B', 'E', '\0', '\0' }, + { 'B', 'E', 'D', '\0' }, + { 'B', 'E', 'E', '\0' }, + { 'B', 'E', 'G', '\0' }, + { 'B', 'E', 'N', '\0' }, + { 'B', 'E', 'T', '\0' }, + { 'B', 'E', 'Y', '\0' }, + { 'B', 'I', 'B', '\0' }, + { 'B', 'I', 'D', '\0' }, + { 'B', 'I', 'G', '\0' }, + { 'B', 'I', 'N', '\0' }, + { 'B', 'I', 'T', '\0' }, + { 'B', 'O', 'B', '\0' }, + { 'B', 'O', 'G', '\0' }, + { 'B', 'O', 'N', '\0' }, + { 'B', 'O', 'O', '\0' }, + { 'B', 'O', 'P', '\0' }, + { 'B', 'O', 'W', '\0' }, + { 'B', 'O', 'Y', '\0' }, + { 'B', 'U', 'B', '\0' }, + { 'B', 'U', 'D', '\0' }, + { 'B', 'U', 'G', '\0' }, + { 'B', 'U', 'M', '\0' }, + { 'B', 'U', 'N', '\0' }, + { 'B', 'U', 'S', '\0' }, + { 'B', 'U', 'T', '\0' }, + { 'B', 'U', 'Y', '\0' }, + { 'B', 'Y', '\0', '\0' }, + { 'B', 'Y', 'E', '\0' }, + { 'C', 'A', 'B', '\0' }, + { 'C', 'A', 'L', '\0' }, + { 'C', 'A', 'M', '\0' }, + { 'C', 'A', 'N', '\0' }, + { 'C', 'A', 'P', '\0' }, + { 'C', 'A', 'R', '\0' }, + { 'C', 'A', 'T', '\0' }, + { 'C', 'A', 'W', '\0' }, + { 'C', 'O', 'D', '\0' }, + { 'C', 'O', 'G', '\0' }, + { 'C', 'O', 'L', '\0' }, + { 'C', 'O', 'N', '\0' }, + { 'C', 'O', 'O', '\0' }, + { 'C', 'O', 'P', '\0' }, + { 'C', 'O', 'T', '\0' }, + { 'C', 'O', 'W', '\0' }, + { 'C', 'O', 'Y', '\0' }, + { 'C', 'R', 'Y', '\0' }, + { 'C', 'U', 'B', '\0' }, + { 'C', 'U', 'E', '\0' }, + { 'C', 'U', 'P', '\0' }, + { 'C', 'U', 'R', '\0' }, + { 'C', 'U', 'T', '\0' }, + { 'D', 'A', 'B', '\0' }, + { 'D', 'A', 'D', '\0' }, + { 'D', 'A', 'M', '\0' }, + { 'D', 'A', 'N', '\0' }, + { 'D', 'A', 'R', '\0' }, + { 'D', 'A', 'Y', '\0' }, + { 'D', 'E', 'E', '\0' }, + { 'D', 'E', 'L', '\0' }, + { 'D', 'E', 'N', '\0' }, + { 'D', 'E', 'S', '\0' }, + { 'D', 'E', 'W', '\0' }, + { 'D', 'I', 'D', '\0' }, + { 'D', 'I', 'E', '\0' }, + { 'D', 'I', 'G', '\0' }, + { 'D', 'I', 'N', '\0' }, + { 'D', 'I', 'P', '\0' }, + { 'D', 'O', '\0', '\0' }, + { 'D', 'O', 'E', '\0' }, + { 'D', 'O', 'G', '\0' }, + { 'D', 'O', 'N', '\0' }, + { 'D', 'O', 'T', '\0' }, + { 'D', 'O', 'W', '\0' }, + { 'D', 'R', 'Y', '\0' }, + { 'D', 'U', 'B', '\0' }, + { 'D', 'U', 'D', '\0' }, + { 'D', 'U', 'E', '\0' }, + { 'D', 'U', 'G', '\0' }, + { 'D', 'U', 'N', '\0' }, + { 'E', 'A', 'R', '\0' }, + { 'E', 'A', 'T', '\0' }, + { 'E', 'D', '\0', '\0' }, + { 'E', 'E', 'L', '\0' }, + { 'E', 'G', 'G', '\0' }, + { 'E', 'G', 'O', '\0' }, + { 'E', 'L', 'I', '\0' }, + { 'E', 'L', 'K', '\0' }, + { 'E', 'L', 'M', '\0' }, + { 'E', 'L', 'Y', '\0' }, + { 'E', 'M', '\0', '\0' }, + { 'E', 'N', 'D', '\0' }, + { 'E', 'S', 'T', '\0' }, + { 'E', 'T', 'C', '\0' }, + { 'E', 'V', 'A', '\0' }, + { 'E', 'V', 'E', '\0' }, + { 'E', 'W', 'E', '\0' }, + { 'E', 'Y', 'E', '\0' }, + { 'F', 'A', 'D', '\0' }, + { 'F', 'A', 'N', '\0' }, + { 'F', 'A', 'R', '\0' }, + { 'F', 'A', 'T', '\0' }, + { 'F', 'A', 'Y', '\0' }, + { 'F', 'E', 'D', '\0' }, + { 'F', 'E', 'E', '\0' }, + { 'F', 'E', 'W', '\0' }, + { 'F', 'I', 'B', '\0' }, + { 'F', 'I', 'G', '\0' }, + { 'F', 'I', 'N', '\0' }, + { 'F', 'I', 'R', '\0' }, + { 'F', 'I', 'T', '\0' }, + { 'F', 'L', 'O', '\0' }, + { 'F', 'L', 'Y', '\0' }, + { 'F', 'O', 'E', '\0' }, + { 'F', 'O', 'G', '\0' }, + { 'F', 'O', 'R', '\0' }, + { 'F', 'R', 'Y', '\0' }, + { 'F', 'U', 'M', '\0' }, + { 'F', 'U', 'N', '\0' }, + { 'F', 'U', 'R', '\0' }, + { 'G', 'A', 'B', '\0' }, + { 'G', 'A', 'D', '\0' }, + { 'G', 'A', 'G', '\0' }, + { 'G', 'A', 'L', '\0' }, + { 'G', 'A', 'M', '\0' }, + { 'G', 'A', 'P', '\0' }, + { 'G', 'A', 'S', '\0' }, + { 'G', 'A', 'Y', '\0' }, + { 'G', 'E', 'E', '\0' }, + { 'G', 'E', 'L', '\0' }, + { 'G', 'E', 'M', '\0' }, + { 'G', 'E', 'T', '\0' }, + { 'G', 'I', 'G', '\0' }, + { 'G', 'I', 'L', '\0' }, + { 'G', 'I', 'N', '\0' }, + { 'G', 'O', '\0', '\0' }, + { 'G', 'O', 'T', '\0' }, + { 'G', 'U', 'M', '\0' }, + { 'G', 'U', 'N', '\0' }, + { 'G', 'U', 'S', '\0' }, + { 'G', 'U', 'T', '\0' }, + { 'G', 'U', 'Y', '\0' }, + { 'G', 'Y', 'M', '\0' }, + { 'G', 'Y', 'P', '\0' }, + { 'H', 'A', '\0', '\0' }, + { 'H', 'A', 'D', '\0' }, + { 'H', 'A', 'L', '\0' }, + { 'H', 'A', 'M', '\0' }, + { 'H', 'A', 'N', '\0' }, + { 'H', 'A', 'P', '\0' }, + { 'H', 'A', 'S', '\0' }, + { 'H', 'A', 'T', '\0' }, + { 'H', 'A', 'W', '\0' }, + { 'H', 'A', 'Y', '\0' }, + { 'H', 'E', '\0', '\0' }, + { 'H', 'E', 'M', '\0' }, + { 'H', 'E', 'N', '\0' }, + { 'H', 'E', 'R', '\0' }, + { 'H', 'E', 'W', '\0' }, + { 'H', 'E', 'Y', '\0' }, + { 'H', 'I', '\0', '\0' }, + { 'H', 'I', 'D', '\0' }, + { 'H', 'I', 'M', '\0' }, + { 'H', 'I', 'P', '\0' }, + { 'H', 'I', 'S', '\0' }, + { 'H', 'I', 'T', '\0' }, + { 'H', 'O', '\0', '\0' }, + { 'H', 'O', 'B', '\0' }, + { 'H', 'O', 'C', '\0' }, + { 'H', 'O', 'E', '\0' }, + { 'H', 'O', 'G', '\0' }, + { 'H', 'O', 'P', '\0' }, + { 'H', 'O', 'T', '\0' }, + { 'H', 'O', 'W', '\0' }, + { 'H', 'U', 'B', '\0' }, + { 'H', 'U', 'E', '\0' }, + { 'H', 'U', 'G', '\0' }, + { 'H', 'U', 'H', '\0' }, + { 'H', 'U', 'M', '\0' }, + { 'H', 'U', 'T', '\0' }, + { 'I', '\0', '\0', '\0' }, + { 'I', 'C', 'Y', '\0' }, + { 'I', 'D', 'A', '\0' }, + { 'I', 'F', '\0', '\0' }, + { 'I', 'K', 'E', '\0' }, + { 'I', 'L', 'L', '\0' }, + { 'I', 'N', 'K', '\0' }, + { 'I', 'N', 'N', '\0' }, + { 'I', 'O', '\0', '\0' }, + { 'I', 'O', 'N', '\0' }, + { 'I', 'Q', '\0', '\0' }, + { 'I', 'R', 'A', '\0' }, + { 'I', 'R', 'E', '\0' }, + { 'I', 'R', 'K', '\0' }, + { 'I', 'S', '\0', '\0' }, + { 'I', 'T', '\0', '\0' }, + { 'I', 'T', 'S', '\0' }, + { 'I', 'V', 'Y', '\0' }, + { 'J', 'A', 'B', '\0' }, + { 'J', 'A', 'G', '\0' }, + { 'J', 'A', 'M', '\0' }, + { 'J', 'A', 'N', '\0' }, + { 'J', 'A', 'R', '\0' }, + { 'J', 'A', 'W', '\0' }, + { 'J', 'A', 'Y', '\0' }, + { 'J', 'E', 'T', '\0' }, + { 'J', 'I', 'G', '\0' }, + { 'J', 'I', 'M', '\0' }, + { 'J', 'O', '\0', '\0' }, + { 'J', 'O', 'B', '\0' }, + { 'J', 'O', 'E', '\0' }, + { 'J', 'O', 'G', '\0' }, + { 'J', 'O', 'T', '\0' }, + { 'J', 'O', 'Y', '\0' }, + { 'J', 'U', 'G', '\0' }, + { 'J', 'U', 'T', '\0' }, + { 'K', 'A', 'Y', '\0' }, + { 'K', 'E', 'G', '\0' }, + { 'K', 'E', 'N', '\0' }, + { 'K', 'E', 'Y', '\0' }, + { 'K', 'I', 'D', '\0' }, + { 'K', 'I', 'M', '\0' }, + { 'K', 'I', 'N', '\0' }, + { 'K', 'I', 'T', '\0' }, + { 'L', 'A', '\0', '\0' }, + { 'L', 'A', 'B', '\0' }, + { 'L', 'A', 'C', '\0' }, + { 'L', 'A', 'D', '\0' }, + { 'L', 'A', 'G', '\0' }, + { 'L', 'A', 'M', '\0' }, + { 'L', 'A', 'P', '\0' }, + { 'L', 'A', 'W', '\0' }, + { 'L', 'A', 'Y', '\0' }, + { 'L', 'E', 'A', '\0' }, + { 'L', 'E', 'D', '\0' }, + { 'L', 'E', 'E', '\0' }, + { 'L', 'E', 'G', '\0' }, + { 'L', 'E', 'N', '\0' }, + { 'L', 'E', 'O', '\0' }, + { 'L', 'E', 'T', '\0' }, + { 'L', 'E', 'W', '\0' }, + { 'L', 'I', 'D', '\0' }, + { 'L', 'I', 'E', '\0' }, + { 'L', 'I', 'N', '\0' }, + { 'L', 'I', 'P', '\0' }, + { 'L', 'I', 'T', '\0' }, + { 'L', 'O', '\0', '\0' }, + { 'L', 'O', 'B', '\0' }, + { 'L', 'O', 'G', '\0' }, + { 'L', 'O', 'P', '\0' }, + { 'L', 'O', 'S', '\0' }, + { 'L', 'O', 'T', '\0' }, + { 'L', 'O', 'U', '\0' }, + { 'L', 'O', 'W', '\0' }, + { 'L', 'O', 'Y', '\0' }, + { 'L', 'U', 'G', '\0' }, + { 'L', 'Y', 'E', '\0' }, + { 'M', 'A', '\0', '\0' }, + { 'M', 'A', 'C', '\0' }, + { 'M', 'A', 'D', '\0' }, + { 'M', 'A', 'E', '\0' }, + { 'M', 'A', 'N', '\0' }, + { 'M', 'A', 'O', '\0' }, + { 'M', 'A', 'P', '\0' }, + { 'M', 'A', 'T', '\0' }, + { 'M', 'A', 'W', '\0' }, + { 'M', 'A', 'Y', '\0' }, + { 'M', 'E', '\0', '\0' }, + { 'M', 'E', 'G', '\0' }, + { 'M', 'E', 'L', '\0' }, + { 'M', 'E', 'N', '\0' }, + { 'M', 'E', 'T', '\0' }, + { 'M', 'E', 'W', '\0' }, + { 'M', 'I', 'D', '\0' }, + { 'M', 'I', 'N', '\0' }, + { 'M', 'I', 'T', '\0' }, + { 'M', 'O', 'B', '\0' }, + { 'M', 'O', 'D', '\0' }, + { 'M', 'O', 'E', '\0' }, + { 'M', 'O', 'O', '\0' }, + { 'M', 'O', 'P', '\0' }, + { 'M', 'O', 'S', '\0' }, + { 'M', 'O', 'T', '\0' }, + { 'M', 'O', 'W', '\0' }, + { 'M', 'U', 'D', '\0' }, + { 'M', 'U', 'G', '\0' }, + { 'M', 'U', 'M', '\0' }, + { 'M', 'Y', '\0', '\0' }, + { 'N', 'A', 'B', '\0' }, + { 'N', 'A', 'G', '\0' }, + { 'N', 'A', 'N', '\0' }, + { 'N', 'A', 'P', '\0' }, + { 'N', 'A', 'T', '\0' }, + { 'N', 'A', 'Y', '\0' }, + { 'N', 'E', '\0', '\0' }, + { 'N', 'E', 'D', '\0' }, + { 'N', 'E', 'E', '\0' }, + { 'N', 'E', 'T', '\0' }, + { 'N', 'E', 'W', '\0' }, + { 'N', 'I', 'B', '\0' }, + { 'N', 'I', 'L', '\0' }, + { 'N', 'I', 'P', '\0' }, + { 'N', 'I', 'T', '\0' }, + { 'N', 'O', '\0', '\0' }, + { 'N', 'O', 'B', '\0' }, + { 'N', 'O', 'D', '\0' }, + { 'N', 'O', 'N', '\0' }, + { 'N', 'O', 'R', '\0' }, + { 'N', 'O', 'T', '\0' }, + { 'N', 'O', 'V', '\0' }, + { 'N', 'O', 'W', '\0' }, + { 'N', 'U', '\0', '\0' }, + { 'N', 'U', 'N', '\0' }, + { 'N', 'U', 'T', '\0' }, + { 'O', '\0', '\0', '\0' }, + { 'O', 'A', 'F', '\0' }, + { 'O', 'A', 'K', '\0' }, + { 'O', 'A', 'R', '\0' }, + { 'O', 'A', 'T', '\0' }, + { 'O', 'D', 'D', '\0' }, + { 'O', 'D', 'E', '\0' }, + { 'O', 'F', '\0', '\0' }, + { 'O', 'F', 'F', '\0' }, + { 'O', 'F', 'T', '\0' }, + { 'O', 'H', '\0', '\0' }, + { 'O', 'I', 'L', '\0' }, + { 'O', 'K', '\0', '\0' }, + { 'O', 'L', 'D', '\0' }, + { 'O', 'N', '\0', '\0' }, + { 'O', 'N', 'E', '\0' }, + { 'O', 'R', '\0', '\0' }, + { 'O', 'R', 'B', '\0' }, + { 'O', 'R', 'E', '\0' }, + { 'O', 'R', 'R', '\0' }, + { 'O', 'S', '\0', '\0' }, + { 'O', 'T', 'T', '\0' }, + { 'O', 'U', 'R', '\0' }, + { 'O', 'U', 'T', '\0' }, + { 'O', 'V', 'A', '\0' }, + { 'O', 'W', '\0', '\0' }, + { 'O', 'W', 'E', '\0' }, + { 'O', 'W', 'L', '\0' }, + { 'O', 'W', 'N', '\0' }, + { 'O', 'X', '\0', '\0' }, + { 'P', 'A', '\0', '\0' }, + { 'P', 'A', 'D', '\0' }, + { 'P', 'A', 'L', '\0' }, + { 'P', 'A', 'M', '\0' }, + { 'P', 'A', 'N', '\0' }, + { 'P', 'A', 'P', '\0' }, + { 'P', 'A', 'R', '\0' }, + { 'P', 'A', 'T', '\0' }, + { 'P', 'A', 'W', '\0' }, + { 'P', 'A', 'Y', '\0' }, + { 'P', 'E', 'A', '\0' }, + { 'P', 'E', 'G', '\0' }, + { 'P', 'E', 'N', '\0' }, + { 'P', 'E', 'P', '\0' }, + { 'P', 'E', 'R', '\0' }, + { 'P', 'E', 'T', '\0' }, + { 'P', 'E', 'W', '\0' }, + { 'P', 'H', 'I', '\0' }, + { 'P', 'I', '\0', '\0' }, + { 'P', 'I', 'E', '\0' }, + { 'P', 'I', 'N', '\0' }, + { 'P', 'I', 'T', '\0' }, + { 'P', 'L', 'Y', '\0' }, + { 'P', 'O', '\0', '\0' }, + { 'P', 'O', 'D', '\0' }, + { 'P', 'O', 'E', '\0' }, + { 'P', 'O', 'P', '\0' }, + { 'P', 'O', 'T', '\0' }, + { 'P', 'O', 'W', '\0' }, + { 'P', 'R', 'O', '\0' }, + { 'P', 'R', 'Y', '\0' }, + { 'P', 'U', 'B', '\0' }, + { 'P', 'U', 'G', '\0' }, + { 'P', 'U', 'N', '\0' }, + { 'P', 'U', 'P', '\0' }, + { 'P', 'U', 'T', '\0' }, + { 'Q', 'U', 'O', '\0' }, + { 'R', 'A', 'G', '\0' }, + { 'R', 'A', 'M', '\0' }, + { 'R', 'A', 'N', '\0' }, + { 'R', 'A', 'P', '\0' }, + { 'R', 'A', 'T', '\0' }, + { 'R', 'A', 'W', '\0' }, + { 'R', 'A', 'Y', '\0' }, + { 'R', 'E', 'B', '\0' }, + { 'R', 'E', 'D', '\0' }, + { 'R', 'E', 'P', '\0' }, + { 'R', 'E', 'T', '\0' }, + { 'R', 'I', 'B', '\0' }, + { 'R', 'I', 'D', '\0' }, + { 'R', 'I', 'G', '\0' }, + { 'R', 'I', 'M', '\0' }, + { 'R', 'I', 'O', '\0' }, + { 'R', 'I', 'P', '\0' }, + { 'R', 'O', 'B', '\0' }, + { 'R', 'O', 'D', '\0' }, + { 'R', 'O', 'E', '\0' }, + { 'R', 'O', 'N', '\0' }, + { 'R', 'O', 'T', '\0' }, + { 'R', 'O', 'W', '\0' }, + { 'R', 'O', 'Y', '\0' }, + { 'R', 'U', 'B', '\0' }, + { 'R', 'U', 'E', '\0' }, + { 'R', 'U', 'G', '\0' }, + { 'R', 'U', 'M', '\0' }, + { 'R', 'U', 'N', '\0' }, + { 'R', 'Y', 'E', '\0' }, + { 'S', 'A', 'C', '\0' }, + { 'S', 'A', 'D', '\0' }, + { 'S', 'A', 'G', '\0' }, + { 'S', 'A', 'L', '\0' }, + { 'S', 'A', 'M', '\0' }, + { 'S', 'A', 'N', '\0' }, + { 'S', 'A', 'P', '\0' }, + { 'S', 'A', 'T', '\0' }, + { 'S', 'A', 'W', '\0' }, + { 'S', 'A', 'Y', '\0' }, + { 'S', 'E', 'A', '\0' }, + { 'S', 'E', 'C', '\0' }, + { 'S', 'E', 'E', '\0' }, + { 'S', 'E', 'N', '\0' }, + { 'S', 'E', 'T', '\0' }, + { 'S', 'E', 'W', '\0' }, + { 'S', 'H', 'E', '\0' }, + { 'S', 'H', 'Y', '\0' }, + { 'S', 'I', 'N', '\0' }, + { 'S', 'I', 'P', '\0' }, + { 'S', 'I', 'R', '\0' }, + { 'S', 'I', 'S', '\0' }, + { 'S', 'I', 'T', '\0' }, + { 'S', 'K', 'I', '\0' }, + { 'S', 'K', 'Y', '\0' }, + { 'S', 'L', 'Y', '\0' }, + { 'S', 'O', '\0', '\0' }, + { 'S', 'O', 'B', '\0' }, + { 'S', 'O', 'D', '\0' }, + { 'S', 'O', 'N', '\0' }, + { 'S', 'O', 'P', '\0' }, + { 'S', 'O', 'W', '\0' }, + { 'S', 'O', 'Y', '\0' }, + { 'S', 'P', 'A', '\0' }, + { 'S', 'P', 'Y', '\0' }, + { 'S', 'U', 'B', '\0' }, + { 'S', 'U', 'D', '\0' }, + { 'S', 'U', 'E', '\0' }, + { 'S', 'U', 'M', '\0' }, + { 'S', 'U', 'N', '\0' }, + { 'S', 'U', 'P', '\0' }, + { 'T', 'A', 'B', '\0' }, + { 'T', 'A', 'D', '\0' }, + { 'T', 'A', 'G', '\0' }, + { 'T', 'A', 'N', '\0' }, + { 'T', 'A', 'P', '\0' }, + { 'T', 'A', 'R', '\0' }, + { 'T', 'E', 'A', '\0' }, + { 'T', 'E', 'D', '\0' }, + { 'T', 'E', 'E', '\0' }, + { 'T', 'E', 'N', '\0' }, + { 'T', 'H', 'E', '\0' }, + { 'T', 'H', 'Y', '\0' }, + { 'T', 'I', 'C', '\0' }, + { 'T', 'I', 'E', '\0' }, + { 'T', 'I', 'M', '\0' }, + { 'T', 'I', 'N', '\0' }, + { 'T', 'I', 'P', '\0' }, + { 'T', 'O', '\0', '\0' }, + { 'T', 'O', 'E', '\0' }, + { 'T', 'O', 'G', '\0' }, + { 'T', 'O', 'M', '\0' }, + { 'T', 'O', 'N', '\0' }, + { 'T', 'O', 'O', '\0' }, + { 'T', 'O', 'P', '\0' }, + { 'T', 'O', 'W', '\0' }, + { 'T', 'O', 'Y', '\0' }, + { 'T', 'R', 'Y', '\0' }, + { 'T', 'U', 'B', '\0' }, + { 'T', 'U', 'G', '\0' }, + { 'T', 'U', 'M', '\0' }, + { 'T', 'U', 'N', '\0' }, + { 'T', 'W', 'O', '\0' }, + { 'U', 'N', '\0', '\0' }, + { 'U', 'P', '\0', '\0' }, + { 'U', 'S', '\0', '\0' }, + { 'U', 'S', 'E', '\0' }, + { 'V', 'A', 'N', '\0' }, + { 'V', 'A', 'T', '\0' }, + { 'V', 'E', 'T', '\0' }, + { 'V', 'I', 'E', '\0' }, + { 'W', 'A', 'D', '\0' }, + { 'W', 'A', 'G', '\0' }, + { 'W', 'A', 'R', '\0' }, + { 'W', 'A', 'S', '\0' }, + { 'W', 'A', 'Y', '\0' }, + { 'W', 'E', '\0', '\0' }, + { 'W', 'E', 'B', '\0' }, + { 'W', 'E', 'D', '\0' }, + { 'W', 'E', 'E', '\0' }, + { 'W', 'E', 'T', '\0' }, + { 'W', 'H', 'O', '\0' }, + { 'W', 'H', 'Y', '\0' }, + { 'W', 'I', 'N', '\0' }, + { 'W', 'I', 'T', '\0' }, + { 'W', 'O', 'K', '\0' }, + { 'W', 'O', 'N', '\0' }, + { 'W', 'O', 'O', '\0' }, + { 'W', 'O', 'W', '\0' }, + { 'W', 'R', 'Y', '\0' }, + { 'W', 'U', '\0', '\0' }, + { 'Y', 'A', 'M', '\0' }, + { 'Y', 'A', 'P', '\0' }, + { 'Y', 'A', 'W', '\0' }, + { 'Y', 'E', '\0', '\0' }, + { 'Y', 'E', 'A', '\0' }, + { 'Y', 'E', 'S', '\0' }, + { 'Y', 'E', 'T', '\0' }, + { 'Y', 'O', 'U', '\0' }, + { 'A', 'B', 'E', 'D' }, + { 'A', 'B', 'E', 'L' }, + { 'A', 'B', 'E', 'T' }, + { 'A', 'B', 'L', 'E' }, + { 'A', 'B', 'U', 'T' }, + { 'A', 'C', 'H', 'E' }, + { 'A', 'C', 'I', 'D' }, + { 'A', 'C', 'M', 'E' }, + { 'A', 'C', 'R', 'E' }, + { 'A', 'C', 'T', 'A' }, + { 'A', 'C', 'T', 'S' }, + { 'A', 'D', 'A', 'M' }, + { 'A', 'D', 'D', 'S' }, + { 'A', 'D', 'E', 'N' }, + { 'A', 'F', 'A', 'R' }, + { 'A', 'F', 'R', 'O' }, + { 'A', 'G', 'E', 'E' }, + { 'A', 'H', 'E', 'M' }, + { 'A', 'H', 'O', 'Y' }, + { 'A', 'I', 'D', 'A' }, + { 'A', 'I', 'D', 'E' }, + { 'A', 'I', 'D', 'S' }, + { 'A', 'I', 'R', 'Y' }, + { 'A', 'J', 'A', 'R' }, + { 'A', 'K', 'I', 'N' }, + { 'A', 'L', 'A', 'N' }, + { 'A', 'L', 'E', 'C' }, + { 'A', 'L', 'G', 'A' }, + { 'A', 'L', 'I', 'A' }, + { 'A', 'L', 'L', 'Y' }, + { 'A', 'L', 'M', 'A' }, + { 'A', 'L', 'O', 'E' }, + { 'A', 'L', 'S', 'O' }, + { 'A', 'L', 'T', 'O' }, + { 'A', 'L', 'U', 'M' }, + { 'A', 'L', 'V', 'A' }, + { 'A', 'M', 'E', 'N' }, + { 'A', 'M', 'E', 'S' }, + { 'A', 'M', 'I', 'D' }, + { 'A', 'M', 'M', 'O' }, + { 'A', 'M', 'O', 'K' }, + { 'A', 'M', 'O', 'S' }, + { 'A', 'M', 'R', 'A' }, + { 'A', 'N', 'D', 'Y' }, + { 'A', 'N', 'E', 'W' }, + { 'A', 'N', 'N', 'A' }, + { 'A', 'N', 'N', 'E' }, + { 'A', 'N', 'T', 'E' }, + { 'A', 'N', 'T', 'I' }, + { 'A', 'Q', 'U', 'A' }, + { 'A', 'R', 'A', 'B' }, + { 'A', 'R', 'C', 'H' }, + { 'A', 'R', 'E', 'A' }, + { 'A', 'R', 'G', 'O' }, + { 'A', 'R', 'I', 'D' }, + { 'A', 'R', 'M', 'Y' }, + { 'A', 'R', 'T', 'S' }, + { 'A', 'R', 'T', 'Y' }, + { 'A', 'S', 'I', 'A' }, + { 'A', 'S', 'K', 'S' }, + { 'A', 'T', 'O', 'M' }, + { 'A', 'U', 'N', 'T' }, + { 'A', 'U', 'R', 'A' }, + { 'A', 'U', 'T', 'O' }, + { 'A', 'V', 'E', 'R' }, + { 'A', 'V', 'I', 'D' }, + { 'A', 'V', 'I', 'S' }, + { 'A', 'V', 'O', 'N' }, + { 'A', 'V', 'O', 'W' }, + { 'A', 'W', 'A', 'Y' }, + { 'A', 'W', 'R', 'Y' }, + { 'B', 'A', 'B', 'E' }, + { 'B', 'A', 'B', 'Y' }, + { 'B', 'A', 'C', 'H' }, + { 'B', 'A', 'C', 'K' }, + { 'B', 'A', 'D', 'E' }, + { 'B', 'A', 'I', 'L' }, + { 'B', 'A', 'I', 'T' }, + { 'B', 'A', 'K', 'E' }, + { 'B', 'A', 'L', 'D' }, + { 'B', 'A', 'L', 'E' }, + { 'B', 'A', 'L', 'I' }, + { 'B', 'A', 'L', 'K' }, + { 'B', 'A', 'L', 'L' }, + { 'B', 'A', 'L', 'M' }, + { 'B', 'A', 'N', 'D' }, + { 'B', 'A', 'N', 'E' }, + { 'B', 'A', 'N', 'G' }, + { 'B', 'A', 'N', 'K' }, + { 'B', 'A', 'R', 'B' }, + { 'B', 'A', 'R', 'D' }, + { 'B', 'A', 'R', 'E' }, + { 'B', 'A', 'R', 'K' }, + { 'B', 'A', 'R', 'N' }, + { 'B', 'A', 'R', 'R' }, + { 'B', 'A', 'S', 'E' }, + { 'B', 'A', 'S', 'H' }, + { 'B', 'A', 'S', 'K' }, + { 'B', 'A', 'S', 'S' }, + { 'B', 'A', 'T', 'E' }, + { 'B', 'A', 'T', 'H' }, + { 'B', 'A', 'W', 'D' }, + { 'B', 'A', 'W', 'L' }, + { 'B', 'E', 'A', 'D' }, + { 'B', 'E', 'A', 'K' }, + { 'B', 'E', 'A', 'M' }, + { 'B', 'E', 'A', 'N' }, + { 'B', 'E', 'A', 'R' }, + { 'B', 'E', 'A', 'T' }, + { 'B', 'E', 'A', 'U' }, + { 'B', 'E', 'C', 'K' }, + { 'B', 'E', 'E', 'F' }, + { 'B', 'E', 'E', 'N' }, + { 'B', 'E', 'E', 'R' }, + { 'B', 'E', 'E', 'T' }, + { 'B', 'E', 'L', 'A' }, + { 'B', 'E', 'L', 'L' }, + { 'B', 'E', 'L', 'T' }, + { 'B', 'E', 'N', 'D' }, + { 'B', 'E', 'N', 'T' }, + { 'B', 'E', 'R', 'G' }, + { 'B', 'E', 'R', 'N' }, + { 'B', 'E', 'R', 'T' }, + { 'B', 'E', 'S', 'S' }, + { 'B', 'E', 'S', 'T' }, + { 'B', 'E', 'T', 'A' }, + { 'B', 'E', 'T', 'H' }, + { 'B', 'H', 'O', 'Y' }, + { 'B', 'I', 'A', 'S' }, + { 'B', 'I', 'D', 'E' }, + { 'B', 'I', 'E', 'N' }, + { 'B', 'I', 'L', 'E' }, + { 'B', 'I', 'L', 'K' }, + { 'B', 'I', 'L', 'L' }, + { 'B', 'I', 'N', 'D' }, + { 'B', 'I', 'N', 'G' }, + { 'B', 'I', 'R', 'D' }, + { 'B', 'I', 'T', 'E' }, + { 'B', 'I', 'T', 'S' }, + { 'B', 'L', 'A', 'B' }, + { 'B', 'L', 'A', 'T' }, + { 'B', 'L', 'E', 'D' }, + { 'B', 'L', 'E', 'W' }, + { 'B', 'L', 'O', 'B' }, + { 'B', 'L', 'O', 'C' }, + { 'B', 'L', 'O', 'T' }, + { 'B', 'L', 'O', 'W' }, + { 'B', 'L', 'U', 'E' }, + { 'B', 'L', 'U', 'M' }, + { 'B', 'L', 'U', 'R' }, + { 'B', 'O', 'A', 'R' }, + { 'B', 'O', 'A', 'T' }, + { 'B', 'O', 'C', 'A' }, + { 'B', 'O', 'C', 'K' }, + { 'B', 'O', 'D', 'E' }, + { 'B', 'O', 'D', 'Y' }, + { 'B', 'O', 'G', 'Y' }, + { 'B', 'O', 'H', 'R' }, + { 'B', 'O', 'I', 'L' }, + { 'B', 'O', 'L', 'D' }, + { 'B', 'O', 'L', 'O' }, + { 'B', 'O', 'L', 'T' }, + { 'B', 'O', 'M', 'B' }, + { 'B', 'O', 'N', 'A' }, + { 'B', 'O', 'N', 'D' }, + { 'B', 'O', 'N', 'E' }, + { 'B', 'O', 'N', 'G' }, + { 'B', 'O', 'N', 'N' }, + { 'B', 'O', 'N', 'Y' }, + { 'B', 'O', 'O', 'K' }, + { 'B', 'O', 'O', 'M' }, + { 'B', 'O', 'O', 'N' }, + { 'B', 'O', 'O', 'T' }, + { 'B', 'O', 'R', 'E' }, + { 'B', 'O', 'R', 'G' }, + { 'B', 'O', 'R', 'N' }, + { 'B', 'O', 'S', 'E' }, + { 'B', 'O', 'S', 'S' }, + { 'B', 'O', 'T', 'H' }, + { 'B', 'O', 'U', 'T' }, + { 'B', 'O', 'W', 'L' }, + { 'B', 'O', 'Y', 'D' }, + { 'B', 'R', 'A', 'D' }, + { 'B', 'R', 'A', 'E' }, + { 'B', 'R', 'A', 'G' }, + { 'B', 'R', 'A', 'N' }, + { 'B', 'R', 'A', 'Y' }, + { 'B', 'R', 'E', 'D' }, + { 'B', 'R', 'E', 'W' }, + { 'B', 'R', 'I', 'G' }, + { 'B', 'R', 'I', 'M' }, + { 'B', 'R', 'O', 'W' }, + { 'B', 'U', 'C', 'K' }, + { 'B', 'U', 'D', 'D' }, + { 'B', 'U', 'F', 'F' }, + { 'B', 'U', 'L', 'B' }, + { 'B', 'U', 'L', 'K' }, + { 'B', 'U', 'L', 'L' }, + { 'B', 'U', 'N', 'K' }, + { 'B', 'U', 'N', 'T' }, + { 'B', 'U', 'O', 'Y' }, + { 'B', 'U', 'R', 'G' }, + { 'B', 'U', 'R', 'L' }, + { 'B', 'U', 'R', 'N' }, + { 'B', 'U', 'R', 'R' }, + { 'B', 'U', 'R', 'T' }, + { 'B', 'U', 'R', 'Y' }, + { 'B', 'U', 'S', 'H' }, + { 'B', 'U', 'S', 'S' }, + { 'B', 'U', 'S', 'T' }, + { 'B', 'U', 'S', 'Y' }, + { 'B', 'Y', 'T', 'E' }, + { 'C', 'A', 'D', 'Y' }, + { 'C', 'A', 'F', 'E' }, + { 'C', 'A', 'G', 'E' }, + { 'C', 'A', 'I', 'N' }, + { 'C', 'A', 'K', 'E' }, + { 'C', 'A', 'L', 'F' }, + { 'C', 'A', 'L', 'L' }, + { 'C', 'A', 'L', 'M' }, + { 'C', 'A', 'M', 'E' }, + { 'C', 'A', 'N', 'E' }, + { 'C', 'A', 'N', 'T' }, + { 'C', 'A', 'R', 'D' }, + { 'C', 'A', 'R', 'E' }, + { 'C', 'A', 'R', 'L' }, + { 'C', 'A', 'R', 'R' }, + { 'C', 'A', 'R', 'T' }, + { 'C', 'A', 'S', 'E' }, + { 'C', 'A', 'S', 'H' }, + { 'C', 'A', 'S', 'K' }, + { 'C', 'A', 'S', 'T' }, + { 'C', 'A', 'V', 'E' }, + { 'C', 'E', 'I', 'L' }, + { 'C', 'E', 'L', 'L' }, + { 'C', 'E', 'N', 'T' }, + { 'C', 'E', 'R', 'N' }, + { 'C', 'H', 'A', 'D' }, + { 'C', 'H', 'A', 'R' }, + { 'C', 'H', 'A', 'T' }, + { 'C', 'H', 'A', 'W' }, + { 'C', 'H', 'E', 'F' }, + { 'C', 'H', 'E', 'N' }, + { 'C', 'H', 'E', 'W' }, + { 'C', 'H', 'I', 'C' }, + { 'C', 'H', 'I', 'N' }, + { 'C', 'H', 'O', 'U' }, + { 'C', 'H', 'O', 'W' }, + { 'C', 'H', 'U', 'B' }, + { 'C', 'H', 'U', 'G' }, + { 'C', 'H', 'U', 'M' }, + { 'C', 'I', 'T', 'E' }, + { 'C', 'I', 'T', 'Y' }, + { 'C', 'L', 'A', 'D' }, + { 'C', 'L', 'A', 'M' }, + { 'C', 'L', 'A', 'N' }, + { 'C', 'L', 'A', 'W' }, + { 'C', 'L', 'A', 'Y' }, + { 'C', 'L', 'O', 'D' }, + { 'C', 'L', 'O', 'G' }, + { 'C', 'L', 'O', 'T' }, + { 'C', 'L', 'U', 'B' }, + { 'C', 'L', 'U', 'E' }, + { 'C', 'O', 'A', 'L' }, + { 'C', 'O', 'A', 'T' }, + { 'C', 'O', 'C', 'A' }, + { 'C', 'O', 'C', 'K' }, + { 'C', 'O', 'C', 'O' }, + { 'C', 'O', 'D', 'A' }, + { 'C', 'O', 'D', 'E' }, + { 'C', 'O', 'D', 'Y' }, + { 'C', 'O', 'E', 'D' }, + { 'C', 'O', 'I', 'L' }, + { 'C', 'O', 'I', 'N' }, + { 'C', 'O', 'K', 'E' }, + { 'C', 'O', 'L', 'A' }, + { 'C', 'O', 'L', 'D' }, + { 'C', 'O', 'L', 'T' }, + { 'C', 'O', 'M', 'A' }, + { 'C', 'O', 'M', 'B' }, + { 'C', 'O', 'M', 'E' }, + { 'C', 'O', 'O', 'K' }, + { 'C', 'O', 'O', 'L' }, + { 'C', 'O', 'O', 'N' }, + { 'C', 'O', 'O', 'T' }, + { 'C', 'O', 'R', 'D' }, + { 'C', 'O', 'R', 'E' }, + { 'C', 'O', 'R', 'K' }, + { 'C', 'O', 'R', 'N' }, + { 'C', 'O', 'S', 'T' }, + { 'C', 'O', 'V', 'E' }, + { 'C', 'O', 'W', 'L' }, + { 'C', 'R', 'A', 'B' }, + { 'C', 'R', 'A', 'G' }, + { 'C', 'R', 'A', 'M' }, + { 'C', 'R', 'A', 'Y' }, + { 'C', 'R', 'E', 'W' }, + { 'C', 'R', 'I', 'B' }, + { 'C', 'R', 'O', 'W' }, + { 'C', 'R', 'U', 'D' }, + { 'C', 'U', 'B', 'A' }, + { 'C', 'U', 'B', 'E' }, + { 'C', 'U', 'F', 'F' }, + { 'C', 'U', 'L', 'L' }, + { 'C', 'U', 'L', 'T' }, + { 'C', 'U', 'N', 'Y' }, + { 'C', 'U', 'R', 'B' }, + { 'C', 'U', 'R', 'D' }, + { 'C', 'U', 'R', 'E' }, + { 'C', 'U', 'R', 'L' }, + { 'C', 'U', 'R', 'T' }, + { 'C', 'U', 'T', 'S' }, + { 'D', 'A', 'D', 'E' }, + { 'D', 'A', 'L', 'E' }, + { 'D', 'A', 'M', 'E' }, + { 'D', 'A', 'N', 'A' }, + { 'D', 'A', 'N', 'E' }, + { 'D', 'A', 'N', 'G' }, + { 'D', 'A', 'N', 'K' }, + { 'D', 'A', 'R', 'E' }, + { 'D', 'A', 'R', 'K' }, + { 'D', 'A', 'R', 'N' }, + { 'D', 'A', 'R', 'T' }, + { 'D', 'A', 'S', 'H' }, + { 'D', 'A', 'T', 'A' }, + { 'D', 'A', 'T', 'E' }, + { 'D', 'A', 'V', 'E' }, + { 'D', 'A', 'V', 'Y' }, + { 'D', 'A', 'W', 'N' }, + { 'D', 'A', 'Y', 'S' }, + { 'D', 'E', 'A', 'D' }, + { 'D', 'E', 'A', 'F' }, + { 'D', 'E', 'A', 'L' }, + { 'D', 'E', 'A', 'N' }, + { 'D', 'E', 'A', 'R' }, + { 'D', 'E', 'B', 'T' }, + { 'D', 'E', 'C', 'K' }, + { 'D', 'E', 'E', 'D' }, + { 'D', 'E', 'E', 'M' }, + { 'D', 'E', 'E', 'R' }, + { 'D', 'E', 'F', 'T' }, + { 'D', 'E', 'F', 'Y' }, + { 'D', 'E', 'L', 'L' }, + { 'D', 'E', 'N', 'T' }, + { 'D', 'E', 'N', 'Y' }, + { 'D', 'E', 'S', 'K' }, + { 'D', 'I', 'A', 'L' }, + { 'D', 'I', 'C', 'E' }, + { 'D', 'I', 'E', 'D' }, + { 'D', 'I', 'E', 'T' }, + { 'D', 'I', 'M', 'E' }, + { 'D', 'I', 'N', 'E' }, + { 'D', 'I', 'N', 'G' }, + { 'D', 'I', 'N', 'T' }, + { 'D', 'I', 'R', 'E' }, + { 'D', 'I', 'R', 'T' }, + { 'D', 'I', 'S', 'C' }, + { 'D', 'I', 'S', 'H' }, + { 'D', 'I', 'S', 'K' }, + { 'D', 'I', 'V', 'E' }, + { 'D', 'O', 'C', 'K' }, + { 'D', 'O', 'E', 'S' }, + { 'D', 'O', 'L', 'E' }, + { 'D', 'O', 'L', 'L' }, + { 'D', 'O', 'L', 'T' }, + { 'D', 'O', 'M', 'E' }, + { 'D', 'O', 'N', 'E' }, + { 'D', 'O', 'O', 'M' }, + { 'D', 'O', 'O', 'R' }, + { 'D', 'O', 'R', 'A' }, + { 'D', 'O', 'S', 'E' }, + { 'D', 'O', 'T', 'E' }, + { 'D', 'O', 'U', 'G' }, + { 'D', 'O', 'U', 'R' }, + { 'D', 'O', 'V', 'E' }, + { 'D', 'O', 'W', 'N' }, + { 'D', 'R', 'A', 'B' }, + { 'D', 'R', 'A', 'G' }, + { 'D', 'R', 'A', 'M' }, + { 'D', 'R', 'A', 'W' }, + { 'D', 'R', 'E', 'W' }, + { 'D', 'R', 'U', 'B' }, + { 'D', 'R', 'U', 'G' }, + { 'D', 'R', 'U', 'M' }, + { 'D', 'U', 'A', 'L' }, + { 'D', 'U', 'C', 'K' }, + { 'D', 'U', 'C', 'T' }, + { 'D', 'U', 'E', 'L' }, + { 'D', 'U', 'E', 'T' }, + { 'D', 'U', 'K', 'E' }, + { 'D', 'U', 'L', 'L' }, + { 'D', 'U', 'M', 'B' }, + { 'D', 'U', 'N', 'E' }, + { 'D', 'U', 'N', 'K' }, + { 'D', 'U', 'S', 'K' }, + { 'D', 'U', 'S', 'T' }, + { 'D', 'U', 'T', 'Y' }, + { 'E', 'A', 'C', 'H' }, + { 'E', 'A', 'R', 'L' }, + { 'E', 'A', 'R', 'N' }, + { 'E', 'A', 'S', 'E' }, + { 'E', 'A', 'S', 'T' }, + { 'E', 'A', 'S', 'Y' }, + { 'E', 'B', 'E', 'N' }, + { 'E', 'C', 'H', 'O' }, + { 'E', 'D', 'D', 'Y' }, + { 'E', 'D', 'E', 'N' }, + { 'E', 'D', 'G', 'E' }, + { 'E', 'D', 'G', 'Y' }, + { 'E', 'D', 'I', 'T' }, + { 'E', 'D', 'N', 'A' }, + { 'E', 'G', 'A', 'N' }, + { 'E', 'L', 'A', 'N' }, + { 'E', 'L', 'B', 'A' }, + { 'E', 'L', 'L', 'A' }, + { 'E', 'L', 'S', 'E' }, + { 'E', 'M', 'I', 'L' }, + { 'E', 'M', 'I', 'T' }, + { 'E', 'M', 'M', 'A' }, + { 'E', 'N', 'D', 'S' }, + { 'E', 'R', 'I', 'C' }, + { 'E', 'R', 'O', 'S' }, + { 'E', 'V', 'E', 'N' }, + { 'E', 'V', 'E', 'R' }, + { 'E', 'V', 'I', 'L' }, + { 'E', 'Y', 'E', 'D' }, + { 'F', 'A', 'C', 'E' }, + { 'F', 'A', 'C', 'T' }, + { 'F', 'A', 'D', 'E' }, + { 'F', 'A', 'I', 'L' }, + { 'F', 'A', 'I', 'N' }, + { 'F', 'A', 'I', 'R' }, + { 'F', 'A', 'K', 'E' }, + { 'F', 'A', 'L', 'L' }, + { 'F', 'A', 'M', 'E' }, + { 'F', 'A', 'N', 'G' }, + { 'F', 'A', 'R', 'M' }, + { 'F', 'A', 'S', 'T' }, + { 'F', 'A', 'T', 'E' }, + { 'F', 'A', 'W', 'N' }, + { 'F', 'E', 'A', 'R' }, + { 'F', 'E', 'A', 'T' }, + { 'F', 'E', 'E', 'D' }, + { 'F', 'E', 'E', 'L' }, + { 'F', 'E', 'E', 'T' }, + { 'F', 'E', 'L', 'L' }, + { 'F', 'E', 'L', 'T' }, + { 'F', 'E', 'N', 'D' }, + { 'F', 'E', 'R', 'N' }, + { 'F', 'E', 'S', 'T' }, + { 'F', 'E', 'U', 'D' }, + { 'F', 'I', 'E', 'F' }, + { 'F', 'I', 'G', 'S' }, + { 'F', 'I', 'L', 'E' }, + { 'F', 'I', 'L', 'L' }, + { 'F', 'I', 'L', 'M' }, + { 'F', 'I', 'N', 'D' }, + { 'F', 'I', 'N', 'E' }, + { 'F', 'I', 'N', 'K' }, + { 'F', 'I', 'R', 'E' }, + { 'F', 'I', 'R', 'M' }, + { 'F', 'I', 'S', 'H' }, + { 'F', 'I', 'S', 'K' }, + { 'F', 'I', 'S', 'T' }, + { 'F', 'I', 'T', 'S' }, + { 'F', 'I', 'V', 'E' }, + { 'F', 'L', 'A', 'G' }, + { 'F', 'L', 'A', 'K' }, + { 'F', 'L', 'A', 'M' }, + { 'F', 'L', 'A', 'T' }, + { 'F', 'L', 'A', 'W' }, + { 'F', 'L', 'E', 'A' }, + { 'F', 'L', 'E', 'D' }, + { 'F', 'L', 'E', 'W' }, + { 'F', 'L', 'I', 'T' }, + { 'F', 'L', 'O', 'C' }, + { 'F', 'L', 'O', 'G' }, + { 'F', 'L', 'O', 'W' }, + { 'F', 'L', 'U', 'B' }, + { 'F', 'L', 'U', 'E' }, + { 'F', 'O', 'A', 'L' }, + { 'F', 'O', 'A', 'M' }, + { 'F', 'O', 'G', 'Y' }, + { 'F', 'O', 'I', 'L' }, + { 'F', 'O', 'L', 'D' }, + { 'F', 'O', 'L', 'K' }, + { 'F', 'O', 'N', 'D' }, + { 'F', 'O', 'N', 'T' }, + { 'F', 'O', 'O', 'D' }, + { 'F', 'O', 'O', 'L' }, + { 'F', 'O', 'O', 'T' }, + { 'F', 'O', 'R', 'D' }, + { 'F', 'O', 'R', 'E' }, + { 'F', 'O', 'R', 'K' }, + { 'F', 'O', 'R', 'M' }, + { 'F', 'O', 'R', 'T' }, + { 'F', 'O', 'S', 'S' }, + { 'F', 'O', 'U', 'L' }, + { 'F', 'O', 'U', 'R' }, + { 'F', 'O', 'W', 'L' }, + { 'F', 'R', 'A', 'U' }, + { 'F', 'R', 'A', 'Y' }, + { 'F', 'R', 'E', 'D' }, + { 'F', 'R', 'E', 'E' }, + { 'F', 'R', 'E', 'T' }, + { 'F', 'R', 'E', 'Y' }, + { 'F', 'R', 'O', 'G' }, + { 'F', 'R', 'O', 'M' }, + { 'F', 'U', 'E', 'L' }, + { 'F', 'U', 'L', 'L' }, + { 'F', 'U', 'M', 'E' }, + { 'F', 'U', 'N', 'D' }, + { 'F', 'U', 'N', 'K' }, + { 'F', 'U', 'R', 'Y' }, + { 'F', 'U', 'S', 'E' }, + { 'F', 'U', 'S', 'S' }, + { 'G', 'A', 'F', 'F' }, + { 'G', 'A', 'G', 'E' }, + { 'G', 'A', 'I', 'L' }, + { 'G', 'A', 'I', 'N' }, + { 'G', 'A', 'I', 'T' }, + { 'G', 'A', 'L', 'A' }, + { 'G', 'A', 'L', 'E' }, + { 'G', 'A', 'L', 'L' }, + { 'G', 'A', 'L', 'T' }, + { 'G', 'A', 'M', 'E' }, + { 'G', 'A', 'N', 'G' }, + { 'G', 'A', 'R', 'B' }, + { 'G', 'A', 'R', 'Y' }, + { 'G', 'A', 'S', 'H' }, + { 'G', 'A', 'T', 'E' }, + { 'G', 'A', 'U', 'L' }, + { 'G', 'A', 'U', 'R' }, + { 'G', 'A', 'V', 'E' }, + { 'G', 'A', 'W', 'K' }, + { 'G', 'E', 'A', 'R' }, + { 'G', 'E', 'L', 'D' }, + { 'G', 'E', 'N', 'E' }, + { 'G', 'E', 'N', 'T' }, + { 'G', 'E', 'R', 'M' }, + { 'G', 'E', 'T', 'S' }, + { 'G', 'I', 'B', 'E' }, + { 'G', 'I', 'F', 'T' }, + { 'G', 'I', 'L', 'D' }, + { 'G', 'I', 'L', 'L' }, + { 'G', 'I', 'L', 'T' }, + { 'G', 'I', 'N', 'A' }, + { 'G', 'I', 'R', 'D' }, + { 'G', 'I', 'R', 'L' }, + { 'G', 'I', 'S', 'T' }, + { 'G', 'I', 'V', 'E' }, + { 'G', 'L', 'A', 'D' }, + { 'G', 'L', 'E', 'E' }, + { 'G', 'L', 'E', 'N' }, + { 'G', 'L', 'I', 'B' }, + { 'G', 'L', 'O', 'B' }, + { 'G', 'L', 'O', 'M' }, + { 'G', 'L', 'O', 'W' }, + { 'G', 'L', 'U', 'E' }, + { 'G', 'L', 'U', 'M' }, + { 'G', 'L', 'U', 'T' }, + { 'G', 'O', 'A', 'D' }, + { 'G', 'O', 'A', 'L' }, + { 'G', 'O', 'A', 'T' }, + { 'G', 'O', 'E', 'R' }, + { 'G', 'O', 'E', 'S' }, + { 'G', 'O', 'L', 'D' }, + { 'G', 'O', 'L', 'F' }, + { 'G', 'O', 'N', 'E' }, + { 'G', 'O', 'N', 'G' }, + { 'G', 'O', 'O', 'D' }, + { 'G', 'O', 'O', 'F' }, + { 'G', 'O', 'R', 'E' }, + { 'G', 'O', 'R', 'Y' }, + { 'G', 'O', 'S', 'H' }, + { 'G', 'O', 'U', 'T' }, + { 'G', 'O', 'W', 'N' }, + { 'G', 'R', 'A', 'B' }, + { 'G', 'R', 'A', 'D' }, + { 'G', 'R', 'A', 'Y' }, + { 'G', 'R', 'E', 'G' }, + { 'G', 'R', 'E', 'W' }, + { 'G', 'R', 'E', 'Y' }, + { 'G', 'R', 'I', 'D' }, + { 'G', 'R', 'I', 'M' }, + { 'G', 'R', 'I', 'N' }, + { 'G', 'R', 'I', 'T' }, + { 'G', 'R', 'O', 'W' }, + { 'G', 'R', 'U', 'B' }, + { 'G', 'U', 'L', 'F' }, + { 'G', 'U', 'L', 'L' }, + { 'G', 'U', 'N', 'K' }, + { 'G', 'U', 'R', 'U' }, + { 'G', 'U', 'S', 'H' }, + { 'G', 'U', 'S', 'T' }, + { 'G', 'W', 'E', 'N' }, + { 'G', 'W', 'Y', 'N' }, + { 'H', 'A', 'A', 'G' }, + { 'H', 'A', 'A', 'S' }, + { 'H', 'A', 'C', 'K' }, + { 'H', 'A', 'I', 'L' }, + { 'H', 'A', 'I', 'R' }, + { 'H', 'A', 'L', 'E' }, + { 'H', 'A', 'L', 'F' }, + { 'H', 'A', 'L', 'L' }, + { 'H', 'A', 'L', 'O' }, + { 'H', 'A', 'L', 'T' }, + { 'H', 'A', 'N', 'D' }, + { 'H', 'A', 'N', 'G' }, + { 'H', 'A', 'N', 'K' }, + { 'H', 'A', 'N', 'S' }, + { 'H', 'A', 'R', 'D' }, + { 'H', 'A', 'R', 'K' }, + { 'H', 'A', 'R', 'M' }, + { 'H', 'A', 'R', 'T' }, + { 'H', 'A', 'S', 'H' }, + { 'H', 'A', 'S', 'T' }, + { 'H', 'A', 'T', 'E' }, + { 'H', 'A', 'T', 'H' }, + { 'H', 'A', 'U', 'L' }, + { 'H', 'A', 'V', 'E' }, + { 'H', 'A', 'W', 'K' }, + { 'H', 'A', 'Y', 'S' }, + { 'H', 'E', 'A', 'D' }, + { 'H', 'E', 'A', 'L' }, + { 'H', 'E', 'A', 'R' }, + { 'H', 'E', 'A', 'T' }, + { 'H', 'E', 'B', 'E' }, + { 'H', 'E', 'C', 'K' }, + { 'H', 'E', 'E', 'D' }, + { 'H', 'E', 'E', 'L' }, + { 'H', 'E', 'F', 'T' }, + { 'H', 'E', 'L', 'D' }, + { 'H', 'E', 'L', 'L' }, + { 'H', 'E', 'L', 'M' }, + { 'H', 'E', 'R', 'B' }, + { 'H', 'E', 'R', 'D' }, + { 'H', 'E', 'R', 'E' }, + { 'H', 'E', 'R', 'O' }, + { 'H', 'E', 'R', 'S' }, + { 'H', 'E', 'S', 'S' }, + { 'H', 'E', 'W', 'N' }, + { 'H', 'I', 'C', 'K' }, + { 'H', 'I', 'D', 'E' }, + { 'H', 'I', 'G', 'H' }, + { 'H', 'I', 'K', 'E' }, + { 'H', 'I', 'L', 'L' }, + { 'H', 'I', 'L', 'T' }, + { 'H', 'I', 'N', 'D' }, + { 'H', 'I', 'N', 'T' }, + { 'H', 'I', 'R', 'E' }, + { 'H', 'I', 'S', 'S' }, + { 'H', 'I', 'V', 'E' }, + { 'H', 'O', 'B', 'O' }, + { 'H', 'O', 'C', 'K' }, + { 'H', 'O', 'F', 'F' }, + { 'H', 'O', 'L', 'D' }, + { 'H', 'O', 'L', 'E' }, + { 'H', 'O', 'L', 'M' }, + { 'H', 'O', 'L', 'T' }, + { 'H', 'O', 'M', 'E' }, + { 'H', 'O', 'N', 'E' }, + { 'H', 'O', 'N', 'K' }, + { 'H', 'O', 'O', 'D' }, + { 'H', 'O', 'O', 'F' }, + { 'H', 'O', 'O', 'K' }, + { 'H', 'O', 'O', 'T' }, + { 'H', 'O', 'R', 'N' }, + { 'H', 'O', 'S', 'E' }, + { 'H', 'O', 'S', 'T' }, + { 'H', 'O', 'U', 'R' }, + { 'H', 'O', 'V', 'E' }, + { 'H', 'O', 'W', 'E' }, + { 'H', 'O', 'W', 'L' }, + { 'H', 'O', 'Y', 'T' }, + { 'H', 'U', 'C', 'K' }, + { 'H', 'U', 'E', 'D' }, + { 'H', 'U', 'F', 'F' }, + { 'H', 'U', 'G', 'E' }, + { 'H', 'U', 'G', 'H' }, + { 'H', 'U', 'G', 'O' }, + { 'H', 'U', 'L', 'K' }, + { 'H', 'U', 'L', 'L' }, + { 'H', 'U', 'N', 'K' }, + { 'H', 'U', 'N', 'T' }, + { 'H', 'U', 'R', 'D' }, + { 'H', 'U', 'R', 'L' }, + { 'H', 'U', 'R', 'T' }, + { 'H', 'U', 'S', 'H' }, + { 'H', 'Y', 'D', 'E' }, + { 'H', 'Y', 'M', 'N' }, + { 'I', 'B', 'I', 'S' }, + { 'I', 'C', 'O', 'N' }, + { 'I', 'D', 'E', 'A' }, + { 'I', 'D', 'L', 'E' }, + { 'I', 'F', 'F', 'Y' }, + { 'I', 'N', 'C', 'A' }, + { 'I', 'N', 'C', 'H' }, + { 'I', 'N', 'T', 'O' }, + { 'I', 'O', 'N', 'S' }, + { 'I', 'O', 'T', 'A' }, + { 'I', 'O', 'W', 'A' }, + { 'I', 'R', 'I', 'S' }, + { 'I', 'R', 'M', 'A' }, + { 'I', 'R', 'O', 'N' }, + { 'I', 'S', 'L', 'E' }, + { 'I', 'T', 'C', 'H' }, + { 'I', 'T', 'E', 'M' }, + { 'I', 'V', 'A', 'N' }, + { 'J', 'A', 'C', 'K' }, + { 'J', 'A', 'D', 'E' }, + { 'J', 'A', 'I', 'L' }, + { 'J', 'A', 'K', 'E' }, + { 'J', 'A', 'N', 'E' }, + { 'J', 'A', 'V', 'A' }, + { 'J', 'E', 'A', 'N' }, + { 'J', 'E', 'F', 'F' }, + { 'J', 'E', 'R', 'K' }, + { 'J', 'E', 'S', 'S' }, + { 'J', 'E', 'S', 'T' }, + { 'J', 'I', 'B', 'E' }, + { 'J', 'I', 'L', 'L' }, + { 'J', 'I', 'L', 'T' }, + { 'J', 'I', 'V', 'E' }, + { 'J', 'O', 'A', 'N' }, + { 'J', 'O', 'B', 'S' }, + { 'J', 'O', 'C', 'K' }, + { 'J', 'O', 'E', 'L' }, + { 'J', 'O', 'E', 'Y' }, + { 'J', 'O', 'H', 'N' }, + { 'J', 'O', 'I', 'N' }, + { 'J', 'O', 'K', 'E' }, + { 'J', 'O', 'L', 'T' }, + { 'J', 'O', 'V', 'E' }, + { 'J', 'U', 'D', 'D' }, + { 'J', 'U', 'D', 'E' }, + { 'J', 'U', 'D', 'O' }, + { 'J', 'U', 'D', 'Y' }, + { 'J', 'U', 'J', 'U' }, + { 'J', 'U', 'K', 'E' }, + { 'J', 'U', 'L', 'Y' }, + { 'J', 'U', 'N', 'E' }, + { 'J', 'U', 'N', 'K' }, + { 'J', 'U', 'N', 'O' }, + { 'J', 'U', 'R', 'Y' }, + { 'J', 'U', 'S', 'T' }, + { 'J', 'U', 'T', 'E' }, + { 'K', 'A', 'H', 'N' }, + { 'K', 'A', 'L', 'E' }, + { 'K', 'A', 'N', 'E' }, + { 'K', 'A', 'N', 'T' }, + { 'K', 'A', 'R', 'L' }, + { 'K', 'A', 'T', 'E' }, + { 'K', 'E', 'E', 'L' }, + { 'K', 'E', 'E', 'N' }, + { 'K', 'E', 'N', 'O' }, + { 'K', 'E', 'N', 'T' }, + { 'K', 'E', 'R', 'N' }, + { 'K', 'E', 'R', 'R' }, + { 'K', 'E', 'Y', 'S' }, + { 'K', 'I', 'C', 'K' }, + { 'K', 'I', 'L', 'L' }, + { 'K', 'I', 'N', 'D' }, + { 'K', 'I', 'N', 'G' }, + { 'K', 'I', 'R', 'K' }, + { 'K', 'I', 'S', 'S' }, + { 'K', 'I', 'T', 'E' }, + { 'K', 'L', 'A', 'N' }, + { 'K', 'N', 'E', 'E' }, + { 'K', 'N', 'E', 'W' }, + { 'K', 'N', 'I', 'T' }, + { 'K', 'N', 'O', 'B' }, + { 'K', 'N', 'O', 'T' }, + { 'K', 'N', 'O', 'W' }, + { 'K', 'O', 'C', 'H' }, + { 'K', 'O', 'N', 'G' }, + { 'K', 'U', 'D', 'O' }, + { 'K', 'U', 'R', 'D' }, + { 'K', 'U', 'R', 'T' }, + { 'K', 'Y', 'L', 'E' }, + { 'L', 'A', 'C', 'E' }, + { 'L', 'A', 'C', 'K' }, + { 'L', 'A', 'C', 'Y' }, + { 'L', 'A', 'D', 'Y' }, + { 'L', 'A', 'I', 'D' }, + { 'L', 'A', 'I', 'N' }, + { 'L', 'A', 'I', 'R' }, + { 'L', 'A', 'K', 'E' }, + { 'L', 'A', 'M', 'B' }, + { 'L', 'A', 'M', 'E' }, + { 'L', 'A', 'N', 'D' }, + { 'L', 'A', 'N', 'E' }, + { 'L', 'A', 'N', 'G' }, + { 'L', 'A', 'R', 'D' }, + { 'L', 'A', 'R', 'K' }, + { 'L', 'A', 'S', 'S' }, + { 'L', 'A', 'S', 'T' }, + { 'L', 'A', 'T', 'E' }, + { 'L', 'A', 'U', 'D' }, + { 'L', 'A', 'V', 'A' }, + { 'L', 'A', 'W', 'N' }, + { 'L', 'A', 'W', 'S' }, + { 'L', 'A', 'Y', 'S' }, + { 'L', 'E', 'A', 'D' }, + { 'L', 'E', 'A', 'F' }, + { 'L', 'E', 'A', 'K' }, + { 'L', 'E', 'A', 'N' }, + { 'L', 'E', 'A', 'R' }, + { 'L', 'E', 'E', 'K' }, + { 'L', 'E', 'E', 'R' }, + { 'L', 'E', 'F', 'T' }, + { 'L', 'E', 'N', 'D' }, + { 'L', 'E', 'N', 'S' }, + { 'L', 'E', 'N', 'T' }, + { 'L', 'E', 'O', 'N' }, + { 'L', 'E', 'S', 'K' }, + { 'L', 'E', 'S', 'S' }, + { 'L', 'E', 'S', 'T' }, + { 'L', 'E', 'T', 'S' }, + { 'L', 'I', 'A', 'R' }, + { 'L', 'I', 'C', 'E' }, + { 'L', 'I', 'C', 'K' }, + { 'L', 'I', 'E', 'D' }, + { 'L', 'I', 'E', 'N' }, + { 'L', 'I', 'E', 'S' }, + { 'L', 'I', 'E', 'U' }, + { 'L', 'I', 'F', 'E' }, + { 'L', 'I', 'F', 'T' }, + { 'L', 'I', 'K', 'E' }, + { 'L', 'I', 'L', 'A' }, + { 'L', 'I', 'L', 'T' }, + { 'L', 'I', 'L', 'Y' }, + { 'L', 'I', 'M', 'A' }, + { 'L', 'I', 'M', 'B' }, + { 'L', 'I', 'M', 'E' }, + { 'L', 'I', 'N', 'D' }, + { 'L', 'I', 'N', 'E' }, + { 'L', 'I', 'N', 'K' }, + { 'L', 'I', 'N', 'T' }, + { 'L', 'I', 'O', 'N' }, + { 'L', 'I', 'S', 'A' }, + { 'L', 'I', 'S', 'T' }, + { 'L', 'I', 'V', 'E' }, + { 'L', 'O', 'A', 'D' }, + { 'L', 'O', 'A', 'F' }, + { 'L', 'O', 'A', 'M' }, + { 'L', 'O', 'A', 'N' }, + { 'L', 'O', 'C', 'K' }, + { 'L', 'O', 'F', 'T' }, + { 'L', 'O', 'G', 'E' }, + { 'L', 'O', 'I', 'S' }, + { 'L', 'O', 'L', 'A' }, + { 'L', 'O', 'N', 'E' }, + { 'L', 'O', 'N', 'G' }, + { 'L', 'O', 'O', 'K' }, + { 'L', 'O', 'O', 'N' }, + { 'L', 'O', 'O', 'T' }, + { 'L', 'O', 'R', 'D' }, + { 'L', 'O', 'R', 'E' }, + { 'L', 'O', 'S', 'E' }, + { 'L', 'O', 'S', 'S' }, + { 'L', 'O', 'S', 'T' }, + { 'L', 'O', 'U', 'D' }, + { 'L', 'O', 'V', 'E' }, + { 'L', 'O', 'W', 'E' }, + { 'L', 'U', 'C', 'K' }, + { 'L', 'U', 'C', 'Y' }, + { 'L', 'U', 'G', 'E' }, + { 'L', 'U', 'K', 'E' }, + { 'L', 'U', 'L', 'U' }, + { 'L', 'U', 'N', 'D' }, + { 'L', 'U', 'N', 'G' }, + { 'L', 'U', 'R', 'A' }, + { 'L', 'U', 'R', 'E' }, + { 'L', 'U', 'R', 'K' }, + { 'L', 'U', 'S', 'H' }, + { 'L', 'U', 'S', 'T' }, + { 'L', 'Y', 'L', 'E' }, + { 'L', 'Y', 'N', 'N' }, + { 'L', 'Y', 'O', 'N' }, + { 'L', 'Y', 'R', 'A' }, + { 'M', 'A', 'C', 'E' }, + { 'M', 'A', 'D', 'E' }, + { 'M', 'A', 'G', 'I' }, + { 'M', 'A', 'I', 'D' }, + { 'M', 'A', 'I', 'L' }, + { 'M', 'A', 'I', 'N' }, + { 'M', 'A', 'K', 'E' }, + { 'M', 'A', 'L', 'E' }, + { 'M', 'A', 'L', 'I' }, + { 'M', 'A', 'L', 'L' }, + { 'M', 'A', 'L', 'T' }, + { 'M', 'A', 'N', 'A' }, + { 'M', 'A', 'N', 'N' }, + { 'M', 'A', 'N', 'Y' }, + { 'M', 'A', 'R', 'C' }, + { 'M', 'A', 'R', 'E' }, + { 'M', 'A', 'R', 'K' }, + { 'M', 'A', 'R', 'S' }, + { 'M', 'A', 'R', 'T' }, + { 'M', 'A', 'R', 'Y' }, + { 'M', 'A', 'S', 'H' }, + { 'M', 'A', 'S', 'K' }, + { 'M', 'A', 'S', 'S' }, + { 'M', 'A', 'S', 'T' }, + { 'M', 'A', 'T', 'E' }, + { 'M', 'A', 'T', 'H' }, + { 'M', 'A', 'U', 'L' }, + { 'M', 'A', 'Y', 'O' }, + { 'M', 'E', 'A', 'D' }, + { 'M', 'E', 'A', 'L' }, + { 'M', 'E', 'A', 'N' }, + { 'M', 'E', 'A', 'T' }, + { 'M', 'E', 'E', 'K' }, + { 'M', 'E', 'E', 'T' }, + { 'M', 'E', 'L', 'D' }, + { 'M', 'E', 'L', 'T' }, + { 'M', 'E', 'M', 'O' }, + { 'M', 'E', 'N', 'D' }, + { 'M', 'E', 'N', 'U' }, + { 'M', 'E', 'R', 'T' }, + { 'M', 'E', 'S', 'H' }, + { 'M', 'E', 'S', 'S' }, + { 'M', 'I', 'C', 'E' }, + { 'M', 'I', 'K', 'E' }, + { 'M', 'I', 'L', 'D' }, + { 'M', 'I', 'L', 'E' }, + { 'M', 'I', 'L', 'K' }, + { 'M', 'I', 'L', 'L' }, + { 'M', 'I', 'L', 'T' }, + { 'M', 'I', 'M', 'I' }, + { 'M', 'I', 'N', 'D' }, + { 'M', 'I', 'N', 'E' }, + { 'M', 'I', 'N', 'I' }, + { 'M', 'I', 'N', 'K' }, + { 'M', 'I', 'N', 'T' }, + { 'M', 'I', 'R', 'E' }, + { 'M', 'I', 'S', 'S' }, + { 'M', 'I', 'S', 'T' }, + { 'M', 'I', 'T', 'E' }, + { 'M', 'I', 'T', 'T' }, + { 'M', 'O', 'A', 'N' }, + { 'M', 'O', 'A', 'T' }, + { 'M', 'O', 'C', 'K' }, + { 'M', 'O', 'D', 'E' }, + { 'M', 'O', 'L', 'D' }, + { 'M', 'O', 'L', 'E' }, + { 'M', 'O', 'L', 'L' }, + { 'M', 'O', 'L', 'T' }, + { 'M', 'O', 'N', 'A' }, + { 'M', 'O', 'N', 'K' }, + { 'M', 'O', 'N', 'T' }, + { 'M', 'O', 'O', 'D' }, + { 'M', 'O', 'O', 'N' }, + { 'M', 'O', 'O', 'R' }, + { 'M', 'O', 'O', 'T' }, + { 'M', 'O', 'R', 'E' }, + { 'M', 'O', 'R', 'N' }, + { 'M', 'O', 'R', 'T' }, + { 'M', 'O', 'S', 'S' }, + { 'M', 'O', 'S', 'T' }, + { 'M', 'O', 'T', 'H' }, + { 'M', 'O', 'V', 'E' }, + { 'M', 'U', 'C', 'H' }, + { 'M', 'U', 'C', 'K' }, + { 'M', 'U', 'D', 'D' }, + { 'M', 'U', 'F', 'F' }, + { 'M', 'U', 'L', 'E' }, + { 'M', 'U', 'L', 'L' }, + { 'M', 'U', 'R', 'K' }, + { 'M', 'U', 'S', 'H' }, + { 'M', 'U', 'S', 'T' }, + { 'M', 'U', 'T', 'E' }, + { 'M', 'U', 'T', 'T' }, + { 'M', 'Y', 'R', 'A' }, + { 'M', 'Y', 'T', 'H' }, + { 'N', 'A', 'G', 'Y' }, + { 'N', 'A', 'I', 'L' }, + { 'N', 'A', 'I', 'R' }, + { 'N', 'A', 'M', 'E' }, + { 'N', 'A', 'R', 'Y' }, + { 'N', 'A', 'S', 'H' }, + { 'N', 'A', 'V', 'E' }, + { 'N', 'A', 'V', 'Y' }, + { 'N', 'E', 'A', 'L' }, + { 'N', 'E', 'A', 'R' }, + { 'N', 'E', 'A', 'T' }, + { 'N', 'E', 'C', 'K' }, + { 'N', 'E', 'E', 'D' }, + { 'N', 'E', 'I', 'L' }, + { 'N', 'E', 'L', 'L' }, + { 'N', 'E', 'O', 'N' }, + { 'N', 'E', 'R', 'O' }, + { 'N', 'E', 'S', 'S' }, + { 'N', 'E', 'S', 'T' }, + { 'N', 'E', 'W', 'S' }, + { 'N', 'E', 'W', 'T' }, + { 'N', 'I', 'B', 'S' }, + { 'N', 'I', 'C', 'E' }, + { 'N', 'I', 'C', 'K' }, + { 'N', 'I', 'L', 'E' }, + { 'N', 'I', 'N', 'A' }, + { 'N', 'I', 'N', 'E' }, + { 'N', 'O', 'A', 'H' }, + { 'N', 'O', 'D', 'E' }, + { 'N', 'O', 'E', 'L' }, + { 'N', 'O', 'L', 'L' }, + { 'N', 'O', 'N', 'E' }, + { 'N', 'O', 'O', 'K' }, + { 'N', 'O', 'O', 'N' }, + { 'N', 'O', 'R', 'M' }, + { 'N', 'O', 'S', 'E' }, + { 'N', 'O', 'T', 'E' }, + { 'N', 'O', 'U', 'N' }, + { 'N', 'O', 'V', 'A' }, + { 'N', 'U', 'D', 'E' }, + { 'N', 'U', 'L', 'L' }, + { 'N', 'U', 'M', 'B' }, + { 'O', 'A', 'T', 'H' }, + { 'O', 'B', 'E', 'Y' }, + { 'O', 'B', 'O', 'E' }, + { 'O', 'D', 'I', 'N' }, + { 'O', 'H', 'I', 'O' }, + { 'O', 'I', 'L', 'Y' }, + { 'O', 'I', 'N', 'T' }, + { 'O', 'K', 'A', 'Y' }, + { 'O', 'L', 'A', 'F' }, + { 'O', 'L', 'D', 'Y' }, + { 'O', 'L', 'G', 'A' }, + { 'O', 'L', 'I', 'N' }, + { 'O', 'M', 'A', 'N' }, + { 'O', 'M', 'E', 'N' }, + { 'O', 'M', 'I', 'T' }, + { 'O', 'N', 'C', 'E' }, + { 'O', 'N', 'E', 'S' }, + { 'O', 'N', 'L', 'Y' }, + { 'O', 'N', 'T', 'O' }, + { 'O', 'N', 'U', 'S' }, + { 'O', 'R', 'A', 'L' }, + { 'O', 'R', 'G', 'Y' }, + { 'O', 'S', 'L', 'O' }, + { 'O', 'T', 'I', 'S' }, + { 'O', 'T', 'T', 'O' }, + { 'O', 'U', 'C', 'H' }, + { 'O', 'U', 'S', 'T' }, + { 'O', 'U', 'T', 'S' }, + { 'O', 'V', 'A', 'L' }, + { 'O', 'V', 'E', 'N' }, + { 'O', 'V', 'E', 'R' }, + { 'O', 'W', 'L', 'Y' }, + { 'O', 'W', 'N', 'S' }, + { 'Q', 'U', 'A', 'D' }, + { 'Q', 'U', 'I', 'T' }, + { 'Q', 'U', 'O', 'D' }, + { 'R', 'A', 'C', 'E' }, + { 'R', 'A', 'C', 'K' }, + { 'R', 'A', 'C', 'Y' }, + { 'R', 'A', 'F', 'T' }, + { 'R', 'A', 'G', 'E' }, + { 'R', 'A', 'I', 'D' }, + { 'R', 'A', 'I', 'L' }, + { 'R', 'A', 'I', 'N' }, + { 'R', 'A', 'K', 'E' }, + { 'R', 'A', 'N', 'K' }, + { 'R', 'A', 'N', 'T' }, + { 'R', 'A', 'R', 'E' }, + { 'R', 'A', 'S', 'H' }, + { 'R', 'A', 'T', 'E' }, + { 'R', 'A', 'V', 'E' }, + { 'R', 'A', 'Y', 'S' }, + { 'R', 'E', 'A', 'D' }, + { 'R', 'E', 'A', 'L' }, + { 'R', 'E', 'A', 'M' }, + { 'R', 'E', 'A', 'R' }, + { 'R', 'E', 'C', 'K' }, + { 'R', 'E', 'E', 'D' }, + { 'R', 'E', 'E', 'F' }, + { 'R', 'E', 'E', 'K' }, + { 'R', 'E', 'E', 'L' }, + { 'R', 'E', 'I', 'D' }, + { 'R', 'E', 'I', 'N' }, + { 'R', 'E', 'N', 'A' }, + { 'R', 'E', 'N', 'D' }, + { 'R', 'E', 'N', 'T' }, + { 'R', 'E', 'S', 'T' }, + { 'R', 'I', 'C', 'E' }, + { 'R', 'I', 'C', 'H' }, + { 'R', 'I', 'C', 'K' }, + { 'R', 'I', 'D', 'E' }, + { 'R', 'I', 'F', 'T' }, + { 'R', 'I', 'L', 'L' }, + { 'R', 'I', 'M', 'E' }, + { 'R', 'I', 'N', 'G' }, + { 'R', 'I', 'N', 'K' }, + { 'R', 'I', 'S', 'E' }, + { 'R', 'I', 'S', 'K' }, + { 'R', 'I', 'T', 'E' }, + { 'R', 'O', 'A', 'D' }, + { 'R', 'O', 'A', 'M' }, + { 'R', 'O', 'A', 'R' }, + { 'R', 'O', 'B', 'E' }, + { 'R', 'O', 'C', 'K' }, + { 'R', 'O', 'D', 'E' }, + { 'R', 'O', 'I', 'L' }, + { 'R', 'O', 'L', 'L' }, + { 'R', 'O', 'M', 'E' }, + { 'R', 'O', 'O', 'D' }, + { 'R', 'O', 'O', 'F' }, + { 'R', 'O', 'O', 'K' }, + { 'R', 'O', 'O', 'M' }, + { 'R', 'O', 'O', 'T' }, + { 'R', 'O', 'S', 'A' }, + { 'R', 'O', 'S', 'E' }, + { 'R', 'O', 'S', 'S' }, + { 'R', 'O', 'S', 'Y' }, + { 'R', 'O', 'T', 'H' }, + { 'R', 'O', 'U', 'T' }, + { 'R', 'O', 'V', 'E' }, + { 'R', 'O', 'W', 'E' }, + { 'R', 'O', 'W', 'S' }, + { 'R', 'U', 'B', 'E' }, + { 'R', 'U', 'B', 'Y' }, + { 'R', 'U', 'D', 'E' }, + { 'R', 'U', 'D', 'Y' }, + { 'R', 'U', 'I', 'N' }, + { 'R', 'U', 'L', 'E' }, + { 'R', 'U', 'N', 'G' }, + { 'R', 'U', 'N', 'S' }, + { 'R', 'U', 'N', 'T' }, + { 'R', 'U', 'S', 'E' }, + { 'R', 'U', 'S', 'H' }, + { 'R', 'U', 'S', 'K' }, + { 'R', 'U', 'S', 'S' }, + { 'R', 'U', 'S', 'T' }, + { 'R', 'U', 'T', 'H' }, + { 'S', 'A', 'C', 'K' }, + { 'S', 'A', 'F', 'E' }, + { 'S', 'A', 'G', 'E' }, + { 'S', 'A', 'I', 'D' }, + { 'S', 'A', 'I', 'L' }, + { 'S', 'A', 'L', 'E' }, + { 'S', 'A', 'L', 'K' }, + { 'S', 'A', 'L', 'T' }, + { 'S', 'A', 'M', 'E' }, + { 'S', 'A', 'N', 'D' }, + { 'S', 'A', 'N', 'E' }, + { 'S', 'A', 'N', 'G' }, + { 'S', 'A', 'N', 'K' }, + { 'S', 'A', 'R', 'A' }, + { 'S', 'A', 'U', 'L' }, + { 'S', 'A', 'V', 'E' }, + { 'S', 'A', 'Y', 'S' }, + { 'S', 'C', 'A', 'N' }, + { 'S', 'C', 'A', 'R' }, + { 'S', 'C', 'A', 'T' }, + { 'S', 'C', 'O', 'T' }, + { 'S', 'E', 'A', 'L' }, + { 'S', 'E', 'A', 'M' }, + { 'S', 'E', 'A', 'R' }, + { 'S', 'E', 'A', 'T' }, + { 'S', 'E', 'E', 'D' }, + { 'S', 'E', 'E', 'K' }, + { 'S', 'E', 'E', 'M' }, + { 'S', 'E', 'E', 'N' }, + { 'S', 'E', 'E', 'S' }, + { 'S', 'E', 'L', 'F' }, + { 'S', 'E', 'L', 'L' }, + { 'S', 'E', 'N', 'D' }, + { 'S', 'E', 'N', 'T' }, + { 'S', 'E', 'T', 'S' }, + { 'S', 'E', 'W', 'N' }, + { 'S', 'H', 'A', 'G' }, + { 'S', 'H', 'A', 'M' }, + { 'S', 'H', 'A', 'W' }, + { 'S', 'H', 'A', 'Y' }, + { 'S', 'H', 'E', 'D' }, + { 'S', 'H', 'I', 'M' }, + { 'S', 'H', 'I', 'N' }, + { 'S', 'H', 'O', 'D' }, + { 'S', 'H', 'O', 'E' }, + { 'S', 'H', 'O', 'T' }, + { 'S', 'H', 'O', 'W' }, + { 'S', 'H', 'U', 'N' }, + { 'S', 'H', 'U', 'T' }, + { 'S', 'I', 'C', 'K' }, + { 'S', 'I', 'D', 'E' }, + { 'S', 'I', 'F', 'T' }, + { 'S', 'I', 'G', 'H' }, + { 'S', 'I', 'G', 'N' }, + { 'S', 'I', 'L', 'K' }, + { 'S', 'I', 'L', 'L' }, + { 'S', 'I', 'L', 'O' }, + { 'S', 'I', 'L', 'T' }, + { 'S', 'I', 'N', 'E' }, + { 'S', 'I', 'N', 'G' }, + { 'S', 'I', 'N', 'K' }, + { 'S', 'I', 'R', 'E' }, + { 'S', 'I', 'T', 'E' }, + { 'S', 'I', 'T', 'S' }, + { 'S', 'I', 'T', 'U' }, + { 'S', 'K', 'A', 'T' }, + { 'S', 'K', 'E', 'W' }, + { 'S', 'K', 'I', 'D' }, + { 'S', 'K', 'I', 'M' }, + { 'S', 'K', 'I', 'N' }, + { 'S', 'K', 'I', 'T' }, + { 'S', 'L', 'A', 'B' }, + { 'S', 'L', 'A', 'M' }, + { 'S', 'L', 'A', 'T' }, + { 'S', 'L', 'A', 'Y' }, + { 'S', 'L', 'E', 'D' }, + { 'S', 'L', 'E', 'W' }, + { 'S', 'L', 'I', 'D' }, + { 'S', 'L', 'I', 'M' }, + { 'S', 'L', 'I', 'T' }, + { 'S', 'L', 'O', 'B' }, + { 'S', 'L', 'O', 'G' }, + { 'S', 'L', 'O', 'T' }, + { 'S', 'L', 'O', 'W' }, + { 'S', 'L', 'U', 'G' }, + { 'S', 'L', 'U', 'M' }, + { 'S', 'L', 'U', 'R' }, + { 'S', 'M', 'O', 'G' }, + { 'S', 'M', 'U', 'G' }, + { 'S', 'N', 'A', 'G' }, + { 'S', 'N', 'O', 'B' }, + { 'S', 'N', 'O', 'W' }, + { 'S', 'N', 'U', 'B' }, + { 'S', 'N', 'U', 'G' }, + { 'S', 'O', 'A', 'K' }, + { 'S', 'O', 'A', 'R' }, + { 'S', 'O', 'C', 'K' }, + { 'S', 'O', 'D', 'A' }, + { 'S', 'O', 'F', 'A' }, + { 'S', 'O', 'F', 'T' }, + { 'S', 'O', 'I', 'L' }, + { 'S', 'O', 'L', 'D' }, + { 'S', 'O', 'M', 'E' }, + { 'S', 'O', 'N', 'G' }, + { 'S', 'O', 'O', 'N' }, + { 'S', 'O', 'O', 'T' }, + { 'S', 'O', 'R', 'E' }, + { 'S', 'O', 'R', 'T' }, + { 'S', 'O', 'U', 'L' }, + { 'S', 'O', 'U', 'R' }, + { 'S', 'O', 'W', 'N' }, + { 'S', 'T', 'A', 'B' }, + { 'S', 'T', 'A', 'G' }, + { 'S', 'T', 'A', 'N' }, + { 'S', 'T', 'A', 'R' }, + { 'S', 'T', 'A', 'Y' }, + { 'S', 'T', 'E', 'M' }, + { 'S', 'T', 'E', 'W' }, + { 'S', 'T', 'I', 'R' }, + { 'S', 'T', 'O', 'W' }, + { 'S', 'T', 'U', 'B' }, + { 'S', 'T', 'U', 'N' }, + { 'S', 'U', 'C', 'H' }, + { 'S', 'U', 'D', 'S' }, + { 'S', 'U', 'I', 'T' }, + { 'S', 'U', 'L', 'K' }, + { 'S', 'U', 'M', 'S' }, + { 'S', 'U', 'N', 'G' }, + { 'S', 'U', 'N', 'K' }, + { 'S', 'U', 'R', 'E' }, + { 'S', 'U', 'R', 'F' }, + { 'S', 'W', 'A', 'B' }, + { 'S', 'W', 'A', 'G' }, + { 'S', 'W', 'A', 'M' }, + { 'S', 'W', 'A', 'N' }, + { 'S', 'W', 'A', 'T' }, + { 'S', 'W', 'A', 'Y' }, + { 'S', 'W', 'I', 'M' }, + { 'S', 'W', 'U', 'M' }, + { 'T', 'A', 'C', 'K' }, + { 'T', 'A', 'C', 'T' }, + { 'T', 'A', 'I', 'L' }, + { 'T', 'A', 'K', 'E' }, + { 'T', 'A', 'L', 'E' }, + { 'T', 'A', 'L', 'K' }, + { 'T', 'A', 'L', 'L' }, + { 'T', 'A', 'N', 'K' }, + { 'T', 'A', 'S', 'K' }, + { 'T', 'A', 'T', 'E' }, + { 'T', 'A', 'U', 'T' }, + { 'T', 'E', 'A', 'L' }, + { 'T', 'E', 'A', 'M' }, + { 'T', 'E', 'A', 'R' }, + { 'T', 'E', 'C', 'H' }, + { 'T', 'E', 'E', 'M' }, + { 'T', 'E', 'E', 'N' }, + { 'T', 'E', 'E', 'T' }, + { 'T', 'E', 'L', 'L' }, + { 'T', 'E', 'N', 'D' }, + { 'T', 'E', 'N', 'T' }, + { 'T', 'E', 'R', 'M' }, + { 'T', 'E', 'R', 'N' }, + { 'T', 'E', 'S', 'S' }, + { 'T', 'E', 'S', 'T' }, + { 'T', 'H', 'A', 'N' }, + { 'T', 'H', 'A', 'T' }, + { 'T', 'H', 'E', 'E' }, + { 'T', 'H', 'E', 'M' }, + { 'T', 'H', 'E', 'N' }, + { 'T', 'H', 'E', 'Y' }, + { 'T', 'H', 'I', 'N' }, + { 'T', 'H', 'I', 'S' }, + { 'T', 'H', 'U', 'D' }, + { 'T', 'H', 'U', 'G' }, + { 'T', 'I', 'C', 'K' }, + { 'T', 'I', 'D', 'E' }, + { 'T', 'I', 'D', 'Y' }, + { 'T', 'I', 'E', 'D' }, + { 'T', 'I', 'E', 'R' }, + { 'T', 'I', 'L', 'E' }, + { 'T', 'I', 'L', 'L' }, + { 'T', 'I', 'L', 'T' }, + { 'T', 'I', 'M', 'E' }, + { 'T', 'I', 'N', 'A' }, + { 'T', 'I', 'N', 'E' }, + { 'T', 'I', 'N', 'T' }, + { 'T', 'I', 'N', 'Y' }, + { 'T', 'I', 'R', 'E' }, + { 'T', 'O', 'A', 'D' }, + { 'T', 'O', 'G', 'O' }, + { 'T', 'O', 'I', 'L' }, + { 'T', 'O', 'L', 'D' }, + { 'T', 'O', 'L', 'L' }, + { 'T', 'O', 'N', 'E' }, + { 'T', 'O', 'N', 'G' }, + { 'T', 'O', 'N', 'Y' }, + { 'T', 'O', 'O', 'K' }, + { 'T', 'O', 'O', 'L' }, + { 'T', 'O', 'O', 'T' }, + { 'T', 'O', 'R', 'E' }, + { 'T', 'O', 'R', 'N' }, + { 'T', 'O', 'T', 'E' }, + { 'T', 'O', 'U', 'R' }, + { 'T', 'O', 'U', 'T' }, + { 'T', 'O', 'W', 'N' }, + { 'T', 'R', 'A', 'G' }, + { 'T', 'R', 'A', 'M' }, + { 'T', 'R', 'A', 'Y' }, + { 'T', 'R', 'E', 'E' }, + { 'T', 'R', 'E', 'K' }, + { 'T', 'R', 'I', 'G' }, + { 'T', 'R', 'I', 'M' }, + { 'T', 'R', 'I', 'O' }, + { 'T', 'R', 'O', 'D' }, + { 'T', 'R', 'O', 'T' }, + { 'T', 'R', 'O', 'Y' }, + { 'T', 'R', 'U', 'E' }, + { 'T', 'U', 'B', 'A' }, + { 'T', 'U', 'B', 'E' }, + { 'T', 'U', 'C', 'K' }, + { 'T', 'U', 'F', 'T' }, + { 'T', 'U', 'N', 'A' }, + { 'T', 'U', 'N', 'E' }, + { 'T', 'U', 'N', 'G' }, + { 'T', 'U', 'R', 'F' }, + { 'T', 'U', 'R', 'N' }, + { 'T', 'U', 'S', 'K' }, + { 'T', 'W', 'I', 'G' }, + { 'T', 'W', 'I', 'N' }, + { 'T', 'W', 'I', 'T' }, + { 'U', 'L', 'A', 'N' }, + { 'U', 'N', 'I', 'T' }, + { 'U', 'R', 'G', 'E' }, + { 'U', 'S', 'E', 'D' }, + { 'U', 'S', 'E', 'R' }, + { 'U', 'S', 'E', 'S' }, + { 'U', 'T', 'A', 'H' }, + { 'V', 'A', 'I', 'L' }, + { 'V', 'A', 'I', 'N' }, + { 'V', 'A', 'L', 'E' }, + { 'V', 'A', 'R', 'Y' }, + { 'V', 'A', 'S', 'E' }, + { 'V', 'A', 'S', 'T' }, + { 'V', 'E', 'A', 'L' }, + { 'V', 'E', 'D', 'A' }, + { 'V', 'E', 'I', 'L' }, + { 'V', 'E', 'I', 'N' }, + { 'V', 'E', 'N', 'D' }, + { 'V', 'E', 'N', 'T' }, + { 'V', 'E', 'R', 'B' }, + { 'V', 'E', 'R', 'Y' }, + { 'V', 'E', 'T', 'O' }, + { 'V', 'I', 'C', 'E' }, + { 'V', 'I', 'E', 'W' }, + { 'V', 'I', 'N', 'E' }, + { 'V', 'I', 'S', 'E' }, + { 'V', 'O', 'I', 'D' }, + { 'V', 'O', 'L', 'T' }, + { 'V', 'O', 'T', 'E' }, + { 'W', 'A', 'C', 'K' }, + { 'W', 'A', 'D', 'E' }, + { 'W', 'A', 'G', 'E' }, + { 'W', 'A', 'I', 'L' }, + { 'W', 'A', 'I', 'T' }, + { 'W', 'A', 'K', 'E' }, + { 'W', 'A', 'L', 'E' }, + { 'W', 'A', 'L', 'K' }, + { 'W', 'A', 'L', 'L' }, + { 'W', 'A', 'L', 'T' }, + { 'W', 'A', 'N', 'D' }, + { 'W', 'A', 'N', 'E' }, + { 'W', 'A', 'N', 'G' }, + { 'W', 'A', 'N', 'T' }, + { 'W', 'A', 'R', 'D' }, + { 'W', 'A', 'R', 'M' }, + { 'W', 'A', 'R', 'N' }, + { 'W', 'A', 'R', 'T' }, + { 'W', 'A', 'S', 'H' }, + { 'W', 'A', 'S', 'T' }, + { 'W', 'A', 'T', 'S' }, + { 'W', 'A', 'T', 'T' }, + { 'W', 'A', 'V', 'E' }, + { 'W', 'A', 'V', 'Y' }, + { 'W', 'A', 'Y', 'S' }, + { 'W', 'E', 'A', 'K' }, + { 'W', 'E', 'A', 'L' }, + { 'W', 'E', 'A', 'N' }, + { 'W', 'E', 'A', 'R' }, + { 'W', 'E', 'E', 'D' }, + { 'W', 'E', 'E', 'K' }, + { 'W', 'E', 'I', 'R' }, + { 'W', 'E', 'L', 'D' }, + { 'W', 'E', 'L', 'L' }, + { 'W', 'E', 'L', 'T' }, + { 'W', 'E', 'N', 'T' }, + { 'W', 'E', 'R', 'E' }, + { 'W', 'E', 'R', 'T' }, + { 'W', 'E', 'S', 'T' }, + { 'W', 'H', 'A', 'M' }, + { 'W', 'H', 'A', 'T' }, + { 'W', 'H', 'E', 'E' }, + { 'W', 'H', 'E', 'N' }, + { 'W', 'H', 'E', 'T' }, + { 'W', 'H', 'O', 'A' }, + { 'W', 'H', 'O', 'M' }, + { 'W', 'I', 'C', 'K' }, + { 'W', 'I', 'F', 'E' }, + { 'W', 'I', 'L', 'D' }, + { 'W', 'I', 'L', 'L' }, + { 'W', 'I', 'N', 'D' }, + { 'W', 'I', 'N', 'E' }, + { 'W', 'I', 'N', 'G' }, + { 'W', 'I', 'N', 'K' }, + { 'W', 'I', 'N', 'O' }, + { 'W', 'I', 'R', 'E' }, + { 'W', 'I', 'S', 'E' }, + { 'W', 'I', 'S', 'H' }, + { 'W', 'I', 'T', 'H' }, + { 'W', 'O', 'L', 'F' }, + { 'W', 'O', 'N', 'T' }, + { 'W', 'O', 'O', 'D' }, + { 'W', 'O', 'O', 'L' }, + { 'W', 'O', 'R', 'D' }, + { 'W', 'O', 'R', 'E' }, + { 'W', 'O', 'R', 'K' }, + { 'W', 'O', 'R', 'M' }, + { 'W', 'O', 'R', 'N' }, + { 'W', 'O', 'V', 'E' }, + { 'W', 'R', 'I', 'T' }, + { 'W', 'Y', 'N', 'N' }, + { 'Y', 'A', 'L', 'E' }, + { 'Y', 'A', 'N', 'G' }, + { 'Y', 'A', 'N', 'K' }, + { 'Y', 'A', 'R', 'D' }, + { 'Y', 'A', 'R', 'N' }, + { 'Y', 'A', 'W', 'L' }, + { 'Y', 'A', 'W', 'N' }, + { 'Y', 'E', 'A', 'H' }, + { 'Y', 'E', 'A', 'R' }, + { 'Y', 'E', 'L', 'L' }, + { 'Y', 'O', 'G', 'A' }, + { 'Y', 'O', 'K', 'E' } +}; + +/* Extract LENGTH bits from the char array S starting with bit number + START. It always reads three consecutive octects, which means it + can read past end of data when START is at the edge of the region. */ + +static uint32_t +extract (const unsigned char *s, int start, int length) +{ + unsigned char cl = s[start / 8]; + unsigned char cc = s[start / 8 + 1]; + unsigned char cr = s[start / 8 + 2]; + uint32_t x; + x = (uint32_t)(cl << 8 | cc) << 8 | cr; + x >>= 24 - (length + (start % 8)); + x &= (0xffff >> (16 - length)); + return x; +} + +/* Length of a string known to be at least 1 and at most 4 chars + long. */ + +#define STRLEN_1_4(s) (!(s)[1] ? 1 : !(s)[2] ? 2 : !(s)[3] ? 3 : 4) + +/* Encode 8 bytes in C as a string of English words and store them to + STORE. Returns STORE. */ + +static char * +btoe (char *store, const unsigned char *c) +{ + unsigned char cp[10]; /* add in room for the parity 2 bits + + extract() slop. */ + int p, i; + char *store_beg = store; + + *store = '\0'; + + /* Workaround for extract() reads beyond end of data */ + xzero (cp); + memcpy (cp, c, 8); + + /* Compute parity and append it to CP. */ + for (p = 0, i = 0; i < 64; i += 2) + p += extract (cp, i, 2); + cp[8] = (char)p << 6; + + /* The 64 bits of input and the two parity bits comprise 66 bits of + data that are now in CP. We convert that information, 11 bits at + a time, to English words indexed from Wp. Since there are 2048 + (2^11) words in Wp, every 11-bit combination corresponds to a + distinct word. */ + memcpy (store, &Wp[extract (cp, 0, 11)][0], 4); + store += STRLEN_1_4 (store); + *store++ = ' '; + memcpy (store, &Wp[extract (cp, 11, 11)][0], 4); + store += STRLEN_1_4 (store); + *store++ = ' '; + memcpy (store, &Wp[extract (cp, 22, 11)][0], 4); + store += STRLEN_1_4 (store); + *store++ = ' '; + memcpy (store, &Wp[extract (cp, 33, 11)][0], 4); + store += STRLEN_1_4 (store); + *store++ = ' '; + memcpy (store, &Wp[extract (cp, 44, 11)][0], 4); + store += STRLEN_1_4 (store); + *store++ = ' '; + memcpy (store, &Wp[extract (cp, 55, 11)][0], 4); + store[4] = '\0'; /* make sure the string is terminated */ + + DEBUGP (("wrote %s to STORE\n", quote (store_beg))); + return store_beg; +} + +/* Calculate the SKEY response, based on the sequence, seed + (challenge), and the secret password. The calculated response is + used instead of the real password when logging in to SKEY-enabled + servers. + + The result is calculated like this: + + + Concatenate SEED and PASS and calculate the 16-byte MD5 checksum. + + + Shorten the checksum to eight bytes by folding the second eight + bytes onto the first eight using XOR. The resulting eight-byte + sequence is the key. + + + MD5-process the key, fold the checksum to eight bytes and store + it back to the key. Repeat this crunching SEQUENCE times. + (Sequence is a number that gets decremented every time the user + logs in to the server. Therefore an eavesdropper would have to + invert the hash function in order to guess the next one-time + password.) + + + Convert the resulting 64-bit key to 6 English words separated by + spaces (see btoe for details) and return the resulting ASCII + string. + + All this is described in section 6 of rfc2289 in more detail. */ + +const char * +skey_response (int sequence, const char *seed, const char *pass) +{ + unsigned char key[8]; + + /* Room to hold 6 four-letter words (heh), 5 space separators, and + the terminating \0. 24+5+1 == 30 */ + static char english[30]; + + struct md5_ctx ctx; + uint32_t checksum[4]; + + md5_init_ctx (&ctx); + md5_process_bytes ((const unsigned char *) seed, strlen (seed), &ctx); + md5_process_bytes ((const unsigned char *) pass, strlen (pass), &ctx); + md5_finish_ctx (&ctx, (unsigned char *) checksum); + checksum[0] ^= checksum[2]; + checksum[1] ^= checksum[3]; + memcpy (key, checksum, 8); + + while (sequence-- > 0) + { + md5_init_ctx (&ctx); + md5_process_bytes ((unsigned char *) key, 8, &ctx); + md5_finish_ctx (&ctx, (unsigned char *) checksum); + checksum[0] ^= checksum[2]; + checksum[1] ^= checksum[3]; + memcpy (key, checksum, 8); + } + return btoe (english, key); +} diff --git a/src/ftp.c b/src/ftp.c new file mode 100644 index 0000000..a44bf04 --- /dev/null +++ b/src/ftp.c @@ -0,0 +1,2898 @@ +/* File Transfer Protocol support. + Copyright (C) 1996-2011, 2014-2015, 2018-2020 Free Software + Foundation, Inc. + +This file is part of GNU Wget. + +GNU Wget is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 3 of the License, or +(at your option) any later version. + +GNU Wget 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 Wget. If not, see . + +Additional permission under GNU GPL version 3 section 7 + +If you modify this program, or any covered work, by linking or +combining it with the OpenSSL project's OpenSSL library (or a +modified version of that library), containing parts covered by the +terms of the OpenSSL or SSLeay licenses, the Free Software Foundation +grants you additional permission to convey the resulting work. +Corresponding Source for a non-source form of such a combination +shall include the source code for the parts of OpenSSL used as well +as that of the covered work. */ + +#include "wget.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "utils.h" +#include "url.h" +#include "retr.h" +#include "ftp.h" +#include "ssl.h" +#include "connect.h" +#include "host.h" +#include "netrc.h" +#include "convert.h" /* for downloaded_file */ +#include "recur.h" /* for INFINITE_RECURSION */ +#include "warc.h" +#include "c-strcase.h" +#ifdef ENABLE_XATTR +#include "xattr.h" +#endif + +#ifdef __VMS +# include "vms.h" +#endif /* def __VMS */ + + +/* File where the "ls -al" listing will be saved. */ +#ifdef MSDOS +#define LIST_FILENAME "_listing" +#else +#define LIST_FILENAME ".listing" +#endif + +typedef struct +{ + int st; /* connection status */ + int cmd; /* command code */ + int csock; /* control connection socket */ + double dltime; /* time of the download in msecs */ + enum stype rs; /* remote system reported by ftp server */ + enum ustype rsu; /* when rs is ST_UNIX, here there are more details */ + char *id; /* initial directory */ + char *target; /* target file name */ + struct url *proxy; /* FTWK-style proxy */ +} ccon; + + +/* Look for regexp "( *[0-9]+ *byte" (literal parenthesis) anywhere in + the string S, and return the number converted to wgint, if found, 0 + otherwise. */ +static wgint +ftp_expected_bytes (const char *s) +{ + wgint res; + + while (1) + { + while (*s && *s != '(') + ++s; + if (!*s) + return 0; + ++s; /* skip the '(' */ + res = str_to_wgint (s, (char **) &s, 10); + if (!*s) + return 0; + while (*s && c_isspace (*s)) + ++s; + if (!*s) + return 0; + if (c_tolower (*s) != 'b') + continue; + if (c_strncasecmp (s, "byte", 4)) + continue; + else + break; + } + return res; +} + +#ifdef ENABLE_IPV6 +/* + * This function sets up a passive data connection with the FTP server. + * It is merely a wrapper around ftp_epsv, ftp_lpsv and ftp_pasv. + */ +static uerr_t +ftp_do_pasv (int csock, ip_address *addr, int *port) +{ + uerr_t err; + + /* We need to determine the address family and need to call + getpeername, so while we're at it, store the address to ADDR. + ftp_pasv and ftp_lpsv can simply override it. */ + if (!socket_ip_address (csock, addr, ENDPOINT_PEER)) + abort (); + + /* If our control connection is over IPv6, then we first try EPSV and then + * LPSV if the former is not supported. If the control connection is over + * IPv4, we simply issue the good old PASV request. */ + switch (addr->family) + { + case AF_INET: + if (!opt.server_response) + logputs (LOG_VERBOSE, "==> PASV ... "); + err = ftp_pasv (csock, addr, port); + break; + case AF_INET6: + if (!opt.server_response) + logputs (LOG_VERBOSE, "==> EPSV ... "); + err = ftp_epsv (csock, addr, port); + + /* If EPSV is not supported try LPSV */ + if (err == FTPNOPASV) + { + if (!opt.server_response) + logputs (LOG_VERBOSE, "==> LPSV ... "); + err = ftp_lpsv (csock, addr, port); + } + break; + default: + abort (); + } + + return err; +} + +/* + * This function sets up an active data connection with the FTP server. + * It is merely a wrapper around ftp_eprt, ftp_lprt and ftp_port. + */ +static uerr_t +ftp_do_port (int csock, int *local_sock) +{ + uerr_t err; + ip_address cip; + + if (!socket_ip_address (csock, &cip, ENDPOINT_PEER)) + abort (); + + /* If our control connection is over IPv6, then we first try EPRT and then + * LPRT if the former is not supported. If the control connection is over + * IPv4, we simply issue the good old PORT request. */ + switch (cip.family) + { + case AF_INET: + if (!opt.server_response) + logputs (LOG_VERBOSE, "==> PORT ... "); + err = ftp_port (csock, local_sock); + break; + case AF_INET6: + if (!opt.server_response) + logputs (LOG_VERBOSE, "==> EPRT ... "); + err = ftp_eprt (csock, local_sock); + + /* If EPRT is not supported try LPRT */ + if (err == FTPPORTERR) + { + if (!opt.server_response) + logputs (LOG_VERBOSE, "==> LPRT ... "); + err = ftp_lprt (csock, local_sock); + } + break; + default: + abort (); + } + return err; +} +#else + +static uerr_t +ftp_do_pasv (int csock, ip_address *addr, int *port) +{ + if (!opt.server_response) + logputs (LOG_VERBOSE, "==> PASV ... "); + return ftp_pasv (csock, addr, port); +} + +static uerr_t +ftp_do_port (int csock, int *local_sock) +{ + if (!opt.server_response) + logputs (LOG_VERBOSE, "==> PORT ... "); + return ftp_port (csock, local_sock); +} +#endif + +static void +print_length (wgint size, wgint start, bool authoritative) +{ + logprintf (LOG_VERBOSE, _("Length: %s"), number_to_static_string (size)); + if (size >= 1024) + logprintf (LOG_VERBOSE, " (%s)", human_readable (size, 10, 1)); + if (start > 0) + { + if (size - start >= 1024) + logprintf (LOG_VERBOSE, _(", %s (%s) remaining"), + number_to_static_string (size - start), + human_readable (size - start, 10, 1)); + else + logprintf (LOG_VERBOSE, _(", %s remaining"), + number_to_static_string (size - start)); + } + logputs (LOG_VERBOSE, !authoritative ? _(" (unauthoritative)\n") : "\n"); +} + +static uerr_t ftp_get_listing (struct url *, struct url *, ccon *, struct fileinfo **); + +static uerr_t +get_ftp_greeting (int csock, ccon *con) +{ + uerr_t err = 0; + + /* Get the server's greeting */ + err = ftp_greeting (csock); + if (err != FTPOK) + { + logputs (LOG_NOTQUIET, "Error in server response. Closing.\n"); + fd_close (csock); + con->csock = -1; + } + + return err; +} + +#ifdef HAVE_SSL +static uerr_t +init_control_ssl_connection (int csock, struct url *u, bool *using_control_security) +{ + bool using_security = false; + + /* If '--ftps-implicit' was passed, perform the SSL handshake directly, + * and do not send an AUTH command. + * Otherwise send an AUTH sequence before login, + * and perform the SSL handshake if accepted by server. + */ + if (!opt.ftps_implicit && !opt.server_response) + logputs (LOG_VERBOSE, "==> AUTH TLS ... "); + if (opt.ftps_implicit || ftp_auth (csock, SCHEME_FTPS) == FTPOK) + { + if (!ssl_connect_wget (csock, u->host, NULL)) + { + fd_close (csock); + return CONSSLERR; + } + else if (!ssl_check_certificate (csock, u->host)) + { + fd_close (csock); + return VERIFCERTERR; + } + + if (!opt.ftps_implicit && !opt.server_response) + logputs (LOG_VERBOSE, " done.\n"); + + /* If implicit FTPS was requested, we act as "normal" FTP, but over SSL. + * We're not using RFC 2228 commands. + */ + using_security = true; + } + else + { + /* The server does not support 'AUTH TLS'. + * Check if --ftps-fallback-to-ftp was passed. */ + if (opt.ftps_fallback_to_ftp) + { + logputs (LOG_NOTQUIET, "Server does not support AUTH TLS. Falling back to FTP.\n"); + using_security = false; + } + else + { + fd_close (csock); + return FTPNOAUTH; + } + } + + *using_control_security = using_security; + return NOCONERROR; +} +#endif + +/* Retrieves a file with denoted parameters through opening an FTP + connection to the server. It always closes the data connection, + and closes the control connection in case of error. If warc_tmp + is non-NULL, the downloaded data will be written there as well. */ +static uerr_t +getftp (struct url *u, struct url *original_url, + wgint passed_expected_bytes, wgint *qtyread, + wgint restval, ccon *con, int count, wgint *last_expected_bytes, + FILE *warc_tmp) +{ + int csock, dtsock, local_sock, res; + uerr_t err = RETROK; /* appease the compiler */ + FILE *fp = NULL; + char *respline, *tms; + const char *user, *passwd, *tmrate; + int cmd = con->cmd; + wgint expected_bytes = 0; + bool got_expected_bytes = false; + bool rest_failed = false; + int flags; + wgint rd_size, previous_rd_size = 0; + char type_char; + bool try_again; + bool list_a_used = false; +#ifdef HAVE_SSL + enum prot_level prot = (opt.ftps_clear_data_connection ? PROT_CLEAR : PROT_PRIVATE); + /* these variables tell whether the target server + * accepts the security extensions (RFC 2228) or not, + * and whether we're actually using any of them + * (encryption at the control connection only, + * or both at control and data connections) */ + bool using_control_security = false, using_data_security = false; +#endif + + assert (con != NULL); + assert (con->target != NULL); + + /* Debug-check of the sanity of the request by making sure that LIST + and RETR are never both requested (since we can handle only one + at a time. */ + assert (!((cmd & DO_LIST) && (cmd & DO_RETR))); + /* Make sure that at least *something* is requested. */ + assert ((cmd & (DO_LIST | DO_CWD | DO_RETR | DO_LOGIN)) != 0); + + *qtyread = restval; + + /* Find the username with priority */ + if (u->user) + user = u->user; + else if (opt.user && (opt.use_askpass || opt.ask_passwd)) + user = opt.user; + else if (opt.ftp_user) + user = opt.ftp_user; + else if (opt.user) + user = opt.user; + else + user = NULL; + + /* Find the password with priority */ + if (u->passwd) + passwd = u->passwd; + else if (opt.passwd && (opt.use_askpass || opt.ask_passwd)) + passwd = opt.passwd; + else if (opt.ftp_passwd) + passwd = opt.ftp_passwd; + else if (opt.passwd) + passwd = opt.passwd; + else + passwd = NULL; + + /* Check for ~/.netrc if none of the above match */ + if (opt.netrc && (!user || !passwd)) + search_netrc (u->host, (const char **) &user, (const char **) &passwd, 1, NULL); + + if (!user) user = "anonymous"; + if (!passwd) passwd = "-wget@"; + + dtsock = -1; + local_sock = -1; + con->dltime = 0; + +#ifdef HAVE_SSL + if (u->scheme == SCHEME_FTPS) + { + /* Initialize SSL layer first */ + if (!ssl_init ()) + { + scheme_disable (SCHEME_FTPS); + logprintf (LOG_NOTQUIET, _("Could not initialize SSL. It will be disabled.\n")); + err = SSLINITFAILED; + return err; + } + + /* If we're using the default FTP port and implicit FTPS was requested, + * rewrite the port to the default *implicit* FTPS port. + */ + if (opt.ftps_implicit && u->port == DEFAULT_FTP_PORT) + { + DEBUGP (("Implicit FTPS was specified. Rewriting default port to %d.\n", DEFAULT_FTPS_IMPLICIT_PORT)); + u->port = DEFAULT_FTPS_IMPLICIT_PORT; + } + } +#endif + + if (!(cmd & DO_LOGIN)) + { + csock = con->csock; +#ifdef HAVE_SSL + using_data_security = con->st & DATA_CHANNEL_SECURITY; +#endif + } + else /* cmd & DO_LOGIN */ + { + char *host = con->proxy ? con->proxy->host : u->host; + int port = con->proxy ? con->proxy->port : u->port; + + /* Login to the server: */ + + /* First: Establish the control connection. */ + + csock = connect_to_host (host, port); + if (csock == E_HOST) + return HOSTERR; + else if (csock < 0) + return (retryable_socket_connect_error (errno) + ? CONERROR : CONIMPOSSIBLE); + + if (cmd & LEAVE_PENDING) + con->csock = csock; + else + con->csock = -1; + +#ifdef HAVE_SSL + if (u->scheme == SCHEME_FTPS) + { + /* If we're in implicit FTPS mode, we have to set up SSL/TLS before everything else. + * Otherwise we first read the server's greeting, and then send an "AUTH TLS". + */ + if (opt.ftps_implicit) + { + err = init_control_ssl_connection (csock, u, &using_control_security); + if (err != NOCONERROR) + return err; + err = get_ftp_greeting (csock, con); + if (err != FTPOK) + return err; + } + else + { + err = get_ftp_greeting (csock, con); + if (err != FTPOK) + return err; + err = init_control_ssl_connection (csock, u, &using_control_security); + if (err != NOCONERROR) + return err; + } + } + else + { + err = get_ftp_greeting (csock, con); + if (err != FTPOK) + return err; + } +#else + err = get_ftp_greeting (csock, con); + if (err != FTPOK) + return err; +#endif + + /* Second: Login with proper USER/PASS sequence. */ + logprintf (LOG_VERBOSE, _("Logging in as %s ... "), + quotearg_style (escape_quoting_style, user)); + if (opt.server_response) + logputs (LOG_ALWAYS, "\n"); + if (con->proxy) + { + /* If proxy is in use, log in as username@target-site. */ + char *logname = concat_strings (user, "@", u->host, (char *) 0); + err = ftp_login (csock, logname, passwd); + xfree (logname); + } + else + err = ftp_login (csock, user, passwd); + + /* FTPRERR, FTPSRVERR, WRITEFAILED, FTPLOGREFUSED, FTPLOGINC */ + switch (err) + { + case FTPRERR: + logputs (LOG_VERBOSE, "\n"); + logputs (LOG_NOTQUIET, _("\ +Error in server response, closing control connection.\n")); + fd_close (csock); + con->csock = -1; + return err; + case FTPSRVERR: + logputs (LOG_VERBOSE, "\n"); + logputs (LOG_NOTQUIET, _("Error in server greeting.\n")); + fd_close (csock); + con->csock = -1; + return err; + case WRITEFAILED: + logputs (LOG_VERBOSE, "\n"); + logputs (LOG_NOTQUIET, + _("Write failed, closing control connection.\n")); + fd_close (csock); + con->csock = -1; + return err; + case FTPLOGREFUSED: + logputs (LOG_VERBOSE, "\n"); + logputs (LOG_NOTQUIET, _("The server refuses login.\n")); + fd_close (csock); + con->csock = -1; + return FTPLOGREFUSED; + case FTPLOGINC: + logputs (LOG_VERBOSE, "\n"); + logputs (LOG_NOTQUIET, _("Login incorrect.\n")); + fd_close (csock); + con->csock = -1; + return FTPLOGINC; + case FTPOK: + if (!opt.server_response) + logputs (LOG_VERBOSE, _("Logged in!\n")); + break; + default: + abort (); + } + +#ifdef HAVE_SSL + if (using_control_security) + { + /* Send the PBSZ and PROT commands, in that order. + * If we are here it means that the server has already accepted + * some form of FTPS. Thus, these commands must work. + * If they don't work, that's an error. There's no sense in honoring + * --ftps-fallback-to-ftp or similar options. */ + if (u->scheme == SCHEME_FTPS) + { + if (!opt.server_response) + logputs (LOG_VERBOSE, "==> PBSZ 0 ... "); + if ((err = ftp_pbsz (csock, 0)) == FTPNOPBSZ) + { + logputs (LOG_NOTQUIET, _("Server did not accept the 'PBSZ 0' command.\n")); + return err; + } + if (!opt.server_response) + logputs (LOG_VERBOSE, "done."); + + if (!opt.server_response) + logprintf (LOG_VERBOSE, " ==> PROT %c ... ", (int) prot); + if ((err = ftp_prot (csock, prot)) == FTPNOPROT) + { + logprintf (LOG_NOTQUIET, _("Server did not accept the 'PROT %c' command.\n"), (int) prot); + return err; + } + if (!opt.server_response) + logputs (LOG_VERBOSE, "done.\n"); + + if (prot != PROT_CLEAR) + { + using_data_security = true; + con->st |= DATA_CHANNEL_SECURITY; + } + } + } +#endif + + /* Third: Get the system type */ + if (!opt.server_response) + logprintf (LOG_VERBOSE, "==> SYST ... "); + err = ftp_syst (csock, &con->rs, &con->rsu); + /* FTPRERR */ + switch (err) + { + case FTPRERR: + logputs (LOG_VERBOSE, "\n"); + logputs (LOG_NOTQUIET, _("\ +Error in server response, closing control connection.\n")); + fd_close (csock); + con->csock = -1; + return err; + case FTPSRVERR: + logputs (LOG_VERBOSE, "\n"); + logputs (LOG_NOTQUIET, + _("Server error, can't determine system type.\n")); + break; + case FTPOK: + /* Everything is OK. */ + break; + default: + abort (); + } + if (!opt.server_response && err != FTPSRVERR) + logputs (LOG_VERBOSE, _("done. ")); + + /* 2013-10-17 Andrea Urbani (matfanjol) + According to the system type I choose which + list command will be used. + If I don't know that system, I will try, the + first time of each session, "LIST -a" and + "LIST". (see __LIST_A_EXPLANATION__ below) */ + switch (con->rs) + { + case ST_VMS: + /* About ST_VMS there is an old note: + 2008-01-29 SMS. For a VMS FTP server, where "LIST -a" may not + fail, but will never do what is desired here, + skip directly to the simple "LIST" command + (assumed to be the last one in the list). */ + DEBUGP (("\nVMS: I know it and I will use \"LIST\" as standard list command\n")); + con->st |= LIST_AFTER_LIST_A_CHECK_DONE; + con->st |= AVOID_LIST_A; + break; + case ST_UNIX: + if (con->rsu == UST_MULTINET) + { + DEBUGP (("\nUNIX MultiNet: I know it and I will use \"LIST\" " + "as standard list command\n")); + con->st |= LIST_AFTER_LIST_A_CHECK_DONE; + con->st |= AVOID_LIST_A; + } + else if (con->rsu == UST_TYPE_L8) + { + DEBUGP (("\nUNIX TYPE L8: I know it and I will use \"LIST -a\" " + "as standard list command\n")); + con->st |= LIST_AFTER_LIST_A_CHECK_DONE; + con->st |= AVOID_LIST; + } + break; + default: + break; + } + + /* Fourth: Find the initial ftp directory */ + + if (!opt.server_response) + logprintf (LOG_VERBOSE, "==> PWD ... "); + err = ftp_pwd (csock, &con->id); + /* FTPRERR */ + switch (err) + { + case FTPRERR: + logputs (LOG_VERBOSE, "\n"); + logputs (LOG_NOTQUIET, _("\ +Error in server response, closing control connection.\n")); + fd_close (csock); + con->csock = -1; + return err; + case FTPSRVERR : + /* PWD unsupported -- assume "/". */ + xfree (con->id); + con->id = xstrdup ("/"); + break; + case FTPOK: + /* Everything is OK. */ + break; + default: + abort (); + } + +#if 0 + /* 2004-09-17 SMS. + Don't help me out. Please. + A reasonably recent VMS FTP server will cope just fine with + UNIX file specifications. This code just spoils things. + Discarding the device name, for example, is not a wise move. + This code was disabled but left in as an example of what not + to do. + */ + + /* VMS will report something like "PUB$DEVICE:[INITIAL.FOLDER]". + Convert it to "/INITIAL/FOLDER" */ + if (con->rs == ST_VMS) + { + char *path = strchr (con->id, '['); + char *pathend = path ? strchr (path + 1, ']') : NULL; + if (!path || !pathend) + DEBUGP (("Initial VMS directory not in the form [...]!\n")); + else + { + char *idir = con->id; + DEBUGP (("Preprocessing the initial VMS directory\n")); + DEBUGP ((" old = '%s'\n", con->id)); + /* We do the conversion in-place by copying the stuff + between [ and ] to the beginning, and changing dots + to slashes at the same time. */ + *idir++ = '/'; + for (++path; path < pathend; path++, idir++) + *idir = *path == '.' ? '/' : *path; + *idir = '\0'; + DEBUGP ((" new = '%s'\n\n", con->id)); + } + } +#endif /* 0 */ + + if (!opt.server_response) + logputs (LOG_VERBOSE, _("done.\n")); + + /* Fifth: Set the FTP type. */ + type_char = ftp_process_type (u->params); + if (!opt.server_response) + logprintf (LOG_VERBOSE, "==> TYPE %c ... ", type_char); + err = ftp_type (csock, type_char); + /* FTPRERR, WRITEFAILED, FTPUNKNOWNTYPE */ + switch (err) + { + case FTPRERR: + logputs (LOG_VERBOSE, "\n"); + logputs (LOG_NOTQUIET, _("\ +Error in server response, closing control connection.\n")); + fd_close (csock); + con->csock = -1; + return err; + case WRITEFAILED: + logputs (LOG_VERBOSE, "\n"); + logputs (LOG_NOTQUIET, + _("Write failed, closing control connection.\n")); + fd_close (csock); + con->csock = -1; + return err; + case FTPUNKNOWNTYPE: + logputs (LOG_VERBOSE, "\n"); + logprintf (LOG_NOTQUIET, + _("Unknown type `%c', closing control connection.\n"), + type_char); + fd_close (csock); + con->csock = -1; + return err; + case FTPOK: + /* Everything is OK. */ + break; + default: + abort (); + } + if (!opt.server_response) + logputs (LOG_VERBOSE, _("done. ")); + } /* do login */ + + if (cmd & DO_CWD) + { + if (!*u->dir) + logputs (LOG_VERBOSE, _("==> CWD not needed.\n")); + else + { + const char *targ = NULL; + char *target = u->dir; + char targetbuf[1024]; + int cwd_count; + int cwd_end; + int cwd_start; + + DEBUGP (("changing working directory\n")); + + /* Change working directory. To change to a non-absolute + Unix directory, we need to prepend initial directory + (con->id) to it. Absolute directories "just work". + + A relative directory is one that does not begin with '/' + and, on non-Unix OS'es, one that doesn't begin with + "[a-z]:". + + This is not done for OS400, which doesn't use + "/"-delimited directories, nor does it support directory + hierarchies. "CWD foo" followed by "CWD bar" leaves us + in "bar", not in "foo/bar", as would be customary + elsewhere. */ + + /* 2004-09-20 SMS. + Why is this wise even on UNIX? It certainly fouls VMS. + See below for a more reliable, more universal method. + */ + + /* 2008-04-22 MJC. + I'm not crazy about it either. I'm informed it's useful + for misconfigured servers that have some dirs in the path + with +x but -r, but this method is not RFC-conformant. I + understand the need to deal with crappy server + configurations, but it's far better to use the canonical + method first, and fall back to kludges second. + */ + + if (target[0] != '/' + && !(con->rs != ST_UNIX + && c_isalpha (target[0]) + && target[1] == ':') + && (con->rs != ST_OS400) + && (con->rs != ST_VMS)) + { + char *ntarget, *p; + size_t idlen = strlen (con->id); + size_t len; + + /* Strip trailing slash(es) from con->id. */ + while (idlen > 0 && con->id[idlen - 1] == '/') + --idlen; + + len = idlen + 1 + strlen (target); + if (len < sizeof (targetbuf)) + p = ntarget = targetbuf; + else + p = ntarget = xmalloc (len + 1); + + memcpy (p, con->id, idlen); + p += idlen; + *p++ = '/'; + strcpy (p, target); + + DEBUGP (("Prepended initial PWD to relative path:\n")); + DEBUGP ((" pwd: '%s'\n old: '%s'\n new: '%s'\n", + con->id, target, ntarget)); + target = ntarget; + } + +#if 0 + /* 2004-09-17 SMS. + Don't help me out. Please. + A reasonably recent VMS FTP server will cope just fine with + UNIX file specifications. This code just spoils things. + Discarding the device name, for example, is not a wise + move. + This code was disabled but left in as an example of what + not to do. + */ + + /* If the FTP host runs VMS, we will have to convert the absolute + directory path in UNIX notation to absolute directory path in + VMS notation as VMS FTP servers do not like UNIX notation of + absolute paths. "VMS notation" is [dir.subdir.subsubdir]. */ + + if (con->rs == ST_VMS) + { + char *tmpp; + char *ntarget = (char *)alloca (strlen (target) + 2); + /* We use a converted initial dir, so directories in + TARGET will be separated with slashes, something like + "/INITIAL/FOLDER/DIR/SUBDIR". Convert that to + "[INITIAL.FOLDER.DIR.SUBDIR]". */ + strcpy (ntarget, target); + assert (*ntarget == '/'); + *ntarget = '['; + for (tmpp = ntarget + 1; *tmpp; tmpp++) + if (*tmpp == '/') + *tmpp = '.'; + *tmpp++ = ']'; + *tmpp = '\0'; + DEBUGP (("Changed file name to VMS syntax:\n")); + DEBUGP ((" Unix: '%s'\n VMS: '%s'\n", target, ntarget)); + target = ntarget; + } +#endif /* 0 */ + + /* 2004-09-20 SMS. + A relative directory is relative to the initial directory. + Thus, what _is_ useful on VMS (and probably elsewhere) is + to CWD to the initial directory (ideally, whatever the + server reports, _exactly_, NOT badly UNIX-ixed), and then + CWD to the (new) relative directory. This should probably + be restructured as a function, called once or twice, but + I'm lazy enough to take the badly indented loop short-cut + for now. + */ + + /* Decide on one pass (absolute) or two (relative). + The VMS restriction may be relaxed when the squirrely code + above is reformed. + */ + if ((con->rs == ST_VMS) && (target[0] != '/')) + { + cwd_start = 0; + DEBUGP (("Using two-step CWD for relative path.\n")); + } + else + { + /* Go straight to the target. */ + cwd_start = 1; + } + + /* At least one VMS FTP server (TCPware V5.6-2) can switch to + a UNIX emulation mode when given a UNIX-like directory + specification (like "a/b/c"). If allowed to continue this + way, LIST interpretation will be confused, because the + system type (SYST response) will not be re-checked, and + future UNIX-format directory listings (for multiple URLs or + "-r") will be horribly misinterpreted. + + The cheap and nasty work-around is to do a "CWD []" after a + UNIX-like directory specification is used. (A single-level + directory is harmless.) This puts the TCPware server back + into VMS mode, and does no harm on other servers. + + Unlike the rest of this block, this particular behavior + _is_ VMS-specific, so it gets its own VMS test. + */ + if ((con->rs == ST_VMS) && (strchr (target, '/') != NULL)) + { + cwd_end = 3; + DEBUGP (("Using extra \"CWD []\" step for VMS server.\n")); + } + else + { + cwd_end = 2; + } + + /* 2004-09-20 SMS. */ + /* Sorry about the deviant indenting. Laziness. */ + + for (cwd_count = cwd_start; cwd_count < cwd_end; cwd_count++) + { + switch (cwd_count) + { + case 0: + /* Step one (optional): Go to the initial directory, + exactly as reported by the server. + */ + targ = con->id; + break; + + case 1: + /* Step two: Go to the target directory. (Absolute or + relative will work now.) + */ + targ = target; + break; + + case 2: + /* Step three (optional): "CWD []" to restore server + VMS-ness. + */ + targ = "[]"; + break; + + default: + logprintf (LOG_ALWAYS, _("Logically impossible section reached in getftp()")); + logprintf (LOG_ALWAYS, _("cwd_count: %d\ncwd_start: %d\ncwd_end: %d\n"), + cwd_count, cwd_start, cwd_end); + abort (); + } + + if (!opt.server_response) + logprintf (LOG_VERBOSE, "==> CWD (%d) %s ... ", cwd_count, + quotearg_style (escape_quoting_style, target)); + + err = ftp_cwd (csock, targ); + + /* FTPRERR, WRITEFAILED, FTPNSFOD */ + switch (err) + { + case FTPRERR: + logputs (LOG_VERBOSE, "\n"); + logputs (LOG_NOTQUIET, _("\ +Error in server response, closing control connection.\n")); + fd_close (csock); + con->csock = -1; + return err; + case WRITEFAILED: + logputs (LOG_VERBOSE, "\n"); + logputs (LOG_NOTQUIET, + _("Write failed, closing control connection.\n")); + fd_close (csock); + con->csock = -1; + return err; + case FTPNSFOD: + logputs (LOG_VERBOSE, "\n"); + logprintf (LOG_NOTQUIET, _("No such directory %s.\n\n"), + quote (u->dir)); + fd_close (csock); + con->csock = -1; + return err; + case FTPOK: + break; + default: + abort (); + } + + if (!opt.server_response) + logputs (LOG_VERBOSE, _("done.\n")); + + } /* for */ + + /* 2004-09-20 SMS. */ + + if (target != targetbuf) + xfree (target); + + } /* else */ + } + else /* do not CWD */ + logputs (LOG_VERBOSE, _("==> CWD not required.\n")); + + if ((cmd & DO_RETR) && passed_expected_bytes == 0) + { + if (opt.verbose) + { + if (!opt.server_response) + logprintf (LOG_VERBOSE, "==> SIZE %s ... ", + quotearg_style (escape_quoting_style, u->file)); + } + + err = ftp_size (csock, u->file, &expected_bytes); + /* FTPRERR */ + switch (err) + { + case FTPRERR: + case FTPSRVERR: + logputs (LOG_VERBOSE, "\n"); + logputs (LOG_NOTQUIET, _("\ +Error in server response, closing control connection.\n")); + fd_close (csock); + con->csock = -1; + return err; + case FTPOK: + got_expected_bytes = true; + /* Everything is OK. */ + break; + default: + abort (); + } + if (!opt.server_response) + { + logprintf (LOG_VERBOSE, "%s\n", + expected_bytes ? + number_to_static_string (expected_bytes) : + _("done.\n")); + } + } + + if (cmd & DO_RETR && restval > 0 && restval == expected_bytes) + { + /* Server confirms that file has length restval. We should stop now. + Some servers (f.e. NcFTPd) return error when receive REST 0 */ + logputs (LOG_VERBOSE, _("File has already been retrieved.\n")); + fd_close (csock); + con->csock = -1; + return RETRFINISHED; + } + + do + { + try_again = false; + /* If anything is to be retrieved, PORT (or PASV) must be sent. */ + if (cmd & (DO_LIST | DO_RETR)) + { + if (opt.ftp_pasv) + { + ip_address passive_addr; + int passive_port; + err = ftp_do_pasv (csock, &passive_addr, &passive_port); + /* FTPRERR, WRITEFAILED, FTPNOPASV, FTPINVPASV */ + switch (err) + { + case FTPRERR: + logputs (LOG_VERBOSE, "\n"); + logputs (LOG_NOTQUIET, _("\ +Error in server response, closing control connection.\n")); + fd_close (csock); + con->csock = -1; + return err; + case WRITEFAILED: + logputs (LOG_VERBOSE, "\n"); + logputs (LOG_NOTQUIET, + _("Write failed, closing control connection.\n")); + fd_close (csock); + con->csock = -1; + return err; + case FTPNOPASV: + logputs (LOG_VERBOSE, "\n"); + logputs (LOG_NOTQUIET, _("Cannot initiate PASV transfer.\n")); + break; + case FTPINVPASV: + logputs (LOG_VERBOSE, "\n"); + logputs (LOG_NOTQUIET, _("Cannot parse PASV response.\n")); + break; + case FTPOK: + break; + default: + abort (); + } /* switch (err) */ + if (err==FTPOK) + { + DEBUGP (("trying to connect to %s port %d\n", + print_address (&passive_addr), passive_port)); + dtsock = connect_to_ip (&passive_addr, passive_port, NULL); + if (dtsock < 0) + { + int save_errno = errno; + fd_close (csock); + con->csock = -1; + logprintf (LOG_VERBOSE, _("couldn't connect to %s port %d: %s\n"), + print_address (&passive_addr), passive_port, + strerror (save_errno)); + return (retryable_socket_connect_error (save_errno) + ? CONERROR : CONIMPOSSIBLE); + } + + if (!opt.server_response) + logputs (LOG_VERBOSE, _("done. ")); + } + else + return err; + + /* + * We do not want to fall back from PASSIVE mode to ACTIVE mode ! + * The reason is the PORT command exposes the client's real IP address + * to the server. Bad for someone who relies on privacy via a ftp proxy. + */ + } + else + { + err = ftp_do_port (csock, &local_sock); + /* FTPRERR, WRITEFAILED, bindport (FTPSYSERR), HOSTERR, + FTPPORTERR */ + switch (err) + { + case FTPRERR: + logputs (LOG_VERBOSE, "\n"); + logputs (LOG_NOTQUIET, _("\ +Error in server response, closing control connection.\n")); + fd_close (csock); + con->csock = -1; + fd_close (dtsock); + fd_close (local_sock); + return err; + case WRITEFAILED: + logputs (LOG_VERBOSE, "\n"); + logputs (LOG_NOTQUIET, + _("Write failed, closing control connection.\n")); + fd_close (csock); + con->csock = -1; + fd_close (dtsock); + fd_close (local_sock); + return err; + case CONSOCKERR: + logputs (LOG_VERBOSE, "\n"); + logprintf (LOG_NOTQUIET, "socket: %s\n", strerror (errno)); + fd_close (csock); + con->csock = -1; + fd_close (dtsock); + fd_close (local_sock); + return err; + case FTPSYSERR: + logputs (LOG_VERBOSE, "\n"); + logprintf (LOG_NOTQUIET, _("Bind error (%s).\n"), + strerror (errno)); + fd_close (dtsock); + return err; + case FTPPORTERR: + logputs (LOG_VERBOSE, "\n"); + logputs (LOG_NOTQUIET, _("Invalid PORT.\n")); + fd_close (csock); + con->csock = -1; + fd_close (dtsock); + fd_close (local_sock); + return err; + case FTPOK: + break; + default: + abort (); + } /* port switch */ + if (!opt.server_response) + logputs (LOG_VERBOSE, _("done. ")); + } /* dtsock == -1 */ + } /* cmd & (DO_LIST | DO_RETR) */ + + /* Restart if needed. */ + if (restval && (cmd & DO_RETR)) + { + if (!opt.server_response) + logprintf (LOG_VERBOSE, "==> REST %s ... ", + number_to_static_string (restval)); + err = ftp_rest (csock, restval); + + /* FTPRERR, WRITEFAILED, FTPRESTFAIL */ + switch (err) + { + case FTPRERR: + logputs (LOG_VERBOSE, "\n"); + logputs (LOG_NOTQUIET, _("\ +Error in server response, closing control connection.\n")); + fd_close (csock); + con->csock = -1; + fd_close (dtsock); + fd_close (local_sock); + return err; + case WRITEFAILED: + logputs (LOG_VERBOSE, "\n"); + logputs (LOG_NOTQUIET, + _("Write failed, closing control connection.\n")); + fd_close (csock); + con->csock = -1; + fd_close (dtsock); + fd_close (local_sock); + return err; + case FTPRESTFAIL: + logputs (LOG_VERBOSE, _("\nREST failed, starting from scratch.\n")); + rest_failed = true; + break; + case FTPOK: + break; + default: + abort (); + } + if (err != FTPRESTFAIL && !opt.server_response) + logputs (LOG_VERBOSE, _("done. ")); + } /* restval && cmd & DO_RETR */ + + if (cmd & DO_RETR) + { + /* If we're in spider mode, don't really retrieve anything except + the directory listing and verify whether the given "file" exists. */ + if (opt.spider) + { + bool exists = false; + bool all_exist = true; + struct fileinfo *f; + uerr_t _res = ftp_get_listing (u, original_url, con, &f); + /* Set the DO_RETR command flag again, because it gets unset when + calling ftp_get_listing() and would otherwise cause an assertion + failure earlier on when this function gets repeatedly called + (e.g., when recursing). */ + con->cmd |= DO_RETR; + if (_res == RETROK) + { + while (f) + { + if (!strcmp (f->name, u->file)) + { + exists = true; + break; + } else { + all_exist = false; + } + f = f->next; + } + if (exists) + { + logputs (LOG_VERBOSE, "\n"); + logprintf (LOG_NOTQUIET, _("File %s exists.\n"), + quote (u->file)); + } + else + { + logputs (LOG_VERBOSE, "\n"); + logprintf (LOG_NOTQUIET, _("No such file %s.\n"), + quote (u->file)); + } + } + fd_close (csock); + con->csock = -1; + fd_close (dtsock); + fd_close (local_sock); + if (all_exist) { + return RETRFINISHED; + } else { + return FTPNSFOD; + } + } + + if (opt.verbose) + { + if (!opt.server_response) + { + if (restval) + logputs (LOG_VERBOSE, "\n"); + logprintf (LOG_VERBOSE, "==> RETR %s ... ", + quotearg_style (escape_quoting_style, u->file)); + } + } + + err = ftp_retr (csock, u->file); + /* FTPRERR, WRITEFAILED, FTPNSFOD */ + switch (err) + { + case FTPRERR: + logputs (LOG_VERBOSE, "\n"); + logputs (LOG_NOTQUIET, _("\ +Error in server response, closing control connection.\n")); + fd_close (csock); + con->csock = -1; + fd_close (dtsock); + fd_close (local_sock); + return err; + case WRITEFAILED: + logputs (LOG_VERBOSE, "\n"); + logputs (LOG_NOTQUIET, + _("Write failed, closing control connection.\n")); + fd_close (csock); + con->csock = -1; + fd_close (dtsock); + fd_close (local_sock); + return err; + case FTPNSFOD: + logputs (LOG_VERBOSE, "\n"); + logprintf (LOG_NOTQUIET, _("No such file %s.\n\n"), + quote (u->file)); + fd_close (dtsock); + fd_close (local_sock); + return err; + case FTPOK: + break; + default: + abort (); + } + + if (!opt.server_response) + logputs (LOG_VERBOSE, _("done.\n")); + + if (! got_expected_bytes) + expected_bytes = *last_expected_bytes; + } /* do retrieve */ + + if (cmd & DO_LIST) + { + if (!opt.server_response) + logputs (LOG_VERBOSE, "==> LIST ... "); + /* As Maciej W. Rozycki (macro@ds2.pg.gda.pl) says, `LIST' + without arguments is better than `LIST .'; confirmed by + RFC959. */ + err = ftp_list (csock, NULL, con->st&AVOID_LIST_A, con->st&AVOID_LIST, &list_a_used); + + /* FTPRERR, WRITEFAILED */ + switch (err) + { + case FTPRERR: + logputs (LOG_VERBOSE, "\n"); + logputs (LOG_NOTQUIET, _("\ +Error in server response, closing control connection.\n")); + fd_close (csock); + con->csock = -1; + fd_close (dtsock); + fd_close (local_sock); + return err; + case WRITEFAILED: + logputs (LOG_VERBOSE, "\n"); + logputs (LOG_NOTQUIET, + _("Write failed, closing control connection.\n")); + fd_close (csock); + con->csock = -1; + fd_close (dtsock); + fd_close (local_sock); + return err; + case FTPNSFOD: + logputs (LOG_VERBOSE, "\n"); + logprintf (LOG_NOTQUIET, _("No such file or directory %s.\n\n"), + quote (".")); + fd_close (dtsock); + fd_close (local_sock); + return err; + case FTPOK: + break; + default: + abort (); + } + if (!opt.server_response) + logputs (LOG_VERBOSE, _("done.\n")); + + if (! got_expected_bytes) + expected_bytes = *last_expected_bytes; + } /* cmd & DO_LIST */ + + if (!(cmd & (DO_LIST | DO_RETR)) || (opt.spider && !(cmd & DO_LIST))) + return RETRFINISHED; + + /* Some FTP servers return the total length of file after REST + command, others just return the remaining size. */ + if (passed_expected_bytes && restval && expected_bytes + && (expected_bytes == passed_expected_bytes - restval)) + { + DEBUGP (("Lying FTP server found, adjusting.\n")); + expected_bytes = passed_expected_bytes; + } + + /* If no transmission was required, then everything is OK. */ + if (!opt.ftp_pasv) /* we are not using passive mode so we need + to accept */ + { + /* Wait for the server to connect to the address we're waiting + at. */ + dtsock = accept_connection (local_sock); + if (dtsock < 0) + { + logprintf (LOG_NOTQUIET, "accept: %s\n", strerror (errno)); + return CONERROR; + } + } + + /* Open the file -- if output_stream is set, use it instead. */ + + /* 2005-04-17 SMS. + Note that having the output_stream ("-O") file opened in main + (main.c) rather limits the ability in VMS to open the file + differently for ASCII versus binary FTP here. (Of course, doing it + there allows a open failure to be detected immediately, without first + connecting to the server.) + */ + if (!output_stream || con->cmd & DO_LIST) + { +/* On VMS, alter the name as required. */ +#ifdef __VMS + char *targ; + + targ = ods_conform (con->target); + if (targ != con->target) + { + xfree (con->target); + con->target = targ; + } +#endif /* def __VMS */ + + mkalldirs (con->target); + if (opt.backups) + rotate_backups (con->target); + +/* 2005-04-15 SMS. + For VMS, define common fopen() optional arguments, and a handy macro + for use as a variable "binary" flag. + Elsewhere, define a constant "binary" flag. + Isn't it nice to have distinct text and binary file types? +*/ +/* 2011-09-30 SMS. + Added listing files to the set of non-"binary" (text, Stream_LF) + files. (Wget works either way, but other programs, like, say, text + editors, work better on listing files which have text attributes.) + Now we use "binary" attributes for a binary ("IMAGE") transfer, + unless "--ftp-stmlf" was specified, and we always use non-"binary" + (text, Stream_LF) attributes for a listing file, or for an ASCII + transfer. + Tidied the VMS-specific BIN_TYPE_xxx macros, and changed the call to + fopen_excl() (restored?) to use BIN_TYPE_FILE instead of "true". +*/ +#ifdef __VMS +# define BIN_TYPE_TRANSFER (type_char != 'A') +# define BIN_TYPE_FILE \ + ((!(cmd & DO_LIST)) && BIN_TYPE_TRANSFER && (opt.ftp_stmlf == 0)) +# define FOPEN_OPT_ARGS "fop=sqo", "acc", acc_cb, &open_id +# define FOPEN_OPT_ARGS_BIN "ctx=bin,stm", "rfm=fix", "mrs=512" FOPEN_OPT_ARGS +#else /* def __VMS */ +# define BIN_TYPE_FILE true +#endif /* def __VMS [else] */ + + if (restval && !(con->cmd & DO_LIST)) + { +#ifdef __VMS + int open_id; + + if (BIN_TYPE_FILE) + { + open_id = 3; + fp = fopen (con->target, "ab", FOPEN_OPT_ARGS_BIN); + } + else + { + open_id = 4; + fp = fopen (con->target, "a", FOPEN_OPT_ARGS); + } +#else /* def __VMS */ + fp = fopen (con->target, "ab"); +#endif /* def __VMS [else] */ + } + else if (opt.noclobber || opt.always_rest || opt.timestamping || opt.dirstruct + || opt.output_document || count > 0) + { + if (opt.unlink_requested && file_exists_p (con->target, NULL)) + { + if (unlink (con->target) < 0) + { + logprintf (LOG_NOTQUIET, "%s: %s\n", con->target, + strerror (errno)); + fd_close (csock); + con->csock = -1; + fd_close (dtsock); + fd_close (local_sock); + return UNLINKERR; + } + } + +#ifdef __VMS + int open_id; + + if (BIN_TYPE_FILE) + { + open_id = 5; + fp = fopen (con->target, "wb", FOPEN_OPT_ARGS_BIN); + } + else + { + open_id = 6; + fp = fopen (con->target, "w", FOPEN_OPT_ARGS); + } +#else /* def __VMS */ + fp = fopen (con->target, "wb"); +#endif /* def __VMS [else] */ + } + else + { + fp = fopen_excl (con->target, BIN_TYPE_FILE); + if (!fp && errno == EEXIST) + { + /* We cannot just invent a new name and use it (which is + what functions like unique_create typically do) + because we told the user we'd use this name. + Instead, return and retry the download. */ + logprintf (LOG_NOTQUIET, _("%s has sprung into existence.\n"), + con->target); + fd_close (csock); + con->csock = -1; + fd_close (dtsock); + fd_close (local_sock); + return FOPEN_EXCL_ERR; + } + } + if (!fp) + { + logprintf (LOG_NOTQUIET, "%s: %s\n", con->target, strerror (errno)); + fd_close (csock); + con->csock = -1; + fd_close (dtsock); + fd_close (local_sock); + return FOPENERR; + } + } + else + fp = output_stream; + + if (passed_expected_bytes) + { + print_length (passed_expected_bytes, restval, true); + expected_bytes = passed_expected_bytes; + /* for fd_read_body's progress bar */ + } + else if (expected_bytes) + print_length (expected_bytes, restval, false); + +#ifdef HAVE_SSL + if (u->scheme == SCHEME_FTPS && using_data_security) + { + /* We should try to restore the existing SSL session in the data connection + * and fall back to establishing a new session if the server doesn't want to restore it. + */ + if (!opt.ftps_resume_ssl || !ssl_connect_wget (dtsock, u->host, &csock)) + { + if (opt.ftps_resume_ssl) + logputs (LOG_NOTQUIET, "Server does not want to resume the SSL session. Trying with a new one.\n"); + if (!ssl_connect_wget (dtsock, u->host, NULL)) + { + fd_close (csock); + fd_close (dtsock); + err = CONERROR; + logputs (LOG_NOTQUIET, "Could not perform SSL handshake.\n"); + goto exit_error; + } + } + else + logputs (LOG_NOTQUIET, "Resuming SSL session in data connection.\n"); + + if (!ssl_check_certificate (dtsock, u->host)) + { + fd_close (csock); + fd_close (dtsock); + err = CONERROR; + goto exit_error; + } + } +#endif + + /* Get the contents of the document. */ + flags = 0; + if (restval && rest_failed) + flags |= rb_skip_startpos; + rd_size = 0; + res = fd_read_body (con->target, dtsock, fp, + expected_bytes ? expected_bytes - restval : 0, + restval, &rd_size, qtyread, &con->dltime, flags, warc_tmp); + + tms = datetime_str (time (NULL)); + tmrate = retr_rate (rd_size, con->dltime); + total_download_time += con->dltime; + +#ifdef ENABLE_XATTR + if (opt.enable_xattr) + set_file_metadata (u, NULL, fp); +#endif + + fd_close (local_sock); + /* Close the local file. */ + if (!output_stream || con->cmd & DO_LIST) + fclose (fp); + + /* If fd_read_body couldn't write to fp or warc_tmp, bail out. */ + if (res == -2 || (warc_tmp != NULL && res == -3)) + { + logprintf (LOG_NOTQUIET, _("%s: %s, closing control connection.\n"), + con->target, strerror (errno)); + fd_close (csock); + con->csock = -1; + fd_close (dtsock); + if (res == -2) + return FWRITEERR; + else if (res == -3) + return WARC_TMP_FWRITEERR; + } + else if (res == -1) + { + logprintf (LOG_NOTQUIET, _("%s (%s) - Data connection: %s; "), + tms, tmrate, fd_errstr (dtsock)); + if (opt.server_response) + logputs (LOG_ALWAYS, "\n"); + } + fd_close (dtsock); + + /* Get the server to tell us if everything is retrieved. */ + err = ftp_response (csock, &respline); + if (err != FTPOK) + { + /* The control connection is decidedly closed. Print the time + only if it hasn't already been printed. */ + if (res != -1) + logprintf (LOG_NOTQUIET, "%s (%s) - ", tms, tmrate); + logputs (LOG_NOTQUIET, _("Control connection closed.\n")); + /* If there is an error on the control connection, close it, but + return FTPRETRINT, since there is a possibility that the + whole file was retrieved nevertheless (but that is for + ftp_loop_internal to decide). */ + fd_close (csock); + con->csock = -1; + return FTPRETRINT; + } /* err != FTPOK */ + *last_expected_bytes = ftp_expected_bytes (respline); + /* If retrieval failed for any reason, return FTPRETRINT, but do not + close socket, since the control connection is still alive. If + there is something wrong with the control connection, it will + become apparent later. */ + if (*respline != '2') + { + if (res != -1) + logprintf (LOG_NOTQUIET, "%s (%s) - ", tms, tmrate); + logputs (LOG_NOTQUIET, _("Data transfer aborted.\n")); +#ifdef HAVE_SSL + if (!c_strncasecmp (respline, "425", 3) && u->scheme == SCHEME_FTPS) + { + logputs (LOG_NOTQUIET, "FTPS server rejects new SSL sessions in the data connection.\n"); + xfree (respline); + return FTPRESTFAIL; + } +#endif + xfree (respline); + return FTPRETRINT; + } + xfree (respline); + + if (res == -1) + { + /* What now? The data connection was erroneous, whereas the + response says everything is OK. We shall play it safe. */ + return FTPRETRINT; + } + + if (!(cmd & LEAVE_PENDING)) + { + /* Closing the socket is faster than sending 'QUIT' and the + effect is the same. */ + fd_close (csock); + con->csock = -1; + } + /* If it was a listing, and opt.server_response is true, + print it out. */ + if (con->cmd & DO_LIST) + { + if (opt.server_response) + { +/* 2005-02-25 SMS. + Much of this work may already have been done, but repeating it should + do no damage beyond wasting time. +*/ +/* On VMS, alter the name as required. */ +#ifdef __VMS + char *targ; + + targ = ods_conform (con->target); + if (targ != con->target) + { + xfree (con->target); + con->target = targ; + } +#endif /* def __VMS */ + + mkalldirs (con->target); + fp = fopen (con->target, "r"); + if (!fp) + logprintf (LOG_ALWAYS, "%s: %s\n", con->target, strerror (errno)); + else + { + char *line = NULL; + size_t bufsize = 0; + ssize_t len; + + /* The lines are being read with getline because of + no-buffering on opt.lfile. */ + while ((len = getline (&line, &bufsize, fp)) > 0) + { + while (len > 0 && (line[len - 1] == '\n' || line[len - 1] == '\r')) + line[--len] = '\0'; + logprintf (LOG_ALWAYS, "%s\n", + quotearg_style (escape_quoting_style, line)); + } + xfree (line); + fclose (fp); + } + } /* server_response */ + + /* 2013-10-17 Andrea Urbani (matfanjol) + < __LIST_A_EXPLANATION__ > + After the SYST command, looks if it knows that system. + If yes, wget will force the use of "LIST" or "LIST -a". + If no, wget will try, only the first time of each session, before the + "LIST -a" command and after the "LIST". + If "LIST -a" works and returns more or equal data of the "LIST", + "LIST -a" will be the standard list command for all the session. + If "LIST -a" fails or returns less data than "LIST" (think on the case + of an existing file called "-a"), "LIST" will be the standard list + command for all the session. + ("LIST -a" is used to get also the hidden files) + + */ + if (!(con->st & LIST_AFTER_LIST_A_CHECK_DONE)) + { + /* We still have to check "LIST" after the first "LIST -a" to see + if with "LIST" we get more data than "LIST -a", that means + "LIST -a" returned files/folders with "-a" name. */ + if (con->st & AVOID_LIST_A) + { + /* LIST was used in this cycle. + Let's see the result. */ + if (rd_size > previous_rd_size) + { + /* LIST returns more data than "LIST -a". + "LIST" is the official command to use. */ + con->st |= LIST_AFTER_LIST_A_CHECK_DONE; + DEBUGP (("LIST returned more data than \"LIST -a\": " + "I will use \"LIST\" as standard list command\n")); + } + else if (previous_rd_size > rd_size) + { + /* "LIST -a" returned more data then LIST. + "LIST -a" is the official command to use. */ + con->st |= LIST_AFTER_LIST_A_CHECK_DONE; + con->st |= AVOID_LIST; + con->st &= ~AVOID_LIST_A; + /* Sorry, please, download again the "LIST -a"... */ + try_again = true; + DEBUGP (("LIST returned less data than \"LIST -a\": I will " + "use \"LIST -a\" as standard list command\n")); + } + else + { + /* LIST and "LIST -a" return the same data. */ + if (rd_size == 0) + { + /* Same empty data. We will check both again because + we cannot check if "LIST -a" has returned an empty + folder instead of a folder content. */ + con->st &= ~AVOID_LIST_A; + } + else + { + /* Same data, so, better to take "LIST -a" that + shows also hidden files/folders (when present) */ + con->st |= LIST_AFTER_LIST_A_CHECK_DONE; + con->st |= AVOID_LIST; + con->st &= ~AVOID_LIST_A; + DEBUGP (("LIST returned the same amount of data of " + "\"LIST -a\": I will use \"LIST -a\" as standard " + "list command\n")); + } + } + } + else + { + /* In this cycle "LIST -a" should being used. Is it true? */ + if (list_a_used) + { + /* Yes, it is. + OK, let's save the amount of data and try again + with LIST */ + previous_rd_size = rd_size; + try_again = true; + con->st |= AVOID_LIST_A; + } + else + { + /* No: something happens and LIST was used. + This means "LIST -a" raises an error. */ + con->st |= LIST_AFTER_LIST_A_CHECK_DONE; + con->st |= AVOID_LIST_A; + DEBUGP (("\"LIST -a\" failed: I will use \"LIST\" " + "as standard list command\n")); + } + } + } + } + } while (try_again); + return RETRFINISHED; + +exit_error: + + /* If fp is a regular file, close and try to remove it */ + if (fp && (!output_stream || con->cmd & DO_LIST)) + fclose (fp); + return err; +} + +/* A one-file FTP loop. This is the part where FTP retrieval is + retried, and retried, and retried, and... + + This loop either gets commands from con, or (if ON_YOUR_OWN is + set), makes them up to retrieve the file given by the URL. */ +static uerr_t +ftp_loop_internal (struct url *u, struct url *original_url, struct fileinfo *f, + ccon *con, char **local_file, bool force_full_retrieve) +{ + int count, orig_lp; + wgint restval, len = 0, qtyread = 0; + char *tms, *locf; + const char *tmrate = NULL; + uerr_t err; + struct stat st; + + /* Declare WARC variables. */ + bool warc_enabled = (opt.warc_filename != NULL); + FILE *warc_tmp = NULL; + ip_address warc_ip_buf, *warc_ip = NULL; + wgint last_expected_bytes = 0; + + /* Get the target, and set the name for the message accordingly. */ + if ((f == NULL) && (con->target)) + { + /* Explicit file (like ".listing"). */ + locf = con->target; + } + else + { + /* URL-derived file. Consider "-O file" name. */ + xfree (con->target); + con->target = url_file_name (opt.trustservernames || !original_url ? u : original_url, NULL); + if (!opt.output_document) + locf = con->target; + else + locf = opt.output_document; + } + + /* If the output_document was given, then this check was already done and + the file didn't exist. Hence the !opt.output_document */ + + /* If we receive .listing file it is necessary to determine system type of the ftp + server even if opn.noclobber is given. Thus we must ignore opt.noclobber in + order to establish connection with the server and get system type. */ + if (opt.noclobber && !opt.output_document && file_exists_p (con->target, NULL) + && !((con->cmd & DO_LIST) && !(con->cmd & DO_RETR))) + { + logprintf (LOG_VERBOSE, + _("File %s already there; not retrieving.\n"), quote (con->target)); + /* If the file is there, we suppose it's retrieved OK. */ + return RETROK; + } + + /* Remove it if it's a link. */ + remove_link (con->target); + + count = 0; + + if (con->st & ON_YOUR_OWN) + con->st = ON_YOUR_OWN; + + orig_lp = con->cmd & LEAVE_PENDING ? 1 : 0; + + /* THE loop. */ + do + { + /* Increment the pass counter. */ + ++count; + sleep_between_retrievals (count); + if (con->st & ON_YOUR_OWN) + { + con->cmd = 0; + con->cmd |= (DO_RETR | LEAVE_PENDING); + if (con->csock != -1) + con->cmd &= ~ (DO_LOGIN | DO_CWD); + else + con->cmd |= (DO_LOGIN | DO_CWD); + } + else /* not on your own */ + { + if (con->csock != -1) + con->cmd &= ~DO_LOGIN; + else + con->cmd |= DO_LOGIN; + if (con->st & DONE_CWD) + con->cmd &= ~DO_CWD; + else + con->cmd |= DO_CWD; + } + + /* For file RETR requests, we can write a WARC record. + We record the file contents to a temporary file. */ + if (warc_enabled && (con->cmd & DO_RETR) && warc_tmp == NULL) + { + warc_tmp = warc_tempfile (); + if (warc_tmp == NULL) + return WARC_TMP_FOPENERR; + + if (!con->proxy && con->csock != -1) + { + warc_ip = &warc_ip_buf; + socket_ip_address (con->csock, warc_ip, ENDPOINT_PEER); + } + } + + /* Decide whether or not to restart. */ + if (con->cmd & DO_LIST) + restval = 0; + else if (force_full_retrieve) + restval = 0; + else if (opt.start_pos >= 0) + restval = opt.start_pos; + else if (opt.always_rest + && stat (locf, &st) == 0 + && S_ISREG (st.st_mode)) + /* When -c is used, continue from on-disk size. (Can't use + hstat.len even if count>1 because we don't want a failed + first attempt to clobber existing data.) */ + restval = st.st_size; + else if (count > 1) + restval = qtyread; /* start where the previous run left off */ + else + restval = 0; + + /* Get the current time string. */ + tms = datetime_str (time (NULL)); + /* Print fetch message, if opt.verbose. */ + if (opt.verbose) + { + char *hurl = url_string (u, URL_AUTH_HIDE_PASSWD); + char tmp[256]; + strcpy (tmp, " "); + if (count > 1) + sprintf (tmp, _("(try:%2d)"), count); + logprintf (LOG_VERBOSE, "--%s-- %s\n %s => %s\n", + tms, hurl, tmp, quote (locf)); +#ifdef WINDOWS + ws_changetitle (hurl); +#endif + xfree (hurl); + } + /* Send getftp the proper length, if fileinfo was provided. */ + if (f && f->type != FT_SYMLINK) + len = f->size; + else + len = 0; + + /* If we are working on a WARC record, getftp should also write + to the warc_tmp file. */ + err = getftp (u, original_url, len, &qtyread, restval, con, count, + &last_expected_bytes, warc_tmp); + + if (con->csock == -1) + con->st &= ~DONE_CWD; + else + con->st |= DONE_CWD; + + switch (err) + { + case HOSTERR: case CONIMPOSSIBLE: case FWRITEERR: case FOPENERR: + case FTPNSFOD: case FTPLOGINC: case FTPNOPASV: case FTPNOAUTH: case FTPNOPBSZ: case FTPNOPROT: + case UNLINKERR: case WARC_TMP_FWRITEERR: case CONSSLERR: case CONTNOTSUPPORTED: + case VERIFCERTERR: +#ifdef HAVE_SSL + if (err == FTPNOAUTH) + logputs (LOG_NOTQUIET, "Server does not support AUTH TLS.\n"); + if (opt.ftps_implicit) + logputs (LOG_NOTQUIET, "Server does not like implicit FTPS connections.\n"); +#endif + /* Fatal errors, give up. */ + if (warc_tmp != NULL) + { + fclose (warc_tmp); + warc_tmp = NULL; + } + return err; + case CONSOCKERR: case CONERROR: case FTPSRVERR: case FTPRERR: + case WRITEFAILED: case FTPUNKNOWNTYPE: case FTPSYSERR: + case FTPPORTERR: case FTPLOGREFUSED: case FTPINVPASV: + case FOPEN_EXCL_ERR: + printwhat (count, opt.ntry); + /* non-fatal errors */ + if (err == FOPEN_EXCL_ERR) + { + /* Re-determine the file name. */ + xfree (con->target); + con->target = url_file_name (u, NULL); + locf = con->target; + } + continue; + case FTPRETRINT: + /* If the control connection was closed, the retrieval + will be considered OK if f->size == len. */ + if (!f || qtyread != f->size) + { + printwhat (count, opt.ntry); + continue; + } + break; + case RETRFINISHED: + /* Great! */ + break; + default: + /* Not as great. */ + abort (); + } + tms = datetime_str (time (NULL)); + if (!opt.spider) + tmrate = retr_rate (qtyread - restval, con->dltime); + + /* If we get out of the switch above without continue'ing, we've + successfully downloaded a file. Remember this fact. */ + downloaded_file (FILE_DOWNLOADED_NORMALLY, locf); + + if (con->st & ON_YOUR_OWN) + { + fd_close (con->csock); + con->csock = -1; + } + if (!opt.spider) + { + bool write_to_stdout = (opt.output_document && HYPHENP (opt.output_document)); + + logprintf (LOG_VERBOSE, + write_to_stdout + ? _("%s (%s) - written to stdout %s[%s]\n\n") + : _("%s (%s) - %s saved [%s]\n\n"), + tms, tmrate, + write_to_stdout ? "" : quote (locf), + number_to_static_string (qtyread)); + } + if (!opt.verbose && !opt.quiet) + { + /* Need to hide the password from the URL. The `if' is here + so that we don't do the needless allocation every + time. */ + char *hurl = url_string (u, URL_AUTH_HIDE_PASSWD); + logprintf (LOG_NONVERBOSE, "%s URL: %s [%s] -> \"%s\" [%d]\n", + tms, hurl, number_to_static_string (qtyread), locf, count); + xfree (hurl); + } + + if (warc_enabled && (con->cmd & DO_RETR)) + { + /* Create and store a WARC resource record for the retrieved file. */ + bool warc_res; + + warc_res = warc_write_resource_record (NULL, u->url, NULL, NULL, + warc_ip, NULL, warc_tmp, -1); + + if (! warc_res) + return WARC_ERR; + + /* warc_write_resource_record has also closed warc_tmp. */ + warc_tmp = NULL; + } + + if (con->cmd & DO_LIST) + /* This is a directory listing file. */ + { + if (!opt.remove_listing) + /* --dont-remove-listing was specified, so do count this towards the + number of bytes and files downloaded. */ + { + total_downloaded_bytes += qtyread; + numurls++; + } + + /* Deletion of listing files is not controlled by --delete-after, but + by the more specific option --dont-remove-listing, and the code + to do this deletion is in another function. */ + } + else if (!opt.spider) + /* This is not a directory listing file. */ + { + /* Unlike directory listing files, don't pretend normal files weren't + downloaded if they're going to be deleted. People seeding proxies, + for instance, may want to know how many bytes and files they've + downloaded through it. */ + total_downloaded_bytes += qtyread; + numurls++; + + if (opt.delete_after && !input_file_url (opt.input_filename)) + { + DEBUGP (("\ +Removing file due to --delete-after in ftp_loop_internal():\n")); + logprintf (LOG_VERBOSE, _("Removing %s.\n"), locf); + if (unlink (locf)) + logprintf (LOG_NOTQUIET, "unlink: %s\n", strerror (errno)); + } + } + + /* Restore the original leave-pendingness. */ + if (orig_lp) + con->cmd |= LEAVE_PENDING; + else + con->cmd &= ~LEAVE_PENDING; + + if (local_file) + *local_file = xstrdup (locf); + + if (warc_tmp != NULL) + { + fclose (warc_tmp); + warc_tmp = NULL; + } + + return RETROK; + } while (!opt.ntry || (count < opt.ntry)); + + if (con->csock != -1 && (con->st & ON_YOUR_OWN)) + { + fd_close (con->csock); + con->csock = -1; + } + + if (warc_tmp != NULL) + fclose (warc_tmp); + + return TRYLIMEXC; +} + +/* Return the directory listing in a reusable format. The directory + is specified in u->dir. */ +static uerr_t +ftp_get_listing (struct url *u, struct url *original_url, ccon *con, + struct fileinfo **f) +{ + uerr_t err; + char *uf; /* url file name */ + char *lf; /* list file name */ + char *old_target = con->target; + + con->st &= ~ON_YOUR_OWN; + con->cmd |= (DO_LIST | LEAVE_PENDING); + con->cmd &= ~DO_RETR; + + /* Find the listing file name. We do it by taking the file name of + the URL and replacing the last component with the listing file + name. */ + uf = url_file_name (u, NULL); + lf = file_merge (uf, LIST_FILENAME); + xfree (uf); + DEBUGP ((_("Using %s as listing tmp file.\n"), quote (lf))); + + con->target = xstrdup (lf); + xfree (lf); + err = ftp_loop_internal (u, original_url, NULL, con, NULL, false); + lf = xstrdup (con->target); + xfree (con->target); + con->target = old_target; + + if (err == RETROK) + { + *f = ftp_parse_ls (lf, con->rs); + if (opt.remove_listing) + { + if (unlink (lf)) + logprintf (LOG_NOTQUIET, "unlink: %s\n", strerror (errno)); + else + logprintf (LOG_VERBOSE, _("Removed %s.\n"), quote (lf)); + } + } + else + *f = NULL; + xfree (lf); + con->cmd &= ~DO_LIST; + return err; +} + +static uerr_t ftp_retrieve_dirs (struct url *, struct url *, + struct fileinfo *, ccon *); +static uerr_t ftp_retrieve_glob (struct url *, struct url *, ccon *, int); +static struct fileinfo *delelement (struct fileinfo **, struct fileinfo **); + +/* Retrieve a list of files given in struct fileinfo linked list. If + a file is a symbolic link, do not retrieve it, but rather try to + set up a similar link on the local disk, if the symlinks are + supported. + + If opt.recursive is set, after all files have been retrieved, + ftp_retrieve_dirs will be called to retrieve the directories. */ +static uerr_t +ftp_retrieve_list (struct url *u, struct url *original_url, + struct fileinfo *f, ccon *con) +{ + static int depth = 0; + uerr_t err; + struct fileinfo *orig; + wgint local_size; + time_t tml; + bool dlthis; /* Download this (file). */ + const char *actual_target = NULL; + bool force_full_retrieve = false; + + /* Increase the depth. */ + ++depth; + if (opt.reclevel != INFINITE_RECURSION && depth > opt.reclevel) + { + DEBUGP ((_("Recursion depth %d exceeded max. depth %d.\n"), + depth, opt.reclevel)); + --depth; + return RECLEVELEXC; + } + + assert (f != NULL); + orig = f; + + con->st &= ~ON_YOUR_OWN; + if (!(con->st & DONE_CWD)) + con->cmd |= DO_CWD; + else + con->cmd &= ~DO_CWD; + con->cmd |= (DO_RETR | LEAVE_PENDING); + + if (con->csock < 0) + con->cmd |= DO_LOGIN; + else + con->cmd &= ~DO_LOGIN; + + err = RETROK; /* in case it's not used */ + + while (f) + { + char *old_target, *ofile; + + if (opt.quota && total_downloaded_bytes > opt.quota) + { + --depth; + return QUOTEXC; + } + old_target = con->target; + + ofile = xstrdup (u->file); + url_set_file (u, f->name); + + con->target = url_file_name (u, NULL); + err = RETROK; + + dlthis = true; + if (opt.timestamping && f->type == FT_PLAINFILE) + { + struct stat st; + /* If conversion of HTML files retrieved via FTP is ever implemented, + we'll need to stat() .orig here when -K has been specified. + I'm not implementing it now since files on an FTP server are much + more likely than files on an HTTP server to legitimately have a + .orig suffix. */ + if (!stat (con->target, &st)) + { + bool eq_size; + bool cor_val; + /* Else, get it from the file. */ + local_size = st.st_size; + tml = st.st_mtime; +#ifdef WINDOWS + /* Modification time granularity is 2 seconds for Windows, so + increase local time by 1 second for later comparison. */ + tml++; +#endif + /* Compare file sizes only for servers that tell us correct + values. Assume sizes being equal for servers that lie + about file size. */ + cor_val = (con->rs == ST_UNIX || con->rs == ST_WINNT); + eq_size = cor_val ? (local_size == f->size) : true; + if (f->tstamp <= tml && eq_size) + { + /* Remote file is older, file sizes can be compared and + are both equal. */ + logprintf (LOG_VERBOSE, _("\ +Remote file no newer than local file %s -- not retrieving.\n"), quote (con->target)); + dlthis = false; + } + else if (f->tstamp > tml) + { + /* Remote file is newer */ + force_full_retrieve = true; + logprintf (LOG_VERBOSE, _("\ +Remote file is newer than local file %s -- retrieving.\n\n"), + quote (con->target)); + } + else + { + /* Sizes do not match */ + logprintf (LOG_VERBOSE, _("\ +The sizes do not match (local %s) -- retrieving.\n\n"), + number_to_static_string (local_size)); + } + } + } /* opt.timestamping && f->type == FT_PLAINFILE */ + switch (f->type) + { + case FT_SYMLINK: + /* If opt.retr_symlinks is defined, we treat symlinks as + if they were normal files. There is currently no way + to distinguish whether they might be directories, and + follow them. */ + if (!opt.retr_symlinks) + { +#ifdef HAVE_SYMLINK + if (!f->linkto) + logputs (LOG_NOTQUIET, + _("Invalid name of the symlink, skipping.\n")); + else + { + struct stat st; + /* Check whether we already have the correct + symbolic link. */ + int rc = lstat (con->target, &st); + if (rc == 0) + { + size_t len = strlen (f->linkto) + 1; + if (S_ISLNK (st.st_mode)) + { + char buf[1024], *link_target; + size_t n; + bool res; + + if (len < sizeof (buf)) + link_target = buf; + else + link_target = xmalloc (len); + + n = readlink (con->target, link_target, len); + res = (n == len - 1) && (memcmp (link_target, f->linkto, n) == 0); + + if (link_target != buf) + xfree (link_target); + + if (res) + { + logprintf (LOG_VERBOSE, _("\ +Already have correct symlink %s -> %s\n\n"), + quote (con->target), + quote (f->linkto)); + dlthis = false; + break; + } + } + } + logprintf (LOG_VERBOSE, _("Creating symlink %s -> %s\n"), + quote (con->target), quote (f->linkto)); + /* Unlink before creating symlink! */ + unlink (con->target); + if (symlink (f->linkto, con->target) == -1) + logprintf (LOG_NOTQUIET, "symlink: %s\n", strerror (errno)); + logputs (LOG_VERBOSE, "\n"); + } /* have f->linkto */ +#else /* not HAVE_SYMLINK */ + logprintf (LOG_NOTQUIET, + _("Symlinks not supported, skipping symlink %s.\n"), + quote (con->target)); +#endif /* not HAVE_SYMLINK */ + } + else /* opt.retr_symlinks */ + { + if (dlthis) + { + err = ftp_loop_internal (u, original_url, f, con, NULL, + force_full_retrieve); + } + } /* opt.retr_symlinks */ + break; + case FT_DIRECTORY: + if (!opt.recursive) + logprintf (LOG_NOTQUIET, _("Skipping directory %s.\n"), + quote (f->name)); + break; + case FT_PLAINFILE: + /* Call the retrieve loop. */ + if (dlthis) + { + err = ftp_loop_internal (u, original_url, f, con, NULL, + force_full_retrieve); + } + break; + case FT_UNKNOWN: + default: + logprintf (LOG_NOTQUIET, _("%s: unknown/unsupported file type.\n"), + quote (f->name)); + break; + } /* switch */ + + + /* 2004-12-15 SMS. + * Set permissions _before_ setting the times, as setting the + * permissions changes the modified-time, at least on VMS. + * Also, use the opt.output_document name here, too, as + * appropriate. (Do the test once, and save the result.) + */ + + set_local_file (&actual_target, con->target); + + /* If downloading a plain file, and the user requested it, then + set valid (non-zero) permissions. */ + if (dlthis && (actual_target != NULL) && + (f->type == FT_PLAINFILE) && opt.preserve_perm) + { + if (f->perms) + { + if (chmod (actual_target, f->perms)) + logprintf (LOG_NOTQUIET, + _("Failed to set permissions for %s.\n"), + actual_target); + } + else + DEBUGP (("Unrecognized permissions for %s.\n", actual_target)); + } + + /* Set the time-stamp information to the local file. Symlinks + are not to be stamped because it sets the stamp on the + original. :( */ + if (actual_target != NULL) + { + if (opt.useservertimestamps + && !(f->type == FT_SYMLINK && !opt.retr_symlinks) + && f->tstamp != -1 + && dlthis + && file_exists_p (con->target, NULL)) + { + touch (actual_target, f->tstamp); + } + else if (f->tstamp == -1) + logprintf (LOG_NOTQUIET, _("%s: corrupt time-stamp.\n"), + actual_target); + } + + xfree (con->target); + con->target = old_target; + + url_set_file (u, ofile); + xfree (ofile); + + /* Break on fatals. */ + if (err == QUOTEXC || err == HOSTERR || err == FWRITEERR + || err == WARC_ERR || err == WARC_TMP_FOPENERR + || err == WARC_TMP_FWRITEERR) + break; + con->cmd &= ~ (DO_CWD | DO_LOGIN); + f = f->next; + } + + /* We do not want to call ftp_retrieve_dirs here */ + if (opt.recursive && + !(opt.reclevel != INFINITE_RECURSION && depth >= opt.reclevel)) + err = ftp_retrieve_dirs (u, original_url, orig, con); + else if (opt.recursive) + DEBUGP ((_("Will not retrieve dirs since depth is %d (max %d).\n"), + depth, opt.reclevel)); + --depth; + return err; +} + +/* Retrieve the directories given in a file list. This function works + by simply going through the linked list and calling + ftp_retrieve_glob on each directory entry. The function knows + about excluded directories. */ +static uerr_t +ftp_retrieve_dirs (struct url *u, struct url *original_url, + struct fileinfo *f, ccon *con) +{ + char buf[1024]; + char *container = buf; + int container_size = sizeof (buf); + + for (; f; f = f->next) + { + int size; + char *odir, *newdir; + + if (opt.quota && total_downloaded_bytes > opt.quota) + break; + if (f->type != FT_DIRECTORY) + continue; + + /* Allocate u->dir off stack, but reallocate only if a larger + string is needed. It's a pity there's no "realloca" for an + item on the bottom of the stack. */ + size = strlen (u->dir) + 1 + strlen (f->name) + 1; + if (size > container_size) + { + if (container == buf) + container = xmalloc (size); + else + container = xrealloc (container, size); + + container_size = size; + } + newdir = container; + + odir = u->dir; + if (*odir == '\0' + || (*odir == '/' && *(odir + 1) == '\0')) + /* If ODIR is empty or just "/", simply append f->name to + ODIR. (In the former case, to preserve u->dir being + relative; in the latter case, to avoid double slash.) */ + sprintf (newdir, "%s%s", odir, f->name); + else + /* Else, use a separator. */ + sprintf (newdir, "%s/%s", odir, f->name); + + DEBUGP (("Composing new CWD relative to the initial directory.\n")); + DEBUGP ((" odir = '%s'\n f->name = '%s'\n newdir = '%s'\n\n", + odir, f->name, newdir)); + if (!accdir (newdir)) + { + logprintf (LOG_VERBOSE, _("\ +Not descending to %s as it is excluded/not-included.\n"), + quote (newdir)); + continue; + } + + con->st &= ~DONE_CWD; + + odir = xstrdup (u->dir); /* because url_set_dir will free + u->dir. */ + url_set_dir (u, newdir); + ftp_retrieve_glob (u, original_url, con, GLOB_GETALL); + url_set_dir (u, odir); + xfree (odir); + + /* Set the time-stamp? */ + } + + if (container != buf) + xfree (container); + + if (opt.quota && total_downloaded_bytes > opt.quota) + return QUOTEXC; + else + return RETROK; +} + +/* Return true if S has a leading '/' or contains '../' */ +static bool +has_insecure_name_p (const char *s) +{ + if (*s == '/') + return true; + + if (strstr (s, "../") != 0) + return true; + + return false; +} + +/* Test if the file node is invalid. This can occur due to malformed or + * maliciously crafted listing files being returned by the server. + * + * Currently, this function only tests if there are multiple entries in the + * listing file by the same name. However this function can be expanded as more + * such illegal listing formats are discovered. */ +static bool +is_invalid_entry (struct fileinfo *f) +{ + struct fileinfo *cur = f; + char *f_name = f->name; + + /* If the node we're currently checking has a duplicate later, we eliminate + * the current node and leave the next one intact. */ + while (cur->next) + { + cur = cur->next; + if (strcmp (f_name, cur->name) == 0) + return true; + } + return false; +} + +/* A near-top-level function to retrieve the files in a directory. + The function calls ftp_get_listing, to get a linked list of files. + Then it weeds out the file names that do not match the pattern. + ftp_retrieve_list is called with this updated list as an argument. + + If the argument ACTION is GLOB_GETONE, just download the file (but + first get the listing, so that the time-stamp is heeded); if it's + GLOB_GLOBALL, use globbing; if it's GLOB_GETALL, download the whole + directory. */ +static uerr_t +ftp_retrieve_glob (struct url *u, struct url *original_url, + ccon *con, int action) +{ + struct fileinfo *f, *start; + uerr_t res; + + con->cmd |= LEAVE_PENDING; + + res = ftp_get_listing (u, original_url, con, &start); + if (res != RETROK) + return res; + + // Set the function used for glob matching. + int (*matcher) (const char *, const char *, int) + = opt.ignore_case ? fnmatch_nocase : fnmatch; + + // Set the function used to compare strings +#ifdef __VMS + /* 2009-09-09 SMS. + * Odd-ball compiler ("HP C V7.3-009 on OpenVMS Alpha V7.3-2") + * bug causes spurious %CC-E-BADCONDIT complaint with this + * "?:" statement. (Different linkage attributes for strcmp() + * and strcasecmp().) Converting to "if" changes the + * complaint to %CC-W-PTRMISMATCH on "cmp = strcmp;". Adding + * the senseless type cast clears the complaint, and looks + * harmless. + */ + int (*cmp) (const char *, const char *) + = opt.ignore_case ? strcasecmp : (int (*)())strcmp; +#else /* def __VMS */ + int (*cmp) (const char *, const char *) + = opt.ignore_case ? strcasecmp : strcmp; +#endif /* def __VMS [else] */ + + f = start; + while (f) + { + + // Weed out files that do not confirm to the global rules given in + // opt.accepts and opt.rejects + if ((opt.accepts || opt.rejects) && + f->type != FT_DIRECTORY && !acceptable (f->name)) + { + logprintf (LOG_VERBOSE, _("Rejecting %s.\n"), + quote (f->name)); + f = delelement (&f, &start); + continue; + } + + + // Identify and eliminate possibly harmful names or invalid entries. + if (has_insecure_name_p (f->name) || is_invalid_entry (f)) + { + logprintf (LOG_VERBOSE, _("Rejecting %s (Invalid Entry).\n"), + quote (f->name)); + f = delelement (&f, &start); + continue; + } + + if (opt.acceptregex || opt.rejectregex) + { + // accept_url() takes the full URL. + char buf[1024]; + char *url = buf; + + if ((unsigned) snprintf(buf, sizeof(buf), "%s%s%s", + u->url, f->name, f->type == FT_DIRECTORY ? "/" : "") + >= sizeof(buf)) + { + url = aprintf("%s%s%s", u->url, f->name, f->type == FT_DIRECTORY ? "/" : ""); + } + + if (!accept_url (url)) + { + logprintf (LOG_VERBOSE, _ ("%s is excluded/not-included through regex.\n"), url); + f = delelement (&f, &start); + if (url != buf) + xfree(url); + continue; + } + + if (url != buf) + xfree(url); + } + + /* Now weed out the files that do not match our globbing pattern. + If we are dealing with a globbing pattern, that is. */ + if (*u->file) + { + if (action == GLOB_GLOBALL) + { + int matchres = matcher (u->file, f->name, 0); + if (matchres == -1) + { + logprintf (LOG_NOTQUIET, _("Error matching %s against %s: %s\n"), + u->file, quotearg_style (escape_quoting_style, f->name), + strerror (errno)); + freefileinfo (start); + return RETRBADPATTERN; + } + if (matchres == FNM_NOMATCH) + { + f = delelement (&f, &start); /* delete the element from the list */ + continue; + } + } + else if (action == GLOB_GETONE) + { + if (0 != cmp(u->file, f->name)) + { + f = delelement (&f, &start); + continue; + } + } + } + f = f->next; + } + + /* + * Now that preprocessing of the file listing is over, let's try to download + * all the remaining files in our listing. + */ + if (start) + { + /* Just get everything. */ + res = ftp_retrieve_list (u, original_url, start, con); + } + else + { + if (action == GLOB_GLOBALL) + { + /* No luck. */ + /* #### This message SUCKS. We should see what was the + reason that nothing was retrieved. */ + logprintf (LOG_VERBOSE, _("No matches on pattern %s.\n"), + quote (u->file)); + } + else if (action == GLOB_GETONE) /* GLOB_GETONE or GLOB_GETALL */ + { + /* Let's try retrieving it anyway. */ + con->st |= ON_YOUR_OWN; + res = ftp_loop_internal (u, original_url, NULL, con, NULL, false); + return res; + } + + /* If action == GLOB_GETALL, and the file list is empty, there's + no point in trying to download anything or in complaining about + it. (An empty directory should not cause complaints.) + */ + } + freefileinfo (start); + if (opt.quota && total_downloaded_bytes > opt.quota) + return QUOTEXC; + else + return res; +} + +/* The wrapper that calls an appropriate routine according to contents + of URL. Inherently, its capabilities are limited on what can be + encoded into a URL. */ +uerr_t +ftp_loop (struct url *u, struct url *original_url, char **local_file, int *dt, + struct url *proxy, bool recursive, bool glob) +{ + ccon con; /* FTP connection */ + uerr_t res; + + *dt = 0; + + xzero (con); + + con.csock = -1; + con.st = ON_YOUR_OWN; + con.rs = ST_UNIX; + con.id = NULL; + con.proxy = proxy; + + /* If the file name is empty, the user probably wants a directory + index. We'll provide one, properly HTML-ized. Unless + opt.htmlify is 0, of course. :-) */ + if (!*u->file && !recursive) + { + struct fileinfo *f; + res = ftp_get_listing (u, original_url, &con, &f); + + if (res == RETROK) + { + if (opt.htmlify && !opt.spider) + { + struct url *url_file = opt.trustservernames ? u : original_url; + char *filename = (opt.output_document + ? xstrdup (opt.output_document) + : (con.target ? xstrdup (con.target) + : url_file_name (url_file, NULL))); + res = ftp_index (filename, u, f); + if (res == FTPOK && opt.verbose) + { + if (!opt.output_document) + { + struct stat st; + wgint sz; + if (stat (filename, &st) == 0) + sz = st.st_size; + else + sz = -1; + logprintf (LOG_NOTQUIET, + _("Wrote HTML-ized index to %s [%s].\n"), + quote (filename), number_to_static_string (sz)); + } + else + logprintf (LOG_NOTQUIET, + _("Wrote HTML-ized index to %s.\n"), + quote (filename)); + } + xfree (filename); + } + freefileinfo (f); + } + } + else + { + bool ispattern = false; + if (glob) + { + /* Treat the URL as a pattern if the file name part of the + URL path contains wildcards. (Don't check for u->file + because it is unescaped and therefore doesn't leave users + the option to escape literal '*' as %2A.) */ + char *file_part = strrchr (u->path, '/'); + if (!file_part) + file_part = u->path; + ispattern = has_wildcards_p (file_part); + } + if (ispattern || recursive || opt.timestamping || opt.preserve_perm) + { + /* ftp_retrieve_glob is a catch-all function that gets called + if we need globbing, time-stamping, recursion or preserve + permissions. Its third argument is just what we really need. */ + res = ftp_retrieve_glob (u, original_url, &con, + ispattern ? GLOB_GLOBALL : GLOB_GETONE); + } + else + { + res = ftp_loop_internal (u, original_url, NULL, &con, local_file, false); + } + } + if (res == FTPOK) + res = RETROK; + if (res == RETROK) + *dt |= RETROKF; + /* If a connection was left, quench it. */ + if (con.csock != -1) + fd_close (con.csock); + xfree (con.id); + xfree (con.target); + return res; +} + +/* Delete an element from the fileinfo linked list. Returns the + address of the next element, or NULL if the list is exhausted. It + can modify the start of the list. */ +static struct fileinfo * +delelement (struct fileinfo **f, struct fileinfo **start) +{ + struct fileinfo *prev = (*f)->prev; + struct fileinfo *next = (*f)->next; + + xfree ((*f)->name); + xfree ((*f)->linkto); + xfree (*f); + *f = NULL; + + if (next) + next->prev = prev; + if (prev) + prev->next = next; + else + *start = next; + return next; +} + +/* Free the fileinfo linked list of files. */ +void +freefileinfo (struct fileinfo *f) +{ + while (f) + { + struct fileinfo *next = f->next; + xfree (f->name); + if (f->linkto) + xfree (f->linkto); + xfree (f); + f = next; + } +} diff --git a/src/ftp.h b/src/ftp.h new file mode 100644 index 0000000..9958853 --- /dev/null +++ b/src/ftp.h @@ -0,0 +1,184 @@ +/* Declarations for FTP support. + Copyright (C) 1996-2011, 2015, 2018-2020 Free Software Foundation, + Inc. + +This file is part of GNU Wget. + +GNU Wget is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 3 of the License, or +(at your option) any later version. + +GNU Wget 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 Wget. If not, see . + +Additional permission under GNU GPL version 3 section 7 + +If you modify this program, or any covered work, by linking or +combining it with the OpenSSL project's OpenSSL library (or a +modified version of that library), containing parts covered by the +terms of the OpenSSL or SSLeay licenses, the Free Software Foundation +grants you additional permission to convey the resulting work. +Corresponding Source for a non-source form of such a combination +shall include the source code for the parts of OpenSSL used as well +as that of the covered work. */ + +#ifndef FTP_H +#define FTP_H + +#include +#include + +#include "host.h" +#include "url.h" + +/* System types. */ +enum stype +{ + ST_UNIX, + ST_VMS, + ST_WINNT, + ST_MACOS, + ST_OS400, + ST_OTHER +}; + +/* Extensions of the ST_UNIX */ +enum ustype +{ + UST_TYPE_L8, + UST_MULTINET, + UST_OTHER +}; + +#ifdef HAVE_SSL +/* Data channel protection levels (to be used with PBSZ) */ +enum prot_level +{ + PROT_CLEAR = 'C', + PROT_SAFE = 'S', + PROT_CONFIDENTIAL = 'E', + PROT_PRIVATE = 'P' +}; +#endif + +uerr_t ftp_response (int, char **); +uerr_t ftp_greeting (int); +uerr_t ftp_login (int, const char *, const char *); +uerr_t ftp_port (int, int *); +uerr_t ftp_pasv (int, ip_address *, int *); +#ifdef HAVE_SSL +uerr_t ftp_auth (int, enum url_scheme); +uerr_t ftp_pbsz (int, int); +uerr_t ftp_prot (int, enum prot_level); +#endif +#ifdef ENABLE_IPV6 +uerr_t ftp_lprt (int, int *); +uerr_t ftp_lpsv (int, ip_address *, int *); +uerr_t ftp_eprt (int, int *); +uerr_t ftp_epsv (int, ip_address *, int *); +#endif +uerr_t ftp_type (int, int); +uerr_t ftp_cwd (int, const char *); +uerr_t ftp_retr (int, const char *); +uerr_t ftp_rest (int, wgint); +uerr_t ftp_list (int, const char *, bool, bool, bool *); +uerr_t ftp_syst (int, enum stype *, enum ustype *); +uerr_t ftp_pwd (int, char **); +uerr_t ftp_size (int, const char *, wgint *); + +#ifdef ENABLE_OPIE +const char *skey_response (int, const char *, const char *); +#endif + +struct url; + +/* File types. */ +enum ftype +{ + FT_PLAINFILE, + FT_DIRECTORY, + FT_SYMLINK, + FT_UNKNOWN +}; + + +/* Globbing (used by ftp_retrieve_glob). */ +enum +{ + GLOB_GLOBALL, GLOB_GETALL, GLOB_GETONE +}; + +/* Used by to test if time parsed includes hours and minutes. */ +enum parsetype +{ + TT_HOUR_MIN, TT_DAY +}; + + +/* Information about one filename in a linked list. */ +struct fileinfo +{ + enum ftype type; /* file type */ + char *name; /* file name */ + wgint size; /* file size */ + long tstamp; /* time-stamp */ + enum parsetype ptype; /* time parsing */ + int perms; /* file permissions */ + char *linkto; /* link to which file points */ + struct fileinfo *prev; /* previous... */ + struct fileinfo *next; /* ...and next structure. */ +}; + +/* Commands for FTP functions. */ +enum wget_ftp_command +{ + DO_LOGIN = 0x0001, /* Connect and login to the server. */ + DO_CWD = 0x0002, /* Change current directory. */ + DO_RETR = 0x0004, /* Retrieve the file. */ + DO_LIST = 0x0008, /* Retrieve the directory list. */ + LEAVE_PENDING = 0x0010 /* Do not close the socket. */ +}; + +enum wget_ftp_fstatus +{ + NOTHING = 0x0000, /* Nothing done yet. */ + ON_YOUR_OWN = 0x0001, /* The ftp_loop_internal sets the + defaults. */ + DONE_CWD = 0x0002, /* The current working directory is + correct. */ + + /* 2013-10-17 Andrea Urbani (matfanjol) + For more information about the following entries, please, + look at ftp.c, function getftp, text "__LIST_A_EXPLANATION__". */ + AVOID_LIST_A = 0x0004, /* It tells us if during this + session we have to avoid the use + of "LIST -a".*/ + AVOID_LIST = 0x0008, /* It tells us if during this + session we have to avoid to use + "LIST". */ + LIST_AFTER_LIST_A_CHECK_DONE = 0x0010, + /* It tells us if we have already + checked "LIST" after the first + "LIST -a" to handle the case of + file/folders named "-a". */ + DATA_CHANNEL_SECURITY = 0x0020 /* Establish a secure data channel */ +}; + +struct fileinfo *ftp_parse_ls (const char *, const enum stype); +struct fileinfo *ftp_parse_ls_fp (FILE *, const enum stype); +void freefileinfo(struct fileinfo *); +uerr_t ftp_loop (struct url *, struct url *, char **, int *, struct url *, + bool, bool); + +uerr_t ftp_index (const char *, struct url *, struct fileinfo *); + +char ftp_process_type (const char *); + + +#endif /* FTP_H */ diff --git a/src/gnutls.c b/src/gnutls.c new file mode 100644 index 0000000..5706dbb --- /dev/null +++ b/src/gnutls.c @@ -0,0 +1,1116 @@ +/* SSL support via GnuTLS library. + Copyright (C) 2005-2012, 2015, 2018-2020 Free Software Foundation, + Inc. + +This file is part of GNU Wget. + +GNU Wget is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 3 of the License, or +(at your option) any later version. + +GNU Wget 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 Wget. If not, see . + +Additional permission under GNU GPL version 3 section 7 + +If you modify this program, or any covered work, by linking or +combining it with the OpenSSL project's OpenSSL library (or a +modified version of that library), containing parts covered by the +terms of the OpenSSL or SSLeay licenses, the Free Software Foundation +grants you additional permission to convey the resulting work. +Corresponding Source for a non-source form of such a combination +shall include the source code for the parts of OpenSSL used as well +as that of the covered work. */ + +#include "wget.h" + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "utils.h" +#include "connect.h" +#include "url.h" +#include "ptimer.h" +#include "hash.h" +#include "ssl.h" + +#include + +#ifdef WIN32 +# include "w32sock.h" +#endif + +#include "host.h" + +struct st_read_timer +{ + double timeout; + double next_timeout; + struct ptimer *timer; + int timed_out; +}; + +static int +_do_handshake (gnutls_session_t session, int fd, struct st_read_timer *timeout); + +#if GNUTLS_VERSION_NUMBER >= 0x030604 +static int +_do_reauth (gnutls_session_t session, int fd, struct st_read_timer *timeout); +#endif + +static int +key_type_to_gnutls_type (enum keyfile_type type) +{ + switch (type) + { + case keyfile_pem: + return GNUTLS_X509_FMT_PEM; + case keyfile_asn1: + return GNUTLS_X509_FMT_DER; + default: + abort (); + } +} + +/* Note: some of the functions private to this file have names that + begin with "wgnutls_" (e.g. wgnutls_read) so that they wouldn't be + confused with actual gnutls functions -- such as the gnutls_read + preprocessor macro. */ + +static gnutls_certificate_credentials_t credentials; +bool +ssl_init (void) +{ + /* Becomes true if GnuTLS is initialized. */ + static bool ssl_initialized = false; + const char *ca_directory; + DIR *dir; + int ncerts = -1; + int rc; + + /* GnuTLS should be initialized only once. */ + if (ssl_initialized) + return true; + + gnutls_global_init (); + gnutls_certificate_allocate_credentials (&credentials); + gnutls_certificate_set_verify_flags (credentials, + GNUTLS_VERIFY_ALLOW_X509_V1_CA_CRT); + +#if GNUTLS_VERSION_MAJOR >= 3 + if (!opt.ca_directory) + ncerts = gnutls_certificate_set_x509_system_trust (credentials); +#endif + + /* If GnuTLS version is too old or CA loading failed, fallback to old behaviour. + * Also use old behaviour if the CA directory is user-provided. */ + if (ncerts <= 0) + { + ncerts = 0; + + ca_directory = opt.ca_directory ? opt.ca_directory : "/etc/ssl/certs"; + + if ((dir = opendir (ca_directory)) == NULL) + { + if (opt.ca_directory && *opt.ca_directory) + logprintf (LOG_NOTQUIET, _("ERROR: Cannot open directory %s.\n"), + opt.ca_directory); + } + else + { + struct hash_table *inode_map = hash_table_new (196, NULL, NULL); + struct dirent *dent; + + while ((dent = readdir (dir)) != NULL) + { + struct stat st; + char ca_file[1024]; + + if (((unsigned) snprintf (ca_file, sizeof (ca_file), "%s/%s", ca_directory, dent->d_name)) >= sizeof (ca_file)) + continue; // overflow + + if (stat (ca_file, &st) != 0) + continue; + + if (! S_ISREG (st.st_mode)) + continue; + + /* avoid loading the same file twice by checking the inode. */ + if (hash_table_contains (inode_map, (void *)(intptr_t) st.st_ino)) + continue; + + hash_table_put (inode_map, (void *)(intptr_t) st.st_ino, NULL); + if ((rc = gnutls_certificate_set_x509_trust_file (credentials, ca_file, + GNUTLS_X509_FMT_PEM)) <= 0) + DEBUGP (("WARNING: Failed to open cert %s: (%d).\n", ca_file, rc)); + else + ncerts += rc; + } + + hash_table_destroy (inode_map); + closedir (dir); + } + } + + if (opt.ca_cert) + { + if (ncerts < 0) + ncerts = 0; + + if ((rc = gnutls_certificate_set_x509_trust_file (credentials, opt.ca_cert, + GNUTLS_X509_FMT_PEM)) <= 0) + logprintf (LOG_NOTQUIET, _("ERROR: Failed to open cert %s: (%d).\n"), + opt.ca_cert, rc); + else + { + ncerts += rc; + logprintf (LOG_VERBOSE, _("Loaded CA certificate '%s'\n"), opt.ca_cert); + } + } + + if (opt.crl_file) + { + if ((rc = gnutls_certificate_set_x509_crl_file (credentials, opt.crl_file, GNUTLS_X509_FMT_PEM)) <= 0) + { + logprintf (LOG_NOTQUIET, _("ERROR: Failed to load CRL file '%s': (%d)\n"), opt.crl_file, rc); + return false; + } + + logprintf (LOG_VERBOSE, _("Loaded CRL file '%s'\n"), opt.crl_file); + } + + DEBUGP (("Certificates loaded: %d\n", ncerts)); + + /* Use the private key from the cert file unless otherwise specified. */ + if (opt.cert_file && !opt.private_key) + { + opt.private_key = xstrdup (opt.cert_file); + opt.private_key_type = opt.cert_type; + } + /* Use the cert from the private key file unless otherwise specified. */ + if (!opt.cert_file && opt.private_key) + { + opt.cert_file = xstrdup (opt.private_key); + opt.cert_type = opt.private_key_type; + } + + if (opt.cert_file && opt.private_key) + { + int type; + if (opt.private_key_type != opt.cert_type) + { + /* GnuTLS can't handle this */ + logprintf (LOG_NOTQUIET, _("ERROR: GnuTLS requires the key and the \ +cert to be of the same type.\n")); + } + + type = key_type_to_gnutls_type (opt.private_key_type); + + gnutls_certificate_set_x509_key_file (credentials, opt.cert_file, + opt.private_key, + type); + } + + ssl_initialized = true; + + return true; +} + +void +ssl_cleanup (void) +{ + if (credentials) + gnutls_certificate_free_credentials(credentials); + + gnutls_global_deinit(); +} + +struct wgnutls_transport_context +{ + gnutls_session_t session; /* GnuTLS session handle */ + gnutls_datum_t *session_data; + int last_error; /* last error returned by read/write/... */ + + /* Since GnuTLS doesn't support the equivalent to recv(..., + MSG_PEEK) or SSL_peek(), we have to do it ourselves. Peeked data + is stored to PEEKBUF, and wgnutls_read checks that buffer before + actually reading. */ + char peekbuf[512]; + int peeklen; +}; + +static int +wgnutls_read_timeout (int fd, char *buf, int bufsize, void *arg, double timeout) +{ +#ifdef F_GETFL + int flags = 0; +#endif + struct wgnutls_transport_context *ctx = arg; + int ret = gnutls_record_check_pending (ctx->session); + struct st_read_timer read_timer = {(timeout == -1 ? opt.read_timeout : timeout), 0, NULL, 0}; + + if (ret) + return gnutls_record_recv (ctx->session, buf, MIN (ret, bufsize)); + + if (read_timer.timeout) + { +#ifdef F_GETFL + flags = fcntl (fd, F_GETFL, 0); + if (flags < 0) + return flags; + if (fcntl (fd, F_SETFL, flags | O_NONBLOCK)) + return -1; +#else + /* XXX: Assume it was blocking before. */ + const int one = 1; + if (ioctl (fd, FIONBIO, &one) < 0) + return -1; +#endif + + read_timer.timer = ptimer_new (); + if (read_timer.timer == NULL) + { + ret = -1; + goto timer_err; + } + read_timer.next_timeout = read_timer.timeout; + } + + ret = ctx->last_error; + do + { + if (ret == GNUTLS_E_REHANDSHAKE) + { + int err; + DEBUGP (("GnuTLS: *** REHANDSHAKE while reading\n")); + if ((err = _do_handshake (ctx->session, fd, &read_timer)) != 0) + { + ret = err; + break; + } + } +#if GNUTLS_VERSION_NUMBER >= 0x030604 + else if (ret == GNUTLS_E_REAUTH_REQUEST) + { + int err; + DEBUGP (("GnuTLS: *** re-authentication while reading\n")); + if ((err = _do_reauth (ctx->session, fd, &read_timer)) != 0) + { + ret = err; + break; + } + } +#endif + do + { + ret = gnutls_record_recv (ctx->session, buf, bufsize); + if (ret == GNUTLS_E_AGAIN && read_timer.timer) + { + int err = select_fd_nb (fd, read_timer.next_timeout, WAIT_FOR_READ); + if (err <= 0) + { + if (err == 0) + read_timer.timed_out = 1; + goto break_all; + } + if ( (read_timer.next_timeout = read_timer.timeout - ptimer_measure (read_timer.timer)) <= 0 ) + { + read_timer.timed_out = 1; + goto break_all; + } + } + } + while (ret == GNUTLS_E_AGAIN || ret == GNUTLS_E_INTERRUPTED); + } + while (ret == GNUTLS_E_REHANDSHAKE +#if GNUTLS_VERSION_NUMBER >= 0x030604 + || ret == GNUTLS_E_REAUTH_REQUEST +#endif + ); + +break_all: + if (read_timer.timer) + { + ptimer_destroy (read_timer.timer); +timer_err: ; +#ifdef F_GETFL + if (fcntl (fd, F_SETFL, flags) < 0) + return -1; +#else + { + const int zero = 0; + if (ioctl (fd, FIONBIO, &zero) < 0) + return -1; + } +#endif + if (read_timer.timed_out) + errno = ETIMEDOUT; + } + + return ret; +} + +static int +wgnutls_read (int fd, char *buf, int bufsize, void *arg, double timeout) +{ + int ret; + struct wgnutls_transport_context *ctx = arg; + + if (ctx->peeklen) + { + /* If we have any peek data, simply return that. */ + int copysize = MIN (bufsize, ctx->peeklen); + memcpy (buf, ctx->peekbuf, copysize); + ctx->peeklen -= copysize; + if (ctx->peeklen != 0) + memmove (ctx->peekbuf, ctx->peekbuf + copysize, ctx->peeklen); + + return copysize; + } + + ret = wgnutls_read_timeout (fd, buf, bufsize, arg, timeout); + ctx->last_error = ret; + return ret; +} + +static int +wgnutls_write (int fd _GL_UNUSED, char *buf, int bufsize, void *arg) +{ + struct wgnutls_transport_context *ctx = arg; + int ret = ctx->last_error; + + /* it should never happen, + placed here only for debug msg. */ + if (ret == GNUTLS_E_REHANDSHAKE) + { + DEBUGP (("GnuTLS: *** REHANDSHAKE while writing\n")); + if ((ret = _do_handshake (ctx->session, fd, NULL)) != 0) + goto ext; + } +#if GNUTLS_VERSION_NUMBER >= 0x030604 + else if (ret == GNUTLS_E_REAUTH_REQUEST) + { + DEBUGP (("GnuTLS: *** re-authentication while writing\n")); + if ((ret = _do_reauth (ctx->session, fd, NULL)) != 0) + goto ext; + } +#endif + + do + ret = gnutls_record_send (ctx->session, buf, bufsize); + while (ret == GNUTLS_E_INTERRUPTED || ret == GNUTLS_E_AGAIN); +ext: + ctx->last_error = ret; + return ret; +} + +static int +wgnutls_poll (int fd, double timeout, int wait_for, void *arg) +{ + struct wgnutls_transport_context *ctx = arg; + + if ((wait_for & WAIT_FOR_READ) + && (ctx->peeklen || gnutls_record_check_pending (ctx->session))) + return 1; + + if (timeout == -1) + timeout = opt.read_timeout; + return select_fd (fd, timeout, wait_for); +} + +static int +wgnutls_peek (int fd, char *buf, int bufsize, void *arg, double timeout) +{ + int read = 0; + struct wgnutls_transport_context *ctx = arg; + int offset = MIN (bufsize, ctx->peeklen); + + if (ctx->peeklen) + { + memcpy (buf, ctx->peekbuf, offset); + return offset; + } + + if (bufsize > (int) sizeof ctx->peekbuf) + bufsize = sizeof ctx->peekbuf; + + if (bufsize > offset) + { /* let wgnutls_read_timeout() take care about timeout */ + /*if (timeout && gnutls_record_check_pending (ctx->session) == 0 + && select_fd (fd, 0.0, WAIT_FOR_READ) <= 0) + read = 0; + else*/ + read = wgnutls_read_timeout (fd, buf + offset, bufsize - offset, + ctx, timeout); + ctx->last_error = read; + if (read < 0) + { + if (offset) + read = 0; + else + return read; + } + + if (read > 0) + { + memcpy (ctx->peekbuf + offset, buf + offset, + read); + ctx->peeklen += read; + } + } + + return offset + read; +} + +static const char * +wgnutls_errstr (int fd _GL_UNUSED, void *arg) +{ + struct wgnutls_transport_context *ctx = arg; + + if (ctx->last_error > 0 + || ((ctx->last_error == GNUTLS_E_AGAIN + || ctx->last_error == GNUTLS_E_REHANDSHAKE +#if GNUTLS_VERSION_NUMBER >= 0x030604 + || ctx->last_error == GNUTLS_E_REAUTH_REQUEST +#endif + ) && errno == ETIMEDOUT)) + return NULL; + + return gnutls_strerror (ctx->last_error); +} + +static void +wgnutls_close (int fd, void *arg) +{ + struct wgnutls_transport_context *ctx = arg; + /*gnutls_bye (ctx->session, GNUTLS_SHUT_RDWR);*/ + if (ctx->session_data) + { + gnutls_free (ctx->session_data->data); + gnutls_free (ctx->session_data); + } + gnutls_deinit (ctx->session); + xfree (ctx); + close (fd); +} + +/* gnutls_transport is the singleton that describes the SSL transport + methods provided by this file. */ + +static struct transport_implementation wgnutls_transport = +{ + wgnutls_read, wgnutls_write, wgnutls_poll, + wgnutls_peek, wgnutls_errstr, wgnutls_close +}; + +static int +_do_handshake (gnutls_session_t session, int fd, struct st_read_timer *read_timer) +{ +#ifdef F_GETFL + int flags = 0; +#endif + int err; + double next_timeout = (read_timer ? read_timer->next_timeout : opt.read_timeout); + + /* if (read_timer != NULL) - fd is already non blocking */ + if (!read_timer && next_timeout) + { +#ifdef F_GETFL + flags = fcntl (fd, F_GETFL, 0); + if (flags < 0) + return flags; + if (fcntl (fd, F_SETFL, flags | O_NONBLOCK)) + return -1; +#else + /* XXX: Assume it was blocking before. */ + const int one = 1; + if (ioctl (fd, FIONBIO, &one) < 0) + return -1; +#endif + } + + /* We don't stop the handshake process for non-fatal errors */ + do + { + err = gnutls_handshake (session); + + if (err == GNUTLS_E_AGAIN && next_timeout) + { + int sel; + if (gnutls_record_get_direction (session)) + { + /* wait for writeability */ + sel = WAIT_FOR_WRITE; + } + else + { + /* wait for readability */ + sel = WAIT_FOR_READ; + } + sel = select_fd_nb (fd, next_timeout, sel); + + if (sel <= 0) + { + if (sel == 0) + { + if (read_timer) + goto read_timedout; + else + { + errno = ETIMEDOUT; + err = -1; + } + } + break; + } + if (read_timer) + { + if ( (read_timer->next_timeout = read_timer->timeout - ptimer_measure (read_timer->timer)) <= 0 ) + { +read_timedout: /* return GNUTLS_E_REHANDSHAKE for gnutls_read */ + err = GNUTLS_E_REHANDSHAKE; + read_timer->timed_out = 1; + break; + } + next_timeout = read_timer->next_timeout; + } + } + else if (err < 0) + { + logprintf (LOG_NOTQUIET, "GnuTLS: %s\n", gnutls_strerror (err)); + if (err == GNUTLS_E_WARNING_ALERT_RECEIVED || + err == GNUTLS_E_FATAL_ALERT_RECEIVED) + { + gnutls_alert_description_t alert = gnutls_alert_get (session); + const char *str = gnutls_alert_get_name (alert); + logprintf (LOG_NOTQUIET, "GnuTLS: received alert [%u]: %s\n", + alert, str ? str : "(unknown)"); + } + } + } + while (err && gnutls_error_is_fatal (err) == 0); + + if (!read_timer && next_timeout) + { +#ifdef F_GETFL + if (fcntl (fd, F_SETFL, flags) < 0) + return -1; +#else + const int zero = 0; + if (ioctl (fd, FIONBIO, &zero) < 0) + return -1; +#endif + } + + return err; +} + +#if GNUTLS_VERSION_NUMBER >= 0x030604 +static int +_do_reauth (gnutls_session_t session, int fd, struct st_read_timer *read_timer) +{ +#ifdef F_GETFL + int flags = 0; +#endif + int err; + double next_timeout = (read_timer ? read_timer->next_timeout : opt.read_timeout); + + /* if (read_timer != NULL) - fd is already non blocking */ + if (!read_timer && next_timeout) + { +#ifdef F_GETFL + flags = fcntl (fd, F_GETFL, 0); + if (flags < 0) + return flags; + if (fcntl (fd, F_SETFL, flags | O_NONBLOCK)) + return -1; +#else + /* XXX: Assume it was blocking before. */ + const int one = 1; + if (ioctl (fd, FIONBIO, &one) < 0) + return -1; +#endif + } + + /* We don't stop the handshake process for non-fatal errors */ + do + { + err = gnutls_reauth (session, 0); + + if (err == GNUTLS_E_AGAIN && next_timeout) + { + int sel; + if (gnutls_record_get_direction (session)) + { + /* wait for writeability */ + sel = WAIT_FOR_WRITE; + } + else + { + /* wait for readability */ + sel = WAIT_FOR_READ; + } + sel = select_fd_nb (fd, next_timeout, sel); + + if (sel <= 0) + { + if (sel == 0) + { + if (read_timer) + goto read_timedout; + else + { + errno = ETIMEDOUT; + err = -1; + } + } + break; + } + if (read_timer) + { + if ( (read_timer->next_timeout = read_timer->timeout - ptimer_measure (read_timer->timer)) <= 0 ) + { +read_timedout: /* return GNUTLS_E_REAUTH_REQUEST for gnutls_read */ + err = GNUTLS_E_REAUTH_REQUEST; + read_timer->timed_out = 1; + break; + } + next_timeout = read_timer->next_timeout; + } + } + else if (err < 0) + { + logprintf (LOG_NOTQUIET, "GnuTLS: %s\n", gnutls_strerror (err)); + } + } + while (err && gnutls_error_is_fatal (err) == 0); + + if (!read_timer && next_timeout) + { +#ifdef F_GETFL + if (fcntl (fd, F_SETFL, flags) < 0) + return -1; +#else + const int zero = 0; + if (ioctl (fd, FIONBIO, &zero) < 0) + return -1; +#endif + } + + return err; +} +#endif + +static const char * +_sni_hostname(const char *hostname) +{ + size_t len = strlen(hostname); + + char *sni_hostname = xmemdup(hostname, len + 1); + + /* Remove trailing dot(s) to fix #47408. + * Regarding RFC 6066 (SNI): The hostname is represented as a byte + * string using ASCII encoding without a trailing dot. */ + while (len && sni_hostname[--len] == '.') + sni_hostname[len] = 0; + + return sni_hostname; +} + +static int +set_prio_default (gnutls_session_t session) +{ + int err = -1; + +#if HAVE_GNUTLS_PRIORITY_SET_DIRECT + switch (opt.secure_protocol) + { + case secure_protocol_auto: + err = gnutls_set_default_priority (session); + gnutls_session_enable_compatibility_mode(session); + break; + + case secure_protocol_sslv2: + case secure_protocol_sslv3: + err = gnutls_priority_set_direct (session, "NORMAL:-VERS-TLS-ALL:+VERS-SSL3.0", NULL); + break; + + case secure_protocol_tlsv1: + err = gnutls_priority_set_direct (session, "NORMAL:-VERS-SSL3.0", NULL); + break; + + case secure_protocol_tlsv1_1: + err = gnutls_priority_set_direct (session, "NORMAL:-VERS-SSL3.0:-VERS-TLS1.0", NULL); + break; + + case secure_protocol_tlsv1_2: + err = gnutls_priority_set_direct (session, "NORMAL:-VERS-SSL3.0:-VERS-TLS1.0:-VERS-TLS1.1", NULL); + break; + + case secure_protocol_tlsv1_3: +#if GNUTLS_VERSION_NUMBER >= 0x030603 + err = gnutls_priority_set_direct (session, "NORMAL:-VERS-SSL3.0:+VERS-TLS1.3:-VERS-TLS1.0:-VERS-TLS1.1:-VERS-TLS1.2", NULL); + break; +#else + logprintf (LOG_NOTQUIET, _("Your GnuTLS version is too old to support TLS 1.3\n")); + return -1; +#endif + + case secure_protocol_pfs: + err = gnutls_priority_set_direct (session, "PFS:-VERS-SSL3.0", NULL); + if (err != GNUTLS_E_SUCCESS) + /* fallback if PFS is not available */ + err = gnutls_priority_set_direct (session, "NORMAL:-RSA:-VERS-SSL3.0", NULL); + break; + + default: + logprintf (LOG_NOTQUIET, _("GnuTLS: unimplemented 'secure-protocol' option value %u\n"), + (unsigned) opt.secure_protocol); + logprintf (LOG_NOTQUIET, _("Please report this issue to bug-wget@gnu.org\n")); + abort (); + } +#else + int allowed_protocols[4] = {0, 0, 0, 0}; + switch (opt.secure_protocol) + { + case secure_protocol_auto: + err = gnutls_set_default_priority (session); + break; + + case secure_protocol_sslv2: + case secure_protocol_sslv3: + allowed_protocols[0] = GNUTLS_SSL3; + err = gnutls_protocol_set_priority (session, allowed_protocols); + break; + + case secure_protocol_tlsv1: + allowed_protocols[0] = GNUTLS_TLS1_0; + allowed_protocols[1] = GNUTLS_TLS1_1; + allowed_protocols[2] = GNUTLS_TLS1_2; +#if GNUTLS_VERSION_NUMBER >= 0x030603 + allowed_protocols[3] = GNUTLS_TLS1_3; +#endif + err = gnutls_protocol_set_priority (session, allowed_protocols); + break; + + case secure_protocol_tlsv1_1: + allowed_protocols[0] = GNUTLS_TLS1_1; + allowed_protocols[1] = GNUTLS_TLS1_2; +#if GNUTLS_VERSION_NUMBER >= 0x030603 + allowed_protocols[2] = GNUTLS_TLS1_3; +#endif + err = gnutls_protocol_set_priority (session, allowed_protocols); + break; + + case secure_protocol_tlsv1_2: + allowed_protocols[0] = GNUTLS_TLS1_2; +#if GNUTLS_VERSION_NUMBER >= 0x030603 + allowed_protocols[1] = GNUTLS_TLS1_3; +#endif + err = gnutls_protocol_set_priority (session, allowed_protocols); + break; + + case secure_protocol_tlsv1_3: +#if GNUTLS_VERSION_NUMBER >= 0x030603 + allowed_protocols[0] = GNUTLS_TLS1_3; + err = gnutls_protocol_set_priority (session, allowed_protocols); + break; +#else + logprintf (LOG_NOTQUIET, _("Your GnuTLS version is too old to support TLS 1.3\n")); + return -1; +#endif + + default: + logprintf (LOG_NOTQUIET, _("GnuTLS: unimplemented 'secure-protocol' option value %d\n"), opt.secure_protocol); + logprintf (LOG_NOTQUIET, _("Please report this issue to bug-wget@gnu.org\n")); + abort (); + } +#endif + + return err; +} + +bool +ssl_connect_wget (int fd, const char *hostname, int *continue_session) +{ + struct wgnutls_transport_context *ctx; + gnutls_session_t session; + int err; + +#if GNUTLS_VERSION_NUMBER >= 0x030604 + // enable support of TLS1.3 post-handshake authentication + gnutls_init (&session, GNUTLS_CLIENT | GNUTLS_POST_HANDSHAKE_AUTH); +#else + gnutls_init (&session, GNUTLS_CLIENT); +#endif + + /* We set the server name but only if it's not an IP address. */ + if (! is_valid_ip_address (hostname)) + { + /* GnuTLS 3.4.x (x<=10) disrespects the length parameter, we have to construct a new string */ + /* see https://gitlab.com/gnutls/gnutls/issues/78 */ + const char *sni_hostname = _sni_hostname(hostname); + + gnutls_server_name_set (session, GNUTLS_NAME_DNS, sni_hostname, strlen(sni_hostname)); + xfree(sni_hostname); + } + + gnutls_credentials_set (session, GNUTLS_CRD_CERTIFICATE, credentials); +#ifndef FD_TO_SOCKET +# define FD_TO_SOCKET(X) (X) +#endif +#ifdef HAVE_INTPTR_T + gnutls_transport_set_ptr (session, (gnutls_transport_ptr_t) (intptr_t) FD_TO_SOCKET (fd)); +#else + gnutls_transport_set_ptr (session, (gnutls_transport_ptr_t) FD_TO_SOCKET (fd)); +#endif + + if (!opt.tls_ciphers_string) + { + err = set_prio_default (session); + } + else + { +#if HAVE_GNUTLS_PRIORITY_SET_DIRECT + err = gnutls_priority_set_direct (session, opt.tls_ciphers_string, NULL); +#else + logprintf (LOG_NOTQUIET, _("GnuTLS: Cannot set prio string directly. Falling back to default priority.\n")); + err = gnutls_set_default_priority (session); +#endif + } + + if (err < 0) + { + logprintf (LOG_NOTQUIET, "GnuTLS: %s\n", gnutls_strerror (err)); + gnutls_deinit (session); + return false; + } + + if (continue_session) + { + ctx = (struct wgnutls_transport_context *) fd_transport_context (*continue_session); + if (!gnutls_session_is_resumed (session)) + { + if (!ctx || !ctx->session_data || gnutls_session_set_data (session, ctx->session_data->data, ctx->session_data->size)) + { + if (ctx && ctx->session_data) + { + /* server does not want to continue the session */ + if (ctx->session_data->data) + gnutls_free (ctx->session_data->data); + gnutls_free (ctx->session_data); + } + gnutls_deinit (session); + return false; + } + } + else + { + logputs (LOG_ALWAYS, "SSL session has already been resumed. Continuing.\n"); + continue_session = NULL; + } + } + + err = _do_handshake (session, fd, NULL); + + if (err < 0) + { + gnutls_deinit (session); + return false; + } + + ctx = xnew0 (struct wgnutls_transport_context); + ctx->session_data = xnew0 (gnutls_datum_t); + ctx->session = session; + if (gnutls_session_get_data2 (session, ctx->session_data)) + { + xfree (ctx->session_data); + logprintf (LOG_NOTQUIET, "WARNING: Could not save SSL session data for socket %d\n", fd); + } + fd_register_transport (fd, &wgnutls_transport, ctx); + return true; +} + +static bool +pkp_pin_peer_pubkey (gnutls_x509_crt_t cert, const char *pinnedpubkey) +{ + /* Scratch */ + size_t len1 = 0, len2 = 0; + char *buff1 = NULL; + + gnutls_pubkey_t key = NULL; + + /* Result is returned to caller */ + int ret = 0; + bool result = false; + + /* if a path wasn't specified, don't pin */ + if (NULL == pinnedpubkey) + return true; + + if (NULL == cert) + return result; + + /* Begin Gyrations to get the public key */ + gnutls_pubkey_init (&key); + + ret = gnutls_pubkey_import_x509 (key, cert, 0); + if (ret < 0) + goto cleanup; /* failed */ + + ret = gnutls_pubkey_export (key, GNUTLS_X509_FMT_DER, NULL, &len1); + if (ret != GNUTLS_E_SHORT_MEMORY_BUFFER || len1 == 0) + goto cleanup; /* failed */ + + buff1 = xmalloc (len1); + + len2 = len1; + + ret = gnutls_pubkey_export (key, GNUTLS_X509_FMT_DER, buff1, &len2); + if (ret < 0 || len1 != len2) + goto cleanup; /* failed */ + + /* End Gyrations */ + + /* The one good exit point */ + result = wg_pin_peer_pubkey (pinnedpubkey, buff1, len1); + + cleanup: + if (NULL != key) + gnutls_pubkey_deinit (key); + + xfree (buff1); + + return result; +} + +#define _CHECK_CERT(flag,msg) \ + if (status & (flag))\ + {\ + logprintf (LOG_NOTQUIET, (msg),\ + severity, quote (host));\ + success = false;\ + } + +bool +ssl_check_certificate (int fd, const char *host) +{ + struct wgnutls_transport_context *ctx = fd_transport_context (fd); + + unsigned int status; + int err; + + /* If the user has specified --no-check-cert, we still want to warn + him about problems with the server's certificate. */ + const char *severity = opt.check_cert ? _("ERROR") : _("WARNING"); + bool success = true; + bool pinsuccess = opt.pinnedpubkey == NULL; + + /* The user explicitly said to not check for the certificate. */ + if (opt.check_cert == CHECK_CERT_QUIET && pinsuccess) + return success; + + err = gnutls_certificate_verify_peers2 (ctx->session, &status); + if (err < 0) + { + logprintf (LOG_NOTQUIET, _("%s: No certificate presented by %s.\n"), + severity, quotearg_style (escape_quoting_style, host)); + success = false; + goto out; + } + + _CHECK_CERT (GNUTLS_CERT_INVALID, _("%s: The certificate of %s is not trusted.\n")); + _CHECK_CERT (GNUTLS_CERT_SIGNER_NOT_FOUND, _("%s: The certificate of %s doesn't have a known issuer.\n")); + _CHECK_CERT (GNUTLS_CERT_REVOKED, _("%s: The certificate of %s has been revoked.\n")); + _CHECK_CERT (GNUTLS_CERT_SIGNER_NOT_CA, _("%s: The certificate signer of %s was not a CA.\n")); + _CHECK_CERT (GNUTLS_CERT_INSECURE_ALGORITHM, _("%s: The certificate of %s was signed using an insecure algorithm.\n")); + _CHECK_CERT (GNUTLS_CERT_NOT_ACTIVATED, _("%s: The certificate of %s is not yet activated.\n")); + _CHECK_CERT (GNUTLS_CERT_EXPIRED, _("%s: The certificate of %s has expired.\n")); + + if (gnutls_certificate_type_get (ctx->session) == GNUTLS_CRT_X509) + { + time_t now = time (NULL); + gnutls_x509_crt_t cert; + const gnutls_datum_t *cert_list; + unsigned int cert_list_size; + const char *sni_hostname; + + if ((err = gnutls_x509_crt_init (&cert)) < 0) + { + logprintf (LOG_NOTQUIET, _("Error initializing X509 certificate: %s\n"), + gnutls_strerror (err)); + success = false; + goto out; + } + + cert_list = gnutls_certificate_get_peers (ctx->session, &cert_list_size); + if (!cert_list) + { + logprintf (LOG_NOTQUIET, _("No certificate found\n")); + success = false; + goto crt_deinit; + } + err = gnutls_x509_crt_import (cert, cert_list, GNUTLS_X509_FMT_DER); + if (err < 0) + { + logprintf (LOG_NOTQUIET, _("Error parsing certificate: %s\n"), + gnutls_strerror (err)); + success = false; + goto crt_deinit; + } + if (now < gnutls_x509_crt_get_activation_time (cert)) + { + logprintf (LOG_NOTQUIET, _("The certificate has not yet been activated\n")); + success = false; + } + if (now >= gnutls_x509_crt_get_expiration_time (cert)) + { + logprintf (LOG_NOTQUIET, _("The certificate has expired\n")); + success = false; + } + sni_hostname = _sni_hostname(host); + if (!gnutls_x509_crt_check_hostname (cert, sni_hostname)) + { + logprintf (LOG_NOTQUIET, + _("The certificate's owner does not match hostname %s\n"), + quote (sni_hostname)); + success = false; + } + xfree(sni_hostname); + + pinsuccess = pkp_pin_peer_pubkey (cert, opt.pinnedpubkey); + if (!pinsuccess) + { + logprintf (LOG_ALWAYS, _("The public key does not match pinned public key!\n")); + success = false; + } + + crt_deinit: + gnutls_x509_crt_deinit (cert); + } + else + { + logprintf (LOG_NOTQUIET, _("Certificate must be X.509\n")); + success = false; + } + + out: + /* never return true if pinsuccess fails */ + return !pinsuccess ? false : (opt.check_cert == CHECK_CERT_ON ? success : true); +} diff --git a/src/hash.c b/src/hash.c new file mode 100644 index 0000000..6609528 --- /dev/null +++ b/src/hash.c @@ -0,0 +1,813 @@ +/* Hash tables. + Copyright (C) 2000-2011, 2015, 2018-2020 Free Software Foundation, + Inc. + +This file is part of GNU Wget. + +GNU Wget is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 3 of the License, or (at +your option) any later version. + +GNU Wget 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 Wget. If not, see . + +Additional permission under GNU GPL version 3 section 7 + +If you modify this program, or any covered work, by linking or +combining it with the OpenSSL project's OpenSSL library (or a +modified version of that library), containing parts covered by the +terms of the OpenSSL or SSLeay licenses, the Free Software Foundation +grants you additional permission to convey the resulting work. +Corresponding Source for a non-source form of such a combination +shall include the source code for the parts of OpenSSL used as well +as that of the covered work. */ + +/* With -DSTANDALONE, this file can be compiled outside Wget source + tree. To test, also use -DTEST. */ + +#ifndef STANDALONE +# include "wget.h" +#endif + +#include +#include +#include +#include +#include + +#ifndef STANDALONE +/* Get Wget's utility headers. */ +# include "utils.h" +#else +/* Make do without them. */ +# define xnew(type) (xmalloc (sizeof (type))) +# define xnew0(type) (xcalloc (1, sizeof (type))) +# define xnew_array(type, len) (xmalloc ((len) * sizeof (type))) +# define xfree(p) do { free ((void *) (p)); p = NULL; } while (0) + +# ifndef countof +# define countof(x) (sizeof (x) / sizeof ((x)[0])) +# endif +# include +# define c_tolower(x) tolower ((unsigned char) (x)) +# include +#endif + +#include "hash.h" + +/* INTERFACE: + + Hash tables are a technique used to implement mapping between + objects with near-constant-time access and storage. The table + associates keys to values, and a value can be very quickly + retrieved by providing the key. Fast lookup tables are typically + implemented as hash tables. + + The entry points are + hash_table_new -- creates the table. + hash_table_destroy -- destroys the table. + hash_table_put -- establishes or updates key->value mapping. + hash_table_get -- retrieves value of key. + hash_table_get_pair -- get key/value pair for key. + hash_table_contains -- test whether the table contains key. + hash_table_remove -- remove key->value mapping for given key. + hash_table_for_each -- call function for each table entry. + hash_table_iterate -- iterate over entries in hash table. + hash_table_iter_next -- return next element during iteration. + hash_table_clear -- clear hash table contents. + hash_table_count -- return the number of entries in the table. + + The hash table grows internally as new entries are added and is not + limited in size, except by available memory. The table doubles + with each resize, which ensures that the amortized time per + operation remains constant. + + If not instructed otherwise, tables created by hash_table_new + consider the keys to be equal if their pointer values are the same. + You can use make_string_hash_table to create tables whose keys are + considered equal if their string contents are the same. In the + general case, the criterion of equality used to compare keys is + specified at table creation time with two callback functions, + "hash" and "test". The hash function transforms the key into an + arbitrary number that must be the same for two equal keys. The + test function accepts two keys and returns non-zero if they are to + be considered equal. + + Note that neither keys nor values are copied when inserted into the + hash table, so they must exist for the lifetime of the table. This + means that e.g. the use of static strings is OK, but objects with a + shorter life-time probably need to be copied (with strdup() or the + like in the case of strings) before being inserted. */ + +/* IMPLEMENTATION: + + The hash table is implemented as an open-addressed table with + linear probing collision resolution. + + The above means that all the cells (each cell containing a key and + a value pointer) are stored in a contiguous array. Array position + of each cell is determined by the hash value of its key and the + size of the table: location := hash(key) % size. If two different + keys end up on the same position (collide), the one that came + second is stored in the first unoccupied cell that follows it. + This collision resolution technique is called "linear probing". + + There are more advanced collision resolution methods (quadratic + probing, double hashing), but we don't use them because they incur + more non-sequential access to the array, which results in worse CPU + cache behavior. Linear probing works well as long as the + count/size ratio (fullness) is kept below 75%. We make sure to + grow and rehash the table whenever this threshold is exceeded. + + Collisions complicate deletion because simply clearing a cell + followed by previously collided entries would cause those neighbors + to not be picked up by find_cell later. One solution is to leave a + "tombstone" marker instead of clearing the cell, and another is to + recalculate the positions of adjacent cells. We take the latter + approach because it results in less bookkeeping garbage and faster + retrieval at the (slight) expense of deletion. */ + +/* Maximum allowed fullness: when hash table's fullness exceeds this + value, the table is resized. */ +#define HASH_MAX_FULLNESS 0.75 + +/* The hash table size is multiplied by this factor (and then rounded + to the next prime) with each resize. This guarantees infrequent + resizes. */ +#define HASH_RESIZE_FACTOR 2 + +struct cell { + void *key; + void *value; +}; + +typedef unsigned long (*hashfun_t) (const void *); +typedef int (*testfun_t) (const void *, const void *); + +struct hash_table { + hashfun_t hash_function; + testfun_t test_function; + + struct cell *cells; /* contiguous array of cells. */ + int size; /* size of the array. */ + + int count; /* number of occupied entries. */ + int resize_threshold; /* after size exceeds this number of + entries, resize the table. */ + int prime_offset; /* the offset of the current prime in + the prime table. */ +}; + +/* We use the all-bits-set constant (INVALID_PTR) marker to mean that + a cell is empty. It is unaligned and therefore illegal as a + pointer. INVALID_PTR_CHAR (0xff) is the single-character constant + used to initialize the entire cells array as empty. + + The all-bits-set value is a better choice than NULL because it + allows the use of NULL/0 keys. Since the keys are either integers + or pointers, the only key that cannot be used is the integer value + -1. This is acceptable because it still allows the use of + nonnegative integer keys. */ + +#define INVALID_PTR ((void *) ~(uintptr_t) 0) +#ifndef UCHAR_MAX +# define UCHAR_MAX 0xff +#endif +#define INVALID_PTR_CHAR UCHAR_MAX + +/* Whether the cell C is occupied (non-empty). */ +#define CELL_OCCUPIED(c) ((c)->key != INVALID_PTR) + +/* Clear the cell C, i.e. mark it as empty (unoccupied). */ +#define CLEAR_CELL(c) ((c)->key = INVALID_PTR) + +/* "Next" cell is the cell following C, but wrapping back to CELLS + when C would reach CELLS+SIZE. */ +#define NEXT_CELL(c, cells, size) (c != cells + (size - 1) ? c + 1 : cells) + +/* Loop over occupied cells starting at C, terminating the loop when + an empty cell is encountered. */ +#define FOREACH_OCCUPIED_ADJACENT(c, cells, size) \ + for (; CELL_OCCUPIED (c); c = NEXT_CELL (c, cells, size)) + +/* Return the position of KEY in hash table SIZE large, hash function + being HASHFUN. */ +#define HASH_POSITION(key, hashfun, size) ((hashfun) (key) % size) + +/* Find a prime near, but greater than or equal to SIZE. The primes + are looked up from a table with a selection of primes convenient + for this purpose. + + PRIME_OFFSET is a minor optimization: it specifies start position + for the search for the large enough prime. The final offset is + stored in the same variable. That way the list of primes does not + have to be scanned from the beginning each time around. */ + +static int +prime_size (int size, int *prime_offset) +{ + static const int primes[] = { + 13, 19, 29, 41, 59, 79, 107, 149, 197, 263, 347, 457, 599, 787, 1031, + 1361, 1777, 2333, 3037, 3967, 5167, 6719, 8737, 11369, 14783, + 19219, 24989, 32491, 42257, 54941, 71429, 92861, 120721, 156941, + 204047, 265271, 344857, 448321, 582821, 757693, 985003, 1280519, + 1664681, 2164111, 2813353, 3657361, 4754591, 6180989, 8035301, + 10445899, 13579681, 17653589, 22949669, 29834603, 38784989, + 50420551, 65546729, 85210757, 110774011, 144006217, 187208107, + 243370577, 316381771, 411296309, 534685237, 695090819, 903618083, + 1174703521, 1527114613, 1837299131, 2147483647 + }; + size_t i; + + for (i = *prime_offset; i < countof (primes); i++) + if (primes[i] >= size) + { + /* Set the offset to the next prime. That is safe because, + next time we are called, it will be with a larger SIZE, + which means we could never return the same prime anyway. + (If that is not the case, the caller can simply reset + *prime_offset.) */ + *prime_offset = i + 1; + return primes[i]; + } + + abort (); +} + +static int cmp_pointer (const void *, const void *); + +/* Create a hash table with hash function HASH_FUNCTION and test + function TEST_FUNCTION. The table is empty (its count is 0), but + pre-allocated to store at least ITEMS items. + + ITEMS is the number of items that the table can accept without + needing to resize. It is useful when creating a table that is to + be immediately filled with a known number of items. In that case, + the regrows are a waste of time, and specifying ITEMS correctly + will avoid them altogether. + + Note that hash tables grow dynamically regardless of ITEMS. The + only use of ITEMS is to preallocate the table and avoid unnecessary + dynamic regrows. Don't bother making ITEMS prime because it's not + used as size unchanged. To start with a small table that grows as + needed, simply specify zero ITEMS. + + If hash and test callbacks are not specified, identity mapping is + assumed, i.e. pointer values are used for key comparison. (Common + Lisp calls such tables EQ hash tables, and Java calls them + IdentityHashMaps.) If your keys require different comparison, + specify hash and test functions. For easy use of C strings as hash + keys, you can use the convenience functions make_string_hash_table + and make_nocase_string_hash_table. */ + +struct hash_table * +hash_table_new (int items, + unsigned long (*hash_function) (const void *), + int (*test_function) (const void *, const void *)) +{ + int size; + struct hash_table *ht = xnew (struct hash_table); + + ht->hash_function = hash_function ? hash_function : hash_pointer; + ht->test_function = test_function ? test_function : cmp_pointer; + + /* If the size of struct hash_table ever becomes a concern, this + field can go. (Wget doesn't create many hashes.) */ + ht->prime_offset = 0; + + /* Calculate the size that ensures that the table will store at + least ITEMS keys without the need to resize. */ + size = (int) (1 + items / HASH_MAX_FULLNESS); + size = prime_size (size, &ht->prime_offset); + ht->size = size; + ht->resize_threshold = (int) (size * HASH_MAX_FULLNESS); + /*assert (ht->resize_threshold >= items);*/ + + ht->cells = xnew_array (struct cell, ht->size); + + /* Mark cells as empty. We use 0xff rather than 0 to mark empty + keys because it allows us to use NULL/0 as keys. */ + memset (ht->cells, INVALID_PTR_CHAR, size * sizeof (struct cell)); + + ht->count = 0; + + return ht; +} + +/* Free the data associated with hash table HT. */ + +void +hash_table_destroy (struct hash_table *ht) +{ + xfree (ht->cells); + xfree (ht); +} + +/* The heart of most functions in this file -- find the cell whose + KEY is equal to key, using linear probing. Returns the cell + that matches KEY, or the first empty cell if none matches. */ + +static inline struct cell * +find_cell (const struct hash_table *ht, const void *key) +{ + struct cell *cells = ht->cells; + int size = ht->size; + struct cell *c = cells + HASH_POSITION (key, ht->hash_function, size); + testfun_t equals = ht->test_function; + + FOREACH_OCCUPIED_ADJACENT (c, cells, size) + if (equals (key, c->key)) + break; + return c; +} + +/* Get the value that corresponds to the key KEY in the hash table HT. + If no value is found, return NULL. Note that NULL is a legal value + for value; if you are storing NULLs in your hash table, you can use + hash_table_contains to be sure that a (possibly NULL) value exists + in the table. Or, you can use hash_table_get_pair instead of this + function. */ + +void * +hash_table_get (const struct hash_table *ht, const void *key) +{ + struct cell *c = find_cell (ht, key); + if (CELL_OCCUPIED (c)) + return c->value; + else + return NULL; +} + +/* Like hash_table_get, but writes out the pointers to both key and + value. Returns non-zero on success. */ + +int +hash_table_get_pair (const struct hash_table *ht, const void *lookup_key, + void *orig_key, void *value) +{ + struct cell *c = find_cell (ht, lookup_key); + if (CELL_OCCUPIED (c)) + { + if (orig_key) + *(void **)orig_key = c->key; + if (value) + *(void **)value = c->value; + return 1; + } + else + return 0; +} + +/* Return 1 if HT contains KEY, 0 otherwise. */ + +int +hash_table_contains (const struct hash_table *ht, const void *key) +{ + struct cell *c = find_cell (ht, key); + return CELL_OCCUPIED (c); +} + +/* Grow hash table HT as necessary, and rehash all the key-value + mappings. */ + +static void +grow_hash_table (struct hash_table *ht) +{ + hashfun_t hasher = ht->hash_function; + struct cell *old_cells = ht->cells; + struct cell *old_end = ht->cells + ht->size; + struct cell *c, *cells; + int newsize; + + newsize = prime_size (ht->size * HASH_RESIZE_FACTOR, &ht->prime_offset); +#if 0 + printf ("growing from %d to %d; fullness %.2f%% to %.2f%%\n", + ht->size, newsize, + 100.0 * ht->count / ht->size, + 100.0 * ht->count / newsize); +#endif + + ht->size = newsize; + ht->resize_threshold = (int) (newsize * HASH_MAX_FULLNESS); + + cells = xnew_array (struct cell, newsize); + memset (cells, INVALID_PTR_CHAR, newsize * sizeof (struct cell)); + ht->cells = cells; + + for (c = old_cells; c < old_end; c++) + if (CELL_OCCUPIED (c)) + { + struct cell *new_c; + /* We don't need to test for uniqueness of keys because they + come from the hash table and are therefore known to be + unique. */ + new_c = cells + HASH_POSITION (c->key, hasher, newsize); + FOREACH_OCCUPIED_ADJACENT (new_c, cells, newsize) + ; + *new_c = *c; + } + + xfree (old_cells); +} + +/* Put VALUE in the hash table HT under the key KEY. This regrows the + table if necessary. */ + +void +hash_table_put (struct hash_table *ht, const void *key, const void *value) +{ + struct cell *c = find_cell (ht, key); + if (CELL_OCCUPIED (c)) + { + /* update existing item */ + c->key = (void *)key; /* const? */ + c->value = (void *)value; + return; + } + + /* If adding the item would make the table exceed max. fullness, + grow the table first. */ + if (ht->count >= ht->resize_threshold) + { + grow_hash_table (ht); + c = find_cell (ht, key); + } + + /* add new item */ + ++ht->count; + c->key = (void *)key; /* const? */ + c->value = (void *)value; +} + +/* Remove KEY->value mapping from HT. Return 0 if there was no such + entry; return 1 if an entry was removed. */ + +int +hash_table_remove (struct hash_table *ht, const void *key) +{ + struct cell *c = find_cell (ht, key); + if (!CELL_OCCUPIED (c)) + return 0; + else + { + int size = ht->size; + struct cell *cells = ht->cells; + hashfun_t hasher = ht->hash_function; + + CLEAR_CELL (c); + --ht->count; + + /* Rehash all the entries following C. The alternative + approach is to mark the entry as deleted, i.e. create a + "tombstone". That speeds up removal, but leaves a lot of + garbage and slows down hash_table_get and hash_table_put. */ + + c = NEXT_CELL (c, cells, size); + FOREACH_OCCUPIED_ADJACENT (c, cells, size) + { + const void *key2 = c->key; + struct cell *c_new; + + /* Find the new location for the key. */ + c_new = cells + HASH_POSITION (key2, hasher, size); + FOREACH_OCCUPIED_ADJACENT (c_new, cells, size) + if (key2 == c_new->key) + /* The cell C (key2) is already where we want it (in + C_NEW's "chain" of keys.) */ + goto next_rehash; + + *c_new = *c; + CLEAR_CELL (c); + + next_rehash: + ; + } + return 1; + } +} + +/* Clear HT of all entries. After calling this function, the count + and the fullness of the hash table will be zero. The size will + remain unchanged. */ + +void +hash_table_clear (struct hash_table *ht) +{ + memset (ht->cells, INVALID_PTR_CHAR, ht->size * sizeof (struct cell)); + ht->count = 0; +} + +/* Call FN for each entry in HT. FN is called with three arguments: + the key, the value, and ARG. When FN returns a non-zero value, the + mapping stops. + + It is undefined what happens if you add or remove entries in the + hash table while hash_table_for_each is running. The exception is + the entry you're currently mapping over; you may call + hash_table_put or hash_table_remove on that entry's key. That is + also the reason why this function cannot be implemented in terms of + hash_table_iterate. */ + +void +hash_table_for_each (struct hash_table *ht, + int (*fn) (void *, void *, void *), void *arg) +{ + struct cell *c = ht->cells; + struct cell *end = ht->cells + ht->size; + + for (; c < end; c++) + if (CELL_OCCUPIED (c)) + { + void *key; + repeat: + key = c->key; + if (fn (key, c->value, arg)) + return; + /* hash_table_remove might have moved the adjacent cells. */ + if (c->key != key && CELL_OCCUPIED (c)) + goto repeat; + } +} + +/* Initiate iteration over HT. Entries are obtained with + hash_table_iter_next, a typical iteration loop looking like this: + + hash_table_iterator iter; + for (hash_table_iterate (ht, &iter); hash_table_iter_next (&iter); ) + ... do something with iter.key and iter.value ... + + The iterator does not need to be deallocated after use. The hash + table must not be modified while being iterated over. */ + +void +hash_table_iterate (struct hash_table *ht, hash_table_iterator *iter) +{ + iter->pos = ht->cells; + iter->end = ht->cells + ht->size; +} + +/* Get the next hash table entry. ITER is an iterator object + initialized using hash_table_iterate. While there are more + entries, the key and value pointers are stored to ITER->key and + ITER->value respectively and 1 is returned. When there are no more + entries, 0 is returned. + + If the hash table is modified between calls to this function, the + result is undefined. */ + +int +hash_table_iter_next (hash_table_iterator *iter) +{ + struct cell *c = iter->pos; + struct cell *end = iter->end; + for (; c < end; c++) + if (CELL_OCCUPIED (c)) + { + iter->key = c->key; + iter->value = c->value; + iter->pos = c + 1; + return 1; + } + return 0; +} + +/* Return the number of elements in the hash table. This is not the + same as the physical size of the hash table, which is always + greater than the number of elements. */ + +int +hash_table_count (const struct hash_table *ht) +{ + return ht->count; +} + +/* Functions from this point onward are meant for convenience and + don't strictly belong to this file. However, this is as good a + place for them as any. */ + +/* Guidelines for creating custom hash and test functions: + + - The test function returns non-zero for keys that are considered + "equal", zero otherwise. + + - The hash function returns a number that represents the + "distinctness" of the object. In more precise terms, it means + that for any two objects that test "equal" under the test + function, the hash function MUST produce the same result. + + This does not mean that all different objects must produce + different values (that would be "perfect" hashing), only that + non-distinct objects must produce the same values! For instance, + a hash function that returns 0 for any given object is a + perfectly valid (albeit extremely bad) hash function. A hash + function that hashes a string by adding up all its characters is + another example of a valid (but still quite bad) hash function. + + It is not hard to make hash and test functions agree about + equality. For example, if the test function compares strings + case-insensitively, the hash function can lower-case the + characters when calculating the hash value. That ensures that + two strings differing only in case will hash the same. + + - To prevent performance degradation, choose a hash function with + as good "spreading" as possible. A good hash function will use + all the bits of the input when calculating the hash, and will + react to even small changes in input with a completely different + output. But don't make the hash function itself overly slow, + because you'll be incurring a non-negligible overhead to all hash + table operations. */ + +/* + * Support for hash tables whose keys are strings. + * + */ + +/* Base 31 hash function. Taken from Gnome's glib, modified to use + standard C types. + + We used to use the popular hash function from the Dragon Book, but + this one seems to perform much better, both by being faster and by + generating less collisions. */ + +#ifdef __clang__ +__attribute__((no_sanitize("integer"))) +#endif +static unsigned long +hash_string (const void *key) +{ + const char *p = key; + unsigned int h = *p; + + if (h) + for (p += 1; *p != '\0'; p++) + h = (h << 5) - h + *p; + + return h; +} + +/* Frontend for strcmp usable for hash tables. */ + +static int +cmp_string (const void *s1, const void *s2) +{ + return !strcmp ((const char *)s1, (const char *)s2); +} + +/* Return a hash table of preallocated to store at least ITEMS items + suitable to use strings as keys. */ + +struct hash_table * +make_string_hash_table (int items) +{ + return hash_table_new (items, hash_string, cmp_string); +} + +/* + * Support for hash tables whose keys are strings, but which are + * compared case-insensitively. + * + */ + +/* Like hash_string, but produce the same hash regardless of the case. */ + +#ifdef __clang__ +__attribute__((no_sanitize("integer"))) +#endif +static unsigned long +hash_string_nocase (const void *key) +{ + const char *p = key; + unsigned int h = c_tolower (*p); + + if (h) + for (p += 1; *p != '\0'; p++) + h = (h << 5) - h + c_tolower (*p); + + return h; +} + +/* Like string_cmp, but doing case-insensitive comparison. */ + +static int +string_cmp_nocase (const void *s1, const void *s2) +{ + return !strcasecmp ((const char *)s1, (const char *)s2); +} + +/* Like make_string_hash_table, but uses string_hash_nocase and + string_cmp_nocase. */ + +struct hash_table * +make_nocase_string_hash_table (int items) +{ + return hash_table_new (items, hash_string_nocase, string_cmp_nocase); +} + +/* Hashing of numeric values, such as pointers and integers. + + This implementation is the Robert Jenkins' 32 bit Mix Function, + with a simple adaptation for 64-bit values. According to Jenkins + it should offer excellent spreading of values. Unlike the popular + Knuth's multiplication hash, this function doesn't need to know the + hash table size to work. */ + +#ifdef __clang__ +__attribute__((no_sanitize("integer"))) +#endif +unsigned long +hash_pointer (const void *ptr) +{ + uintptr_t key = (uintptr_t) ptr; + key += (key << 12); + key ^= (key >> 22); + key += (key << 4); + key ^= (key >> 9); + key += (key << 10); + key ^= (key >> 2); + key += (key << 7); + key ^= (key >> 12); +#if SIZEOF_VOID_P > 4 + key += (key << 44); + key ^= (key >> 54); + key += (key << 36); + key ^= (key >> 41); + key += (key << 42); + key ^= (key >> 34); + key += (key << 39); + key ^= (key >> 44); +#endif + return (unsigned long) key; +} + +static int +cmp_pointer (const void *ptr1, const void *ptr2) +{ + return ptr1 == ptr2; +} + +#ifdef TEST + +#include +#include + +void +print_hash (struct hash_table *sht) +{ + hash_table_iterator iter; + int count = 0; + + for (hash_table_iterate (sht, &iter); hash_table_iter_next (&iter); + ++count) + printf ("%s: %s\n", iter.key, iter.value); + assert (count == sht->count); +} + +int +main (void) +{ + struct hash_table *ht = make_string_hash_table (0); + char line[80]; + +#ifdef ENABLE_NLS + /* Set the current locale. */ + setlocale (LC_ALL, ""); + /* Set the text message domain. */ + bindtextdomain ("wget", LOCALEDIR); + textdomain ("wget"); +#endif /* ENABLE_NLS */ + + while ((fgets (line, sizeof (line), stdin))) + { + int len = strlen (line); + if (len <= 1) + continue; + line[--len] = '\0'; + if (!hash_table_contains (ht, line)) + hash_table_put (ht, strdup (line), "here I am!"); +#if 1 + if (len % 5 == 0) + { + char *line_copy; + if (hash_table_get_pair (ht, line, &line_copy, NULL)) + { + hash_table_remove (ht, line); + xfree (line_copy); + } + } +#endif + } +#if 0 + print_hash (ht); +#endif +#if 1 + printf ("%d %d\n", ht->count, ht->size); +#endif + return 0; +} +#endif /* TEST */ diff --git a/src/hash.h b/src/hash.h new file mode 100644 index 0000000..b8f7965 --- /dev/null +++ b/src/hash.h @@ -0,0 +1,66 @@ +/* Hash table declarations. + Copyright (C) 2000, 2007-2011, 2015, 2018-2020 Free Software + Foundation, Inc. + +This file is part of GNU Wget. + +GNU Wget is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 3 of the License, or +(at your option) any later version. + +GNU Wget 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 Wget. If not, see . + +Additional permission under GNU GPL version 3 section 7 + +If you modify this program, or any covered work, by linking or +combining it with the OpenSSL project's OpenSSL library (or a +modified version of that library), containing parts covered by the +terms of the OpenSSL or SSLeay licenses, the Free Software Foundation +grants you additional permission to convey the resulting work. +Corresponding Source for a non-source form of such a combination +shall include the source code for the parts of OpenSSL used as well +as that of the covered work. */ + +#ifndef HASH_H +#define HASH_H + +struct hash_table; + +struct hash_table *hash_table_new (int, unsigned long (*) (const void *), + int (*) (const void *, const void *)); +void hash_table_destroy (struct hash_table *); + +void *hash_table_get (const struct hash_table *, const void *); +int hash_table_get_pair (const struct hash_table *, const void *, + void *, void *); +int hash_table_contains (const struct hash_table *, const void *); + +void hash_table_put (struct hash_table *, const void *, const void *); +int hash_table_remove (struct hash_table *, const void *); +void hash_table_clear (struct hash_table *); + +void hash_table_for_each (struct hash_table *, + int (*) (void *, void *, void *), void *); + +typedef struct { + void *key, *value; /* public members */ + void *pos, *end; /* private members */ +} hash_table_iterator; +void hash_table_iterate (struct hash_table *, hash_table_iterator *); +int hash_table_iter_next (hash_table_iterator *); + +int hash_table_count (const struct hash_table *); + +struct hash_table *make_string_hash_table (int); +struct hash_table *make_nocase_string_hash_table (int); + +unsigned long hash_pointer (const void *); + +#endif /* HASH_H */ diff --git a/src/host.c b/src/host.c new file mode 100644 index 0000000..353c1cc --- /dev/null +++ b/src/host.c @@ -0,0 +1,1082 @@ +/* Host name resolution and matching. + Copyright (C) 1996-2012, 2015, 2018-2020 Free Software Foundation, + Inc. + +This file is part of GNU Wget. + +GNU Wget is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + +GNU Wget 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 Wget. If not, see . + +Additional permission under GNU GPL version 3 section 7 + +If you modify this program, or any covered work, by linking or +combining it with the OpenSSL project's OpenSSL library (or a +modified version of that library), containing parts covered by the +terms of the OpenSSL or SSLeay licenses, the Free Software Foundation +grants you additional permission to convey the resulting work. +Corresponding Source for a non-source form of such a combination +shall include the source code for the parts of OpenSSL used as well +as that of the covered work. */ + +#include "wget.h" + +#include +#include +#include +#include + +#ifndef WINDOWS +# include +# include +# include +# ifndef __BEOS__ +# include +# endif +# ifdef __VMS +# include "vms_ip.h" +# else /* def __VMS */ +# include +# endif /* def __VMS [else] */ +# define SET_H_ERRNO(err) ((void)(h_errno = (err))) +#else /* WINDOWS */ +# include +# include +# define SET_H_ERRNO(err) WSASetLastError (err) +#endif /* WINDOWS */ + +#include + +#include "utils.h" +#include "host.h" +#include "url.h" +#include "hash.h" +#include "ptimer.h" + +#ifndef NO_ADDRESS +# define NO_ADDRESS NO_DATA +#endif + +#if !HAVE_DECL_H_ERRNO && !defined(WINDOWS) +extern int h_errno; +#endif + + +/* Lists of IP addresses that result from running DNS queries. See + lookup_host for details. */ + +struct address_list { + int count; /* number of addresses */ + ip_address *addresses; /* pointer to the string of addresses */ + + int faulty; /* number of addresses known not to work. */ + bool connected; /* whether we were able to connect to + one of the addresses in the list, + at least once. */ + + int refcount; /* reference count; when it drops to + 0, the entry is freed. */ +}; + +/* Get the bounds of the address list. */ + +void +address_list_get_bounds (const struct address_list *al, int *start, int *end) +{ + *start = al->faulty; + *end = al->count; +} + +/* Return a pointer to the address at position POS. */ + +const ip_address * +address_list_address_at (const struct address_list *al, int pos) +{ + assert (pos >= al->faulty && pos < al->count); + return al->addresses + pos; +} + +/* Return true if AL contains IP, false otherwise. */ + +bool +address_list_contains (const struct address_list *al, const ip_address *ip) +{ + int i; + switch (ip->family) + { + case AF_INET: + for (i = 0; i < al->count; i++) + { + ip_address *cur = al->addresses + i; + if (cur->family == AF_INET + && (cur->data.d4.s_addr == ip->data.d4.s_addr)) + return true; + } + return false; +#ifdef ENABLE_IPV6 + case AF_INET6: + for (i = 0; i < al->count; i++) + { + ip_address *cur = al->addresses + i; + if (cur->family == AF_INET6 +#ifdef HAVE_SOCKADDR_IN6_SCOPE_ID + && cur->ipv6_scope == ip->ipv6_scope +#endif + && IN6_ARE_ADDR_EQUAL (&cur->data.d6, &ip->data.d6)) + return true; + } + return false; +#endif /* ENABLE_IPV6 */ + default: + abort (); + } +} + +/* Mark the INDEXth element of AL as faulty, so that the next time + this address list is used, the faulty element will be skipped. */ + +void +address_list_set_faulty (struct address_list *al, int index) +{ + /* We assume that the address list is traversed in order, so that a + "faulty" attempt is always preceded with all-faulty addresses, + and this is how Wget uses it. */ + assert (index == al->faulty); + if (index != al->faulty) + { + logprintf (LOG_ALWAYS, "index: %d\nal->faulty: %d\n", index, al->faulty); + logprintf (LOG_ALWAYS, _("Error in handling the address list.\n")); + logprintf (LOG_ALWAYS, _("Please report this issue to bug-wget@gnu.org\n")); + abort(); + } + + ++al->faulty; + if (al->faulty >= al->count) + /* All addresses have been proven faulty. Since there's not much + sense in returning the user an empty address list the next + time, we'll rather make them all clean, so that they can be + retried anew. */ + al->faulty = 0; +} + +/* Set the "connected" flag to true. This flag used by connect.c to + see if the host perhaps needs to be resolved again. */ + +void +address_list_set_connected (struct address_list *al) +{ + al->connected = true; +} + +/* Return the value of the "connected" flag. */ + +bool +address_list_connected_p (const struct address_list *al) +{ + return al->connected; +} + +#ifdef ENABLE_IPV6 + +/* Create an address_list from the addresses in the given struct + addrinfo. */ + +static struct address_list * +address_list_from_addrinfo (const struct addrinfo *ai) +{ + struct address_list *al; + const struct addrinfo *ptr; + int cnt; + ip_address *ip; + + cnt = 0; + for (ptr = ai; ptr != NULL ; ptr = ptr->ai_next) + if (ptr->ai_family == AF_INET || ptr->ai_family == AF_INET6) + ++cnt; + if (cnt == 0) + return NULL; + + al = xnew0 (struct address_list); + al->addresses = xnew_array (ip_address, cnt); + al->count = cnt; + al->refcount = 1; + + ip = al->addresses; + for (ptr = ai; ptr != NULL; ptr = ptr->ai_next) + if (ptr->ai_family == AF_INET6) + { + const struct sockaddr_in6 *sin6 = + (const struct sockaddr_in6 *)ptr->ai_addr; + ip->family = AF_INET6; + ip->data.d6 = sin6->sin6_addr; +#ifdef HAVE_SOCKADDR_IN6_SCOPE_ID + ip->ipv6_scope = sin6->sin6_scope_id; +#endif + ++ip; + } + else if (ptr->ai_family == AF_INET) + { + const struct sockaddr_in *sin = + (const struct sockaddr_in *)ptr->ai_addr; + ip->family = AF_INET; + ip->data.d4 = sin->sin_addr; + ++ip; + } + assert (ip - al->addresses == cnt); + return al; +} + +#define IS_IPV4(addr) (((const ip_address *) addr)->family == AF_INET) + +/* Compare two IP addresses by family, giving preference to the IPv4 + address (sorting it first). In other words, return -1 if ADDR1 is + IPv4 and ADDR2 is IPv6, +1 if ADDR1 is IPv6 and ADDR2 is IPv4, and + 0 otherwise. + + This is intended to be used as the comparator arg to a qsort-like + sorting function, which is why it accepts generic pointers. */ + +static int +cmp_prefer_ipv4 (const void *addr1, const void *addr2) +{ + return !IS_IPV4 (addr1) - !IS_IPV4 (addr2); +} + +#define IS_IPV6(addr) (((const ip_address *) addr)->family == AF_INET6) + +/* Like the above, but give preference to the IPv6 address. */ + +static int +cmp_prefer_ipv6 (const void *addr1, const void *addr2) +{ + return !IS_IPV6 (addr1) - !IS_IPV6 (addr2); +} + +#else /* not ENABLE_IPV6 */ + +/* Create an address_list from a NULL-terminated vector of IPv4 + addresses. This kind of vector is returned by gethostbyname. */ + +static struct address_list * +address_list_from_ipv4_addresses (char **vec) +{ + int count, i; + struct address_list *al = xnew0 (struct address_list); + + count = 0; + while (vec[count]) + ++count; + assert (count > 0); + + al->addresses = xnew_array (ip_address, count); + al->count = count; + al->refcount = 1; + + for (i = 0; i < count; i++) + { + ip_address *ip = &al->addresses[i]; + ip->family = AF_INET; + memcpy (IP_INADDR_DATA (ip), vec[i], 4); + } + + return al; +} + +#endif /* not ENABLE_IPV6 */ + +static void +address_list_delete (struct address_list *al) +{ + xfree (al->addresses); + xfree (al); +} + +/* Mark the address list as being no longer in use. This will reduce + its reference count which will cause the list to be freed when the + count reaches 0. */ + +void +address_list_release (struct address_list *al) +{ + --al->refcount; + DEBUGP (("Releasing 0x%0*lx (new refcount %d).\n", PTR_FORMAT (al), + al->refcount)); + if (al->refcount <= 0) + { + DEBUGP (("Deleting unused 0x%0*lx.\n", PTR_FORMAT (al))); + address_list_delete (al); + } +} + +/* Versions of gethostbyname and getaddrinfo that support timeout. */ + +#ifndef ENABLE_IPV6 + +struct ghbnwt_context { + const char *host_name; + struct hostent *hptr; +}; + +static void +gethostbyname_with_timeout_callback (void *arg) +{ + struct ghbnwt_context *ctx = (struct ghbnwt_context *)arg; + ctx->hptr = gethostbyname (ctx->host_name); +} + +/* Just like gethostbyname, except it times out after TIMEOUT seconds. + In case of timeout, NULL is returned and errno is set to ETIMEDOUT. + The function makes sure that when NULL is returned for reasons + other than timeout, errno is reset. */ + +static struct hostent * +gethostbyname_with_timeout (const char *host_name, double timeout) +{ + struct ghbnwt_context ctx; + ctx.host_name = host_name; + if (run_with_timeout (timeout, gethostbyname_with_timeout_callback, &ctx)) + { + SET_H_ERRNO (HOST_NOT_FOUND); + errno = ETIMEDOUT; + return NULL; + } + if (!ctx.hptr) + errno = 0; + return ctx.hptr; +} + +/* Print error messages for host errors. */ +static const char * +host_errstr (int error) +{ + /* Can't use switch since some of these constants can be equal, + which makes the compiler complain about duplicate case + values. */ + if (error == HOST_NOT_FOUND + || error == NO_RECOVERY + || error == NO_DATA + || error == NO_ADDRESS) + return _("Unknown host"); + else if (error == TRY_AGAIN) + /* Message modeled after what gai_strerror returns in similar + circumstances. */ + return _("Temporary failure in name resolution"); + else + return _("Unknown error"); +} + +#else /* ENABLE_IPV6 */ + +struct gaiwt_context { + const char *node; + const char *service; + const struct addrinfo *hints; + struct addrinfo **res; + int exit_code; +}; + +static void +getaddrinfo_with_timeout_callback (void *arg) +{ + struct gaiwt_context *ctx = (struct gaiwt_context *)arg; + ctx->exit_code = getaddrinfo (ctx->node, ctx->service, ctx->hints, ctx->res); +} + +/* Just like getaddrinfo, except it times out after TIMEOUT seconds. + In case of timeout, the EAI_SYSTEM error code is returned and errno + is set to ETIMEDOUT. */ + +static int +getaddrinfo_with_timeout (const char *node, const char *service, + const struct addrinfo *hints, struct addrinfo **res, + double timeout) +{ + struct gaiwt_context ctx; + ctx.node = node; + ctx.service = service; + ctx.hints = hints; + ctx.res = res; + + if (run_with_timeout (timeout, getaddrinfo_with_timeout_callback, &ctx)) + { + errno = ETIMEDOUT; + return EAI_SYSTEM; + } + return ctx.exit_code; +} + +#endif /* ENABLE_IPV6 */ + +/* Return a textual representation of ADDR, i.e. the dotted quad for + IPv4 addresses, and the colon-separated list of hex words (with all + zeros omitted, etc.) for IPv6 addresses. */ + +const char * +print_address (const ip_address *addr) +{ + static char buf[64]; + + if (!inet_ntop (addr->family, IP_INADDR_DATA (addr), buf, sizeof buf)) + snprintf (buf, sizeof buf, "", strerror (errno)); + + return buf; +} + +/* The following two functions were adapted from glibc's + implementation of inet_pton, written by Paul Vixie. */ + +static bool +is_valid_ipv4_address (const char *str, const char *end) +{ + bool saw_digit = false; + int octets = 0; + int val = 0; + + while (str < end) + { + int ch = *str++; + + if (ch >= '0' && ch <= '9') + { + val = val * 10 + (ch - '0'); + + if (val > 255) + return false; + if (!saw_digit) + { + if (++octets > 4) + return false; + saw_digit = true; + } + } + else if (ch == '.' && saw_digit) + { + if (octets == 4) + return false; + val = 0; + saw_digit = false; + } + else + return false; + } + if (octets < 4) + return false; + + return true; +} + +bool +is_valid_ipv6_address (const char *str, const char *end) +{ + /* Use lower-case for these to avoid clash with system headers. */ + enum { + ns_inaddrsz = 4, + ns_in6addrsz = 16, + ns_int16sz = 2 + }; + + const char *curtok; + int tp; + const char *colonp; + bool saw_xdigit; + unsigned int val; + + tp = 0; + colonp = NULL; + + if (str == end) + return false; + + /* Leading :: requires some special handling. */ + if (*str == ':') + { + ++str; + if (str == end || *str != ':') + return false; + } + + curtok = str; + saw_xdigit = false; + val = 0; + + while (str < end) + { + int ch = *str++; + + /* if ch is a number, add it to val. */ + if (c_isxdigit (ch)) + { + val <<= 4; + val |= _unhex (ch); + if (val > 0xffff) + return false; + saw_xdigit = true; + continue; + } + + /* if ch is a colon ... */ + if (ch == ':') + { + curtok = str; + if (!saw_xdigit) + { + if (colonp != NULL) + return false; + colonp = str + tp; + continue; + } + else if (str == end) + return false; + if (tp > ns_in6addrsz - ns_int16sz) + return false; + tp += ns_int16sz; + saw_xdigit = false; + val = 0; + continue; + } + + /* if ch is a dot ... */ + if (ch == '.' && (tp <= ns_in6addrsz - ns_inaddrsz) + && is_valid_ipv4_address (curtok, end) == 1) + { + tp += ns_inaddrsz; + saw_xdigit = false; + break; + } + + return false; + } + + if (saw_xdigit) + { + if (tp > ns_in6addrsz - ns_int16sz) + return false; + tp += ns_int16sz; + } + + if (colonp != NULL) + { + if (tp == ns_in6addrsz) + return false; + tp = ns_in6addrsz; + } + + if (tp != ns_in6addrsz) + return false; + + return true; +} + +/* Simple host cache, used by lookup_host to speed up resolving. The + cache doesn't handle TTL because Wget is a fairly short-lived + application. Refreshing is attempted when connect fails, though -- + see connect_to_host. */ + +/* Mapping between known hosts and to lists of their addresses. */ +static struct hash_table *host_name_addresses_map; + + +/* Return the host's resolved addresses from the cache, if + available. */ + +static struct address_list * +cache_query (const char *host) +{ + struct address_list *al; + if (!host_name_addresses_map) + return NULL; + al = hash_table_get (host_name_addresses_map, host); + if (al) + { + DEBUGP (("Found %s in host_name_addresses_map (%p)\n", host, (void *) al)); + ++al->refcount; + return al; + } + return NULL; +} + +/* Cache the DNS lookup of HOST. Subsequent invocations of + lookup_host will return the cached value. */ + +static void +cache_store (const char *host, struct address_list *al) +{ + if (!host_name_addresses_map) + host_name_addresses_map = make_nocase_string_hash_table (0); + + ++al->refcount; + hash_table_put (host_name_addresses_map, xstrdup_lower (host), al); + + IF_DEBUG + { + int i; + debug_logprintf ("Caching %s =>", host); + for (i = 0; i < al->count; i++) + debug_logprintf (" %s", print_address (al->addresses + i)); + debug_logprintf ("\n"); + } +} + +/* Remove HOST from the DNS cache. Does nothing is HOST is not in + the cache. */ + +static void +cache_remove (const char *host) +{ + struct address_list *al; + if (!host_name_addresses_map) + return; + al = hash_table_get (host_name_addresses_map, host); + if (al) + { + address_list_release (al); + hash_table_remove (host_name_addresses_map, host); + } +} + +#ifdef HAVE_LIBCARES +#include +#include +extern ares_channel ares; + +static struct address_list * +merge_address_lists (struct address_list *al1, struct address_list *al2) +{ + int count = al1->count + al2->count; + + /* merge al2 into al1 */ + al1->addresses = xrealloc (al1->addresses, sizeof (ip_address) * count); + memcpy (al1->addresses + al1->count, al2->addresses, sizeof (ip_address) * al2->count); + al1->count = count; + + address_list_delete (al2); + + return al1; +} + +static struct address_list * +address_list_from_hostent (struct hostent *host) +{ + int count, i; + struct address_list *al = xnew0 (struct address_list); + + for (count = 0; host->h_addr_list[count]; count++) + ; + + assert (count > 0); + + al->addresses = xnew_array (ip_address, count); + al->count = count; + al->refcount = 1; + + for (i = 0; i < count; i++) + { + ip_address *ip = &al->addresses[i]; + ip->family = host->h_addrtype; + memcpy (IP_INADDR_DATA (ip), host->h_addr_list[i], ip->family == AF_INET ? 4 : 16); + } + + return al; +} + +/* Since GnuLib's select() (i.e. rpl_select()) cannot handle socket-numbers + * returned from C-ares, we must use the original select() from Winsock. + */ +#ifdef WINDOWS +#undef select +#endif + +static void +wait_ares (ares_channel channel) +{ + struct ptimer *timer = NULL; + + if (opt.dns_timeout) + timer = ptimer_new (); + + for (;;) + { + struct timeval *tvp, tv; + fd_set read_fds, write_fds; + int nfds, rc; + + FD_ZERO (&read_fds); + FD_ZERO (&write_fds); + nfds = ares_fds (channel, &read_fds, &write_fds); + if (nfds == 0) + break; + + if (timer) + { + double max = opt.dns_timeout - ptimer_measure (timer); + + tv.tv_sec = (long) max; + tv.tv_usec = 1000000 * (max - (long) max); + tvp = ares_timeout (channel, &tv, &tv); + } + else + tvp = ares_timeout (channel, NULL, &tv); + + rc = select (nfds, &read_fds, &write_fds, NULL, tvp); + if (rc == 0 && timer && ptimer_measure (timer) >= opt.dns_timeout) + ares_cancel (channel); + else + ares_process (channel, &read_fds, &write_fds); + } + if (timer) + ptimer_destroy (timer); +} + +static void +callback (void *arg, int status, int timeouts _GL_UNUSED, struct hostent *host) +{ + struct address_list **al = (struct address_list **) arg; + + if (!host || status != ARES_SUCCESS) + { + *al = NULL; + return; + } + + *al = address_list_from_hostent (host); +} +#endif + +/* Look up HOST in DNS and return a list of IP addresses. + + This function caches its result so that, if the same host is passed + the second time, the addresses are returned without DNS lookup. + (Use LH_REFRESH to force lookup, or set opt.dns_cache to 0 to + globally disable caching.) + + The order of the returned addresses is affected by the setting of + opt.prefer_family: if it is set to prefer_ipv4, IPv4 addresses are + placed at the beginning; if it is prefer_ipv6, IPv6 ones are placed + at the beginning; otherwise, the order is left intact. The + relative order of addresses with the same family is left + undisturbed in either case. + + FLAGS can be a combination of: + LH_SILENT - don't print the "resolving ... done" messages. + LH_BIND - resolve addresses for use with bind, which under + IPv6 means to use AI_PASSIVE flag to getaddrinfo. + Passive lookups are not cached under IPv6. + LH_REFRESH - if HOST is cached, remove the entry from the cache + and resolve it anew. */ + +struct address_list * +lookup_host (const char *host, int flags) +{ + struct address_list *al; + bool silent = !!(flags & LH_SILENT); + bool use_cache; + bool numeric_address = false; + double timeout = opt.dns_timeout; + +#ifndef ENABLE_IPV6 + /* If we're not using getaddrinfo, first check if HOST specifies a + numeric IPv4 address. Some implementations of gethostbyname + (e.g. the Ultrix one and possibly Winsock) don't accept + dotted-decimal IPv4 addresses. */ + { + uint32_t addr_ipv4 = (uint32_t)inet_addr (host); + if (addr_ipv4 != (uint32_t) -1) + { + /* No need to cache host->addr relation, just return the + address. */ + char *vec[2]; + vec[0] = (char *)&addr_ipv4; + vec[1] = NULL; + return address_list_from_ipv4_addresses (vec); + } + } +#else /* ENABLE_IPV6 */ + /* If we're using getaddrinfo, at least check whether the address is + already numeric, in which case there is no need to print the + "Resolving..." output. (This comes at no additional cost since + the is_valid_ipv*_address are already required for + url_parse.) */ + { + const char *end = host + strlen (host); + if (is_valid_ipv4_address (host, end) || is_valid_ipv6_address (host, end)) + numeric_address = true; + } +#endif + + /* Cache is normally on, but can be turned off with --no-dns-cache. + Don't cache passive lookups under IPv6. */ + use_cache = opt.dns_cache; +#ifdef ENABLE_IPV6 + if ((flags & LH_BIND) || numeric_address) + use_cache = false; +#endif + + /* Try to find the host in the cache so we don't need to talk to the + resolver. If LH_REFRESH is requested, remove HOST from the cache + instead. */ + if (use_cache) + { + if (!(flags & LH_REFRESH)) + { + al = cache_query (host); + if (al) + return al; + } + else + cache_remove (host); + } + + /* No luck with the cache; resolve HOST. */ + + if (!silent && !numeric_address) + { + char *str = NULL, *name; + + if (opt.enable_iri && (name = idn_decode ((char *) host)) != NULL) + { + str = aprintf ("%s (%s)", name, host); + xfree (name); + } + + logprintf (LOG_VERBOSE, _("Resolving %s... "), + quotearg_style (escape_quoting_style, str ? str : host)); + + xfree (str); + } + +#ifdef ENABLE_IPV6 +#ifdef HAVE_LIBCARES + if (ares) + { + struct address_list *al4 = NULL; + struct address_list *al6 = NULL; + + if (opt.ipv4_only || !opt.ipv6_only) + ares_gethostbyname (ares, host, AF_INET, callback, &al4); + if (opt.ipv6_only || !opt.ipv4_only) + ares_gethostbyname (ares, host, AF_INET6, callback, &al6); + + wait_ares (ares); + + if (al4 && al6) + al = merge_address_lists (al4, al6); + else if (al4) + al = al4; + else + al = al6; + } + else +#endif + { + int err; + struct addrinfo hints, *res; + + xzero (hints); + hints.ai_socktype = SOCK_STREAM; + if (opt.ipv4_only) + hints.ai_family = AF_INET; + else if (opt.ipv6_only) + hints.ai_family = AF_INET6; + else + /* We tried using AI_ADDRCONFIG, but removed it because: it + misinterprets IPv6 loopbacks, it is broken on AIX 5.1, and + it's unneeded since we sort the addresses anyway. */ + hints.ai_family = AF_UNSPEC; + + if (flags & LH_BIND) + hints.ai_flags |= AI_PASSIVE; + +#ifdef AI_NUMERICHOST + if (numeric_address) + { + /* Where available, the AI_NUMERICHOST hint can prevent costly + access to DNS servers. */ + hints.ai_flags |= AI_NUMERICHOST; + timeout = 0; /* no timeout needed when "resolving" + numeric hosts -- avoid setting up + signal handlers and such. */ + } +#endif + + err = getaddrinfo_with_timeout (host, NULL, &hints, &res, timeout); + + if (err != 0 || res == NULL) + { + if (!silent) + logprintf (LOG_VERBOSE, _ ("failed: %s.\n"), + err != EAI_SYSTEM ? gai_strerror (err) : strerror (errno)); + return NULL; + } + al = address_list_from_addrinfo (res); + freeaddrinfo (res); + } + + if (!al) + { + logprintf (LOG_VERBOSE, + _ ("failed: No IPv4/IPv6 addresses for host.\n")); + return NULL; + } + + /* Reorder addresses so that IPv4 ones (or IPv6 ones, as per + --prefer-family) come first. Sorting is stable so the order of + the addresses with the same family is undisturbed. */ + if (al->count > 1 && opt.prefer_family != prefer_none) + stable_sort (al->addresses, al->count, sizeof (ip_address), + opt.prefer_family == prefer_ipv4 + ? cmp_prefer_ipv4 : cmp_prefer_ipv6); +#else /* not ENABLE_IPV6 */ +#ifdef HAVE_LIBCARES + if (ares) + { + ares_gethostbyname (ares, host, AF_INET, callback, &al); + wait_ares (ares); + } + else +#endif + { + struct hostent *hptr = gethostbyname_with_timeout (host, timeout); + if (!hptr) + { + if (!silent) + { + if (errno != ETIMEDOUT) + logprintf (LOG_VERBOSE, _ ("failed: %s.\n"), + host_errstr (h_errno)); + else + logputs (LOG_VERBOSE, _ ("failed: timed out.\n")); + } + return NULL; + } + /* Do older systems have h_addr_list? */ + al = address_list_from_ipv4_addresses (hptr->h_addr_list); + } +#endif /* not ENABLE_IPV6 */ + + /* Print the addresses determined by DNS lookup, but no more than + three if show_all_dns_entries is not specified. */ + if (!silent && !numeric_address) + { + int i; + int printmax = al->count; + + if (!opt.show_all_dns_entries && printmax > 3) + printmax = 3; + + for (i = 0; i < printmax; i++) + { + logputs (LOG_VERBOSE, print_address (al->addresses + i)); + if (i < printmax - 1) + logputs (LOG_VERBOSE, ", "); + } + if (printmax != al->count) + logputs (LOG_VERBOSE, ", ..."); + logputs (LOG_VERBOSE, "\n"); + } + + /* Cache the lookup information. */ + if (use_cache) + cache_store (host, al); + + return al; +} + +/* Determine whether a URL is acceptable to be followed, according to + a list of domains to accept. */ +bool +accept_domain (struct url *u) +{ + assert (u->host != NULL); + if (opt.domains) + { + if (!sufmatch ((const char **)opt.domains, u->host)) + return false; + } + if (opt.exclude_domains) + { + if (sufmatch ((const char **)opt.exclude_domains, u->host)) + return false; + } + return true; +} + +/* Check whether WHAT is matched in LIST, each element of LIST being a + pattern to match WHAT against, using backward matching (see + match_backwards() in utils.c). + + If an element of LIST matched, 1 is returned, 0 otherwise. */ +bool +sufmatch (const char **list, const char *what) +{ + int i, j, k, lw; + + lw = strlen (what); + + for (i = 0; list[i]; i++) + { + j = strlen (list[i]); + if (lw < j) + continue; /* what is no (sub)domain of list[i] */ + + for (k = lw; j >= 0 && k >= 0; j--, k--) + if (c_tolower (list[i][j]) != c_tolower (what[k])) + break; + + /* Domain or subdomain match + * k == -1: exact match + * k >= 0 && what[k] == '.': subdomain match + * k >= 0 && list[i][0] == '.': dot-prefixed subdomain match + */ + if (j == -1 && (k == -1 || what[k] == '.' || list[i][0] == '.')) + return true; + } + + return false; +} + +#if defined DEBUG_MALLOC || defined TESTING +void +host_cleanup (void) +{ + if (host_name_addresses_map) + { + hash_table_iterator iter; + for (hash_table_iterate (host_name_addresses_map, &iter); + hash_table_iter_next (&iter); + ) + { + char *host = iter.key; + struct address_list *al = iter.value; + xfree (host); + assert (al->refcount == 1); + address_list_delete (al); + } + hash_table_destroy (host_name_addresses_map); + host_name_addresses_map = NULL; + } +} +#endif + +bool +is_valid_ip_address (const char *name) +{ + const char *endp; + + endp = name + strlen(name); + if (is_valid_ipv4_address (name, endp)) + return true; +#ifdef ENABLE_IPV6 + if (is_valid_ipv6_address (name, endp)) + return true; +#endif + return false; +} diff --git a/src/host.h b/src/host.h new file mode 100644 index 0000000..a199d26 --- /dev/null +++ b/src/host.h @@ -0,0 +1,107 @@ +/* Declarations for host.c + Copyright (C) 1996-2012, 2015, 2018-2020 Free Software Foundation, + Inc. + +This file is part of GNU Wget. + +GNU Wget is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + +GNU Wget 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 Wget. If not, see . + +Additional permission under GNU GPL version 3 section 7 + +If you modify this program, or any covered work, by linking or +combining it with the OpenSSL project's OpenSSL library (or a +modified version of that library), containing parts covered by the +terms of the OpenSSL or SSLeay licenses, the Free Software Foundation +grants you additional permission to convey the resulting work. +Corresponding Source for a non-source form of such a combination +shall include the source code for the parts of OpenSSL used as well +as that of the covered work. */ + +#ifndef HOST_H +#define HOST_H + +#ifdef WINDOWS +# include +#else +# ifdef __VMS +# include "vms_ip.h" +# else /* def __VMS */ +# include +# endif /* def __VMS [else] */ +# include +# include +#ifndef __BEOS__ +# include +#endif +#endif + +struct url; +struct address_list; + +/* This struct defines an IP address, tagged with family type. */ + +typedef struct { + /* Address family, one of AF_INET or AF_INET6. */ + int family; + + /* The actual data, in the form of struct in_addr or in6_addr: */ + union { + struct in_addr d4; /* IPv4 address */ +#ifdef ENABLE_IPV6 + struct in6_addr d6; /* IPv6 address */ +#endif + } data; + + /* Under IPv6 getaddrinfo also returns scope_id. Since it's + IPv6-specific it strictly belongs in the above union, but we put + it here for simplicity. */ +#if defined ENABLE_IPV6 && defined HAVE_SOCKADDR_IN6_SCOPE_ID + int ipv6_scope; +#endif +} ip_address; + +/* IP_INADDR_DATA macro returns a void pointer that can be interpreted + as a pointer to struct in_addr in IPv4 context or a pointer to + struct in6_addr in IPv4 context. This pointer can be passed to + functions that work on either, such as inet_ntop. */ +#define IP_INADDR_DATA(x) ((void *) &(x)->data) + +enum { + LH_SILENT = 1, + LH_BIND = 2, + LH_REFRESH = 4 +}; +struct address_list *lookup_host (const char *, int); + +void address_list_get_bounds (const struct address_list *, int *, int *); +const ip_address *address_list_address_at (const struct address_list *, int); +bool address_list_contains (const struct address_list *, const ip_address *); +void address_list_set_faulty (struct address_list *, int); +void address_list_set_connected (struct address_list *); +bool address_list_connected_p (const struct address_list *); +void address_list_release (struct address_list *); + +const char *print_address (const ip_address *); +#ifdef ENABLE_IPV6 +bool is_valid_ipv6_address (const char *, const char *); +#endif + +bool is_valid_ip_address (const char *name); + +bool accept_domain (struct url *); +bool sufmatch (const char **, const char *); + +void host_cleanup (void); + +#endif /* HOST_H */ diff --git a/src/hsts.c b/src/hsts.c new file mode 100644 index 0000000..914d270 --- /dev/null +++ b/src/hsts.c @@ -0,0 +1,829 @@ +/* HTTP Strict Transport Security (HSTS) support. + Copyright (C) 1996-2012, 2015, 2018-2020 Free Software Foundation, + Inc. + +This file is part of GNU Wget. + +GNU Wget is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + +GNU Wget 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 Wget. If not, see . + +Additional permission under GNU GPL version 3 section 7 + +If you modify this program, or any covered work, by linking or +combining it with the OpenSSL project's OpenSSL library (or a +modified version of that library), containing parts covered by the +terms of the OpenSSL or SSLeay licenses, the Free Software Foundation +grants you additional permission to convey the resulting work. +Corresponding Source for a non-source form of such a combination +shall include the source code for the parts of OpenSSL used as well +as that of the covered work. */ +#include "wget.h" + +#ifdef HAVE_HSTS +#include "hsts.h" +#include "utils.h" +#include "host.h" /* for is_valid_ip_address() */ +#include "hash.h" +#include "c-ctype.h" +#ifdef TESTING +#include "init.h" /* for ajoin_dir_file() */ +#include "../tests/unit-tests.h" +#endif + +#include +#include +#include +#include +#include +#include +#include +#include + +struct hsts_store { + struct hash_table *table; + time_t last_mtime; + bool changed; +}; + +struct hsts_kh { + char *host; + int explicit_port; +}; + +struct hsts_kh_info { + time_t created; + time_t max_age; + bool include_subdomains; +}; + +enum hsts_kh_match { + NO_MATCH, + SUPERDOMAIN_MATCH, + CONGRUENT_MATCH +}; + +#define hsts_is_host_name_valid(host) (!is_valid_ip_address (host)) +#define hsts_is_scheme_valid(scheme) (scheme == SCHEME_HTTPS) +#define hsts_is_host_eligible(scheme, host) \ + (hsts_is_scheme_valid (scheme) && hsts_is_host_name_valid (host)) + +#define DEFAULT_HTTP_PORT 80 +#define DEFAULT_SSL_PORT 443 +#define MAKE_EXPLICIT_PORT(s, p) (s == SCHEME_HTTPS ? (p == DEFAULT_SSL_PORT ? 0 : p) \ + : (p == DEFAULT_HTTP_PORT ? 0 : p)) + +/* Hashing and comparison functions for the hash table */ + +#ifdef __clang__ +__attribute__((no_sanitize("integer"))) +#endif +static unsigned long +hsts_hash_func (const void *key) +{ + struct hsts_kh *k = (struct hsts_kh *) key; + const char *h = NULL; + unsigned int hash = k->explicit_port; + + for (h = k->host; *h; h++) + hash = hash * 31 + *h; + + return hash; +} + +static int +hsts_cmp_func (const void *h1, const void *h2) +{ + struct hsts_kh *kh1 = (struct hsts_kh *) h1, + *kh2 = (struct hsts_kh *) h2; + + return (!strcmp (kh1->host, kh2->host)) && (kh1->explicit_port == kh2->explicit_port); +} + +/* Private functions. Feel free to make some of these public when needed. */ + +static struct hsts_kh_info * +hsts_find_entry (hsts_store_t store, + const char *host, int explicit_port, + enum hsts_kh_match *match_type, + struct hsts_kh *kh) +{ + struct hsts_kh *k = NULL; + struct hsts_kh_info *khi = NULL; + enum hsts_kh_match match = NO_MATCH; + char *pos = NULL; + char *org_ptr = NULL; + + k = (struct hsts_kh *) xnew (struct hsts_kh); + k->host = xstrdup_lower (host); + k->explicit_port = explicit_port; + + /* save pointer so that we don't get into trouble later when freeing */ + org_ptr = k->host; + + khi = (struct hsts_kh_info *) hash_table_get (store->table, k); + if (khi) + { + match = CONGRUENT_MATCH; + goto end; + } + + while (match == NO_MATCH && + (pos = strchr (k->host, '.')) && pos - k->host > 0 && + strchr (pos + 1, '.')) + { + k->host += (pos - k->host + 1); + khi = (struct hsts_kh_info *) hash_table_get (store->table, k); + if (khi) + match = SUPERDOMAIN_MATCH; + } + +end: + /* restore pointer or we'll get a SEGV */ + k->host = org_ptr; + + /* copy parameters to previous frame */ + if (match_type) + *match_type = match; + if (kh) + memcpy (kh, k, sizeof (struct hsts_kh)); + else + xfree (k->host); + + xfree (k); + return khi; +} + +static bool +hsts_new_entry_internal (hsts_store_t store, + const char *host, int port, + time_t created, time_t max_age, + bool include_subdomains, + bool check_validity, + bool check_expired, + bool check_duplicates) +{ + struct hsts_kh *kh = xnew (struct hsts_kh); + struct hsts_kh_info *khi = xnew0 (struct hsts_kh_info); + bool success = false; + + kh->host = xstrdup_lower (host); + kh->explicit_port = MAKE_EXPLICIT_PORT (SCHEME_HTTPS, port); + + khi->created = created; + khi->max_age = max_age; + khi->include_subdomains = include_subdomains; + + /* Check validity */ + if (check_validity && !hsts_is_host_name_valid (host)) + goto bail; + + if (check_expired && ((khi->created + khi->max_age) < khi->created)) + goto bail; + + if (check_duplicates && hash_table_contains (store->table, kh)) + goto bail; + + /* Now store the new entry */ + hash_table_put (store->table, kh, khi); + success = true; + +bail: + if (!success) + { + /* abort! */ + xfree (kh->host); + xfree (kh); + xfree (khi); + } + + return success; +} + +/* + Creates a new entry, but does not check whether that entry already exists. + This function assumes that check has already been done by the caller. + */ +static bool +hsts_add_entry (hsts_store_t store, + const char *host, int port, + time_t max_age, bool include_subdomains) +{ + time_t t = time (NULL); + + /* It might happen time() returned -1 */ + return (t == (time_t)(-1) ? + false : + hsts_new_entry_internal (store, host, port, t, max_age, include_subdomains, false, true, false)); +} + +/* Creates a new entry, unless an identical one already exists. */ +static bool +hsts_new_entry (hsts_store_t store, + const char *host, int port, + time_t created, time_t max_age, + bool include_subdomains) +{ + return hsts_new_entry_internal (store, host, port, created, max_age, include_subdomains, true, true, true); +} + +static void +hsts_remove_entry (hsts_store_t store, struct hsts_kh *kh) +{ + hash_table_remove (store->table, kh); +} + +static bool +hsts_store_merge (hsts_store_t store, + const char *host, int port, + time_t created, time_t max_age, + bool include_subdomains) +{ + enum hsts_kh_match match_type = NO_MATCH; + struct hsts_kh_info *khi = NULL; + bool success = false; + + port = MAKE_EXPLICIT_PORT (SCHEME_HTTPS, port); + khi = hsts_find_entry (store, host, port, &match_type, NULL); + if (khi && match_type == CONGRUENT_MATCH && created > khi->created) + { + /* update the entry with the new info */ + khi->created = created; + khi->max_age = max_age; + khi->include_subdomains = include_subdomains; + + success = true; + } + else if (!khi) + success = hsts_new_entry (store, host, port, created, max_age, include_subdomains); + + return success; +} + +static bool +hsts_read_database (hsts_store_t store, FILE *fp, bool merge_with_existing_entries) +{ + char *line = NULL, *p; + size_t len = 0; + int items_read; + bool result = false; + bool (*func)(hsts_store_t, const char *, int, time_t, time_t, bool); + + char host[256]; + int port; + time_t created, max_age; + int include_subdomains; + + func = (merge_with_existing_entries ? hsts_store_merge : hsts_new_entry); + + while (getline (&line, &len, fp) > 0) + { + for (p = line; c_isspace (*p); p++) + ; + + if (*p == '#') + continue; + + items_read = sscanf (p, "%255s %d %d %lu %lu", + host, + &port, + &include_subdomains, + (unsigned long *) &created, + (unsigned long *) &max_age); + + if (items_read == 5) + func (store, host, port, created, max_age, !!include_subdomains); + } + + xfree (line); + result = true; + + return result; +} + +static void +hsts_store_dump (hsts_store_t store, FILE *fp) +{ + hash_table_iterator it; + + /* Print preliminary comments. We don't care if any of these fail. */ + fputs ("# HSTS 1.0 Known Hosts database for GNU Wget.\n", fp); + fputs ("# Edit at your own risk.\n", fp); + fputs ("# \t\t\t\t\n", fp); + + /* Now cycle through the HSTS store in memory and dump the entries */ + for (hash_table_iterate (store->table, &it); hash_table_iter_next (&it);) + { + struct hsts_kh *kh = (struct hsts_kh *) it.key; + struct hsts_kh_info *khi = (struct hsts_kh_info *) it.value; + + if (fprintf (fp, "%s\t%d\t%d\t%lu\t%lu\n", + kh->host, kh->explicit_port, khi->include_subdomains, + (unsigned long) khi->created, + (unsigned long) khi->max_age) < 0) + { + logprintf (LOG_ALWAYS, "Could not write the HSTS database correctly.\n"); + break; + } + } +} + +/* + * Test: + * - The file is a regular file (ie. not a symlink), and + * - The file is not world-writable. + */ +static bool +hsts_file_access_valid (const char *filename) +{ + struct stat st; + + if (stat (filename, &st) == -1) + return false; + + return +#ifndef WINDOWS + /* + * The world-writable concept is a Unix-centric notion. + * We bypass this test on Windows. + */ + !(st.st_mode & S_IWOTH) && +#endif + S_ISREG (st.st_mode); +} + +/* HSTS API */ + +/* + Changes the given URLs according to the HSTS policy. + + If there's no host in the store that either congruently + or not, matches the given URL, no changes are made. + Returns true if the URL was changed, or false + if it was left intact. + */ +bool +hsts_match (hsts_store_t store, struct url *u) +{ + bool url_changed = false; + struct hsts_kh_info *entry = NULL; + struct hsts_kh *kh = xnew(struct hsts_kh); + enum hsts_kh_match match = NO_MATCH; + int port = MAKE_EXPLICIT_PORT (u->scheme, u->port); + + /* avoid doing any computation if we're already in HTTPS */ + if (!hsts_is_scheme_valid (u->scheme)) + { + entry = hsts_find_entry (store, u->host, port, &match, kh); + if (entry) + { + if ((entry->created + entry->max_age) >= time(NULL)) + { + if ((match == CONGRUENT_MATCH) || + (match == SUPERDOMAIN_MATCH && entry->include_subdomains)) + { + /* we found a matching Known HSTS Host + rewrite the URL */ + u->scheme = SCHEME_HTTPS; + if (u->port == 80) + u->port = 443; + url_changed = true; + store->changed = true; + } + } + else + { + hsts_remove_entry (store, kh); + store->changed = true; + } + } + xfree (kh->host); + } + + xfree (kh); + + return url_changed; +} + +/* + Add a new HSTS Known Host to the HSTS store. + + If the host already exists, its information is updated, + or it'll be removed from the store if max_age is zero. + + Bear in mind that the store is kept in memory, and will not + be written to disk until hsts_store_save is called. + This function regrows the in-memory HSTS store if necessary. + + Currently, for a host to be taken into consideration, + two conditions have to be met: + - Connection must be through a secure channel (HTTPS). + - The host must not be an IPv4 or IPv6 address. + + The RFC 6797 states that hosts that match IPv4 or IPv6 format + should be discarded at URI rewrite time. But we short-circuit + that check here, since there's no point in storing a host that + will never be matched. + + Returns true if a new entry was actually created, or false + if an existing entry was updated/deleted. */ +bool +hsts_store_entry (hsts_store_t store, + enum url_scheme scheme, const char *host, int port, + time_t max_age, bool include_subdomains) +{ + bool result = false; + enum hsts_kh_match match = NO_MATCH; + struct hsts_kh *kh = xnew(struct hsts_kh); + struct hsts_kh_info *entry = NULL; + + if (hsts_is_host_eligible (scheme, host)) + { + port = MAKE_EXPLICIT_PORT (scheme, port); + entry = hsts_find_entry (store, host, port, &match, kh); + if (entry && match == CONGRUENT_MATCH) + { + if (max_age == 0) + { + hsts_remove_entry (store, kh); + store->changed = true; + } + else if (max_age > 0) + { + /* RFC 6797 states that 'max_age' is a TTL relative to the + * reception of the STS header so we have to update the + * 'created' field too. The RFC also states that we have to + * update the entry each time we see HSTS header. + * See also Section 11.2. */ + time_t t = time (NULL); + + if (t != (time_t)(-1) && t != entry->created) + { + entry->created = t; + entry->max_age = max_age; + entry->include_subdomains = include_subdomains; + store->changed = true; + } + } + /* we ignore negative max_ages */ + } + else if (entry == NULL || match == SUPERDOMAIN_MATCH) + { + /* Either we didn't find a matching host, + or we got a superdomain match. + In either case, we create a new entry. + + We have to perform an explicit check because it might + happen we got a non-existent entry with max_age == 0. + */ + result = hsts_add_entry (store, host, port, max_age, include_subdomains); + if (result) + store->changed = true; + } + /* we ignore new entries with max_age == 0 */ + xfree (kh->host); + } + + xfree (kh); + + return result; +} + +hsts_store_t +hsts_store_open (const char *filename) +{ + hsts_store_t store = NULL; + file_stats_t fstats; + + store = xnew0 (struct hsts_store); + store->table = hash_table_new (0, hsts_hash_func, hsts_cmp_func); + store->last_mtime = 0; + store->changed = false; + + if (file_exists_p (filename, &fstats)) + { + if (hsts_file_access_valid (filename)) + { + struct stat st; + FILE *fp = fopen_stat (filename, "r", &fstats); + + if (!fp || !hsts_read_database (store, fp, false)) + { + /* abort! */ + hsts_store_close (store); + xfree (store); + if (fp) + fclose (fp); + goto out; + } + + if (fstat (fileno (fp), &st) == 0) + store->last_mtime = st.st_mtime; + + fclose (fp); + } + else + { + /* + * If we're not reading the HSTS database, + * then by all means act as if HSTS was disabled. + */ + hsts_store_close (store); + xfree (store); + + logprintf (LOG_NOTQUIET, "Will not apply HSTS. " + "The HSTS database must be a regular and non-world-writable file.\n"); + } + } + +out: + return store; +} + +void +hsts_store_save (hsts_store_t store, const char *filename) +{ + struct stat st; + FILE *fp = NULL; + int fd = 0; + + if (filename && hash_table_count (store->table) > 0) + { + fp = fopen (filename, "a+"); + if (fp) + { + /* Lock the file to avoid potential race conditions */ + fd = fileno (fp); + flock (fd, LOCK_EX); + + /* If the file has changed, merge the changes with our in-memory data + before dumping them to the file. + Otherwise we could potentially overwrite the data stored by other Wget processes. + */ + if (store->last_mtime && stat (filename, &st) == 0 && st.st_mtime > store->last_mtime) + hsts_read_database (store, fp, true); + + /* We've merged the latest changes so we can now truncate the file + and dump everything. */ + fseek (fp, 0, SEEK_SET); + ftruncate (fd, 0); + + /* now dump to the file */ + hsts_store_dump (store, fp); + + /* fclose is expected to unlock the file for us */ + fclose (fp); + } + } +} + +bool +hsts_store_has_changed (hsts_store_t store) +{ + return (store ? store->changed : false); +} + +void +hsts_store_close (hsts_store_t store) +{ + hash_table_iterator it; + + /* free all the host fields */ + for (hash_table_iterate (store->table, &it); hash_table_iter_next (&it);) + { + xfree (((struct hsts_kh *) it.key)->host); + xfree (it.key); + xfree (it.value); + } + + hash_table_destroy (store->table); +} + +#ifdef TESTING +/* I know I'm really evil because I'm writing macros + that change control flow. But we're testing, who will tell? :D + */ +#define TEST_URL_RW(s, u, p) do { \ + if (test_url_rewrite (s, u, p, true)) \ + return test_url_rewrite (s, u, p, true); \ + } while (0) + +#define TEST_URL_NORW(s, u, p) do { \ + if (test_url_rewrite (s, u, p, false)) \ + return test_url_rewrite (s, u, p, false); \ + } while (0) + +static char * +get_hsts_store_filename (void) +{ + char *filename = NULL; + FILE *fp = NULL; + + if (opt.homedir) + { + filename = ajoin_dir_file (opt.homedir, ".wget-hsts-test"); + fp = fopen (filename, "w"); + if (fp) + fclose (fp); + } + + return filename; +} + +static hsts_store_t +open_hsts_test_store (void) +{ + char *filename = NULL; + hsts_store_t table = NULL; + + filename = get_hsts_store_filename (); + table = hsts_store_open (filename); + xfree (filename); + + return table; +} + +static void +close_hsts_test_store (hsts_store_t store) +{ + char *filename; + + if ((filename = get_hsts_store_filename ())) + { + unlink (filename); + xfree (filename); + } + xfree (store); +} + +static const char* +test_url_rewrite (hsts_store_t s, const char *url, int port, bool rewrite) +{ + bool result; + struct url u; + + u.host = xstrdup (url); + u.port = port; + u.scheme = SCHEME_HTTP; + + result = hsts_match (s, &u); + + if (rewrite) + { + if (port == 80) + mu_assert("URL: port should've been rewritten to 443", u.port == 443); + else + mu_assert("URL: port should've been left intact", u.port == port); + mu_assert("URL: scheme should've been rewritten to HTTPS", u.scheme == SCHEME_HTTPS); + mu_assert("result should've been true", result == true); + } + else + { + mu_assert("URL: port should've been left intact", u.port == port); + mu_assert("URL: scheme should've been left intact", u.scheme == SCHEME_HTTP); + mu_assert("result should've been false", result == false); + } + + xfree (u.host); + return NULL; +} + +const char * +test_hsts_new_entry (void) +{ + enum hsts_kh_match match = NO_MATCH; + struct hsts_kh_info *khi; + hsts_store_t s; + bool created; + + s = open_hsts_test_store (); + mu_assert("Could not open the HSTS store. This could be due to lack of memory.", s != NULL); + + created = hsts_store_entry (s, SCHEME_HTTP, "www.foo.com", 80, 1234, true); + mu_assert("No entry should have been created.", created == false); + + created = hsts_store_entry (s, SCHEME_HTTPS, "www.foo.com", 443, 1234, true); + mu_assert("A new entry should have been created", created == true); + + khi = hsts_find_entry (s, "www.foo.com", MAKE_EXPLICIT_PORT (SCHEME_HTTPS, 443), &match, NULL); + mu_assert("Should've been a congruent match", match == CONGRUENT_MATCH); + mu_assert("No valid HSTS info was returned", khi != NULL); + mu_assert("Variable 'max_age' should be 1234", khi->max_age == 1234); + mu_assert("Variable 'include_subdomains' should be asserted", khi->include_subdomains == true); + + khi = hsts_find_entry (s, "b.www.foo.com", MAKE_EXPLICIT_PORT (SCHEME_HTTPS, 443), &match, NULL); + mu_assert("Should've been a superdomain match", match == SUPERDOMAIN_MATCH); + mu_assert("No valid HSTS info was returned", khi != NULL); + mu_assert("Variable 'max_age' should be 1234", khi->max_age == 1234); + mu_assert("Variable 'include_subdomains' should be asserted", khi->include_subdomains == true); + + khi = hsts_find_entry (s, "ww.foo.com", MAKE_EXPLICIT_PORT (SCHEME_HTTPS, 443), &match, NULL); + mu_assert("Should've been no match", match == NO_MATCH); + + khi = hsts_find_entry (s, "foo.com", MAKE_EXPLICIT_PORT (SCHEME_HTTPS, 443), &match, NULL); + mu_assert("Should've been no match", match == NO_MATCH); + + khi = hsts_find_entry (s, ".foo.com", MAKE_EXPLICIT_PORT (SCHEME_HTTPS, 443), &match, NULL); + mu_assert("Should've been no match", match == NO_MATCH); + + khi = hsts_find_entry (s, ".www.foo.com", MAKE_EXPLICIT_PORT (SCHEME_HTTPS, 443), &match, NULL); + mu_assert("Should've been no match", match == NO_MATCH); + + hsts_store_close (s); + close_hsts_test_store (s); + + return NULL; +} + +const char* +test_hsts_url_rewrite_superdomain (void) +{ + hsts_store_t s; + bool created; + + s = open_hsts_test_store (); + mu_assert("Could not open the HSTS store", s != NULL); + + created = hsts_store_entry (s, SCHEME_HTTPS, "www.foo.com", 443, 1234, true); + mu_assert("A new entry should've been created", created == true); + + TEST_URL_RW (s, "www.foo.com", 80); + TEST_URL_RW (s, "bar.www.foo.com", 80); + + hsts_store_close (s); + close_hsts_test_store (s); + + return NULL; +} + +const char* +test_hsts_url_rewrite_congruent (void) +{ + hsts_store_t s; + bool created; + + s = open_hsts_test_store (); + mu_assert("Could not open the HSTS store", s != NULL); + + created = hsts_store_entry (s, SCHEME_HTTPS, "foo.com", 443, 1234, false); + mu_assert("A new entry should've been created", created == true); + + TEST_URL_RW (s, "foo.com", 80); + TEST_URL_NORW (s, "www.foo.com", 80); + + hsts_store_close (s); + close_hsts_test_store (s); + + return NULL; +} + +const char* +test_hsts_read_database (void) +{ + hsts_store_t table; + char *file = NULL; + FILE *fp = NULL; + time_t created = time(NULL) - 10; + + if (opt.homedir) + { + file = ajoin_dir_file (opt.homedir, ".wget-hsts-testing"); + fp = fopen (file, "w"); + if (fp) + { + fputs ("# dummy comment\n", fp); + fprintf (fp, "foo.example.com\t0\t1\t%lu\t123\n",(unsigned long) created); + fprintf (fp, "bar.example.com\t0\t0\t%lu\t456\n", (unsigned long) created); + fprintf (fp, "test.example.com\t8080\t0\t%lu\t789\n", (unsigned long) created); + fclose (fp); + + table = hsts_store_open (file); + + TEST_URL_RW (table, "foo.example.com", 80); + TEST_URL_RW (table, "www.foo.example.com", 80); + TEST_URL_RW (table, "bar.example.com", 80); + + TEST_URL_NORW(table, "www.bar.example.com", 80); + + TEST_URL_RW (table, "test.example.com", 8080); + + hsts_store_close (table); + close_hsts_test_store (table); + unlink (file); + } + xfree (file); + } + + return NULL; +} +#endif /* TESTING */ +#endif /* HAVE_HSTS */ diff --git a/src/hsts.h b/src/hsts.h new file mode 100644 index 0000000..7cc41e3 --- /dev/null +++ b/src/hsts.h @@ -0,0 +1,53 @@ +/* Declarations for hsts.c + Copyright (C) 1996-2012, 2015, 2018-2020 Free Software Foundation, + Inc. + +This file is part of GNU Wget. + +GNU Wget is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + +GNU Wget 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 Wget. If not, see . + +Additional permission under GNU GPL version 3 section 7 + +If you modify this program, or any covered work, by linking or +combining it with the OpenSSL project's OpenSSL library (or a +modified version of that library), containing parts covered by the +terms of the OpenSSL or SSLeay licenses, the Free Software Foundation +grants you additional permission to convey the resulting work. +Corresponding Source for a non-source form of such a combination +shall include the source code for the parts of OpenSSL used as well +as that of the covered work. */ + +#ifndef WGET_HSTS_H +#define WGET_HSTS_H + +#ifdef HAVE_HSTS + +#include "wget.h" +#include "url.h" + +typedef struct hsts_store *hsts_store_t; + +hsts_store_t hsts_store_open (const char *); + +void hsts_store_save (hsts_store_t, const char *); +void hsts_store_close (hsts_store_t); +bool hsts_store_has_changed (hsts_store_t); + +bool hsts_store_entry (hsts_store_t, + enum url_scheme, const char *, int, + time_t, bool); +bool hsts_match (hsts_store_t, struct url *); + +#endif /* HAVE_HSTS */ +#endif /* WGET_HSTS_H */ diff --git a/src/html-parse.c b/src/html-parse.c new file mode 100644 index 0000000..6367732 --- /dev/null +++ b/src/html-parse.c @@ -0,0 +1,1221 @@ +/* HTML parser for Wget. + Copyright (C) 1998-2011, 2015, 2018-2020 Free Software Foundation, + Inc. + +This file is part of GNU Wget. + +GNU Wget is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 3 of the License, or (at +your option) any later version. + +GNU Wget 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 Wget. If not, see . + +Additional permission under GNU GPL version 3 section 7 + +If you modify this program, or any covered work, by linking or +combining it with the OpenSSL project's OpenSSL library (or a +modified version of that library), containing parts covered by the +terms of the OpenSSL or SSLeay licenses, the Free Software Foundation +grants you additional permission to convey the resulting work. +Corresponding Source for a non-source form of such a combination +shall include the source code for the parts of OpenSSL used as well +as that of the covered work. */ + +/* The only entry point to this module is map_html_tags(), which see. */ + +/* TODO: + + - Allow hooks for callers to process contents outside tags. This + is needed to implement handling